mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-02-13 08:14:58 -05:00
Compare commits
5 Commits
fix/claude
...
swiftyos/o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff4ab078f0 | ||
|
|
a2a14a0c55 | ||
|
|
a84da6c7ea | ||
|
|
50425cccff | ||
|
|
d12ff35a21 |
@@ -1,4 +1,9 @@
|
|||||||
import { withSentryConfig } from "@sentry/nextjs";
|
import { withSentryConfig } from "@sentry/nextjs";
|
||||||
|
import bundleAnalyzer from "@next/bundle-analyzer";
|
||||||
|
|
||||||
|
const withBundleAnalyzer = bundleAnalyzer({
|
||||||
|
enabled: process.env.ANALYZE === "true",
|
||||||
|
});
|
||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
@@ -15,11 +20,33 @@ const nextConfig = {
|
|||||||
},
|
},
|
||||||
output: "standalone",
|
output: "standalone",
|
||||||
transpilePackages: ["geist"],
|
transpilePackages: ["geist"],
|
||||||
|
compiler: {
|
||||||
|
removeConsole:
|
||||||
|
process.env.NODE_ENV === "production"
|
||||||
|
? {
|
||||||
|
exclude: ["error", "warn"],
|
||||||
|
}
|
||||||
|
: false,
|
||||||
|
},
|
||||||
|
experimental: {
|
||||||
|
optimizePackageImports: [
|
||||||
|
"@phosphor-icons/react",
|
||||||
|
"@radix-ui/react-alert-dialog",
|
||||||
|
"@radix-ui/react-dialog",
|
||||||
|
"@radix-ui/react-dropdown-menu",
|
||||||
|
"@radix-ui/react-select",
|
||||||
|
"@radix-ui/react-tabs",
|
||||||
|
"@radix-ui/react-tooltip",
|
||||||
|
"framer-motion",
|
||||||
|
"@xyflow/react",
|
||||||
|
"react-markdown",
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const isDevelopmentBuild = process.env.NODE_ENV !== "production";
|
const isDevelopmentBuild = process.env.NODE_ENV !== "production";
|
||||||
|
|
||||||
export default isDevelopmentBuild
|
const finalConfig = isDevelopmentBuild
|
||||||
? nextConfig
|
? nextConfig
|
||||||
: withSentryConfig(nextConfig, {
|
: withSentryConfig(nextConfig, {
|
||||||
// For all available options, see:
|
// For all available options, see:
|
||||||
@@ -80,3 +107,5 @@ export default isDevelopmentBuild
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default withBundleAnalyzer(finalConfig);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "pnpm run generate:api:force && next dev --turbo",
|
"dev": "pnpm run generate:api:force && next dev --turbo",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
|
"build:analyze": "ANALYZE=true next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"start:standalone": "cd .next/standalone && node server.js",
|
"start:standalone": "cd .next/standalone && node server.js",
|
||||||
"lint": "next lint && prettier --check .",
|
"lint": "next lint && prettier --check .",
|
||||||
@@ -87,7 +88,6 @@
|
|||||||
"react-modal": "3.16.3",
|
"react-modal": "3.16.3",
|
||||||
"react-shepherd": "6.1.9",
|
"react-shepherd": "6.1.9",
|
||||||
"react-window": "1.8.11",
|
"react-window": "1.8.11",
|
||||||
"recharts": "3.1.2",
|
|
||||||
"rehype-autolink-headings": "7.1.0",
|
"rehype-autolink-headings": "7.1.0",
|
||||||
"rehype-highlight": "7.0.2",
|
"rehype-highlight": "7.0.2",
|
||||||
"rehype-katex": "7.0.1",
|
"rehype-katex": "7.0.1",
|
||||||
@@ -105,6 +105,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chromatic-com/storybook": "4.1.0",
|
"@chromatic-com/storybook": "4.1.0",
|
||||||
|
"@next/bundle-analyzer": "15.5.2",
|
||||||
"@playwright/test": "1.54.2",
|
"@playwright/test": "1.54.2",
|
||||||
"@storybook/addon-a11y": "9.1.2",
|
"@storybook/addon-a11y": "9.1.2",
|
||||||
"@storybook/addon-docs": "9.1.2",
|
"@storybook/addon-docs": "9.1.2",
|
||||||
|
|||||||
381
autogpt_platform/frontend/pnpm-lock.yaml
generated
381
autogpt_platform/frontend/pnpm-lock.yaml
generated
@@ -194,9 +194,6 @@ importers:
|
|||||||
react-window:
|
react-window:
|
||||||
specifier: 1.8.11
|
specifier: 1.8.11
|
||||||
version: 1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 1.8.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
recharts:
|
|
||||||
specifier: 3.1.2
|
|
||||||
version: 3.1.2(@types/react@18.3.17)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(redux@5.0.1)
|
|
||||||
rehype-autolink-headings:
|
rehype-autolink-headings:
|
||||||
specifier: 7.1.0
|
specifier: 7.1.0
|
||||||
version: 7.1.0
|
version: 7.1.0
|
||||||
@@ -243,6 +240,9 @@ importers:
|
|||||||
'@chromatic-com/storybook':
|
'@chromatic-com/storybook':
|
||||||
specifier: 4.1.0
|
specifier: 4.1.0
|
||||||
version: 4.1.0(storybook@9.1.2(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@24.2.1)(typescript@5.9.2))(prettier@3.6.2))
|
version: 4.1.0(storybook@9.1.2(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@24.2.1)(typescript@5.9.2))(prettier@3.6.2))
|
||||||
|
'@next/bundle-analyzer':
|
||||||
|
specifier: 15.5.2
|
||||||
|
version: 15.5.2
|
||||||
'@playwright/test':
|
'@playwright/test':
|
||||||
specifier: 1.54.2
|
specifier: 1.54.2
|
||||||
version: 1.54.2
|
version: 1.54.2
|
||||||
@@ -964,6 +964,10 @@ packages:
|
|||||||
'@date-fns/tz@1.2.0':
|
'@date-fns/tz@1.2.0':
|
||||||
resolution: {integrity: sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==}
|
resolution: {integrity: sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==}
|
||||||
|
|
||||||
|
'@discoveryjs/json-ext@0.5.7':
|
||||||
|
resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
|
||||||
'@emnapi/core@1.4.5':
|
'@emnapi/core@1.4.5':
|
||||||
resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==}
|
resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==}
|
||||||
|
|
||||||
@@ -1417,6 +1421,9 @@ packages:
|
|||||||
'@neoconfetti/react@1.0.0':
|
'@neoconfetti/react@1.0.0':
|
||||||
resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==}
|
resolution: {integrity: sha512-klcSooChXXOzIm+SE5IISIAn3bYzYfPjbX7D7HoqZL84oAfgREeSg5vSIaSFH+DaGzzvImTyWe1OyrJ67vik4A==}
|
||||||
|
|
||||||
|
'@next/bundle-analyzer@15.5.2':
|
||||||
|
resolution: {integrity: sha512-UWOFpy/NK5iSeIP0mgdq4VqGB4/z37uq5v5dEtvzmY/BlaPO6m4EtFUaH6RVI0w2wG5sh0TG86i/cA5wcaJtgg==}
|
||||||
|
|
||||||
'@next/env@15.4.7':
|
'@next/env@15.4.7':
|
||||||
resolution: {integrity: sha512-PrBIpO8oljZGTOe9HH0miix1w5MUiGJ/q83Jge03mHEE0E3pyqzAy2+l5G6aJDbXoobmxPJTVhbCuwlLtjSHwg==}
|
resolution: {integrity: sha512-PrBIpO8oljZGTOe9HH0miix1w5MUiGJ/q83Jge03mHEE0E3pyqzAy2+l5G6aJDbXoobmxPJTVhbCuwlLtjSHwg==}
|
||||||
|
|
||||||
@@ -1762,6 +1769,9 @@ packages:
|
|||||||
webpack-plugin-serve:
|
webpack-plugin-serve:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@polka/url@1.0.0-next.29':
|
||||||
|
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||||
|
|
||||||
'@prisma/instrumentation@6.11.1':
|
'@prisma/instrumentation@6.11.1':
|
||||||
resolution: {integrity: sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==}
|
resolution: {integrity: sha512-mrZOev24EDhnefmnZX7WVVT7v+r9LttPRqf54ONvj6re4XMF7wFTpK2tLJi4XHB7fFp/6xhYbgRel8YV7gQiyA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -2280,17 +2290,6 @@ packages:
|
|||||||
'@radix-ui/rect@1.1.1':
|
'@radix-ui/rect@1.1.1':
|
||||||
resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
|
resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
|
||||||
|
|
||||||
'@reduxjs/toolkit@2.9.0':
|
|
||||||
resolution: {integrity: sha512-fSfQlSRu9Z5yBkvsNhYF2rPS8cGXn/TZVrlwN1948QyZ8xMZ0JvP50S2acZNaf+o63u6aEeMjipFyksjIcWrog==}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.9.0 || ^17.0.0 || ^18 || ^19
|
|
||||||
react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
react:
|
|
||||||
optional: true
|
|
||||||
react-redux:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/plugin-commonjs@28.0.1':
|
'@rollup/plugin-commonjs@28.0.1':
|
||||||
resolution: {integrity: sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==}
|
resolution: {integrity: sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==}
|
||||||
engines: {node: '>=16.0.0 || 14 >= 14.17'}
|
engines: {node: '>=16.0.0 || 14 >= 14.17'}
|
||||||
@@ -2565,9 +2564,6 @@ packages:
|
|||||||
'@shikijs/vscode-textmate@10.0.2':
|
'@shikijs/vscode-textmate@10.0.2':
|
||||||
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
|
resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
|
||||||
|
|
||||||
'@standard-schema/spec@1.0.0':
|
|
||||||
resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
|
|
||||||
|
|
||||||
'@standard-schema/utils@0.3.0':
|
'@standard-schema/utils@0.3.0':
|
||||||
resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
|
resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
|
||||||
|
|
||||||
@@ -2857,39 +2853,18 @@ packages:
|
|||||||
'@types/cookie@0.6.0':
|
'@types/cookie@0.6.0':
|
||||||
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
||||||
|
|
||||||
'@types/d3-array@3.2.1':
|
|
||||||
resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==}
|
|
||||||
|
|
||||||
'@types/d3-color@3.1.3':
|
'@types/d3-color@3.1.3':
|
||||||
resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
|
resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
|
||||||
|
|
||||||
'@types/d3-drag@3.0.7':
|
'@types/d3-drag@3.0.7':
|
||||||
resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==}
|
resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==}
|
||||||
|
|
||||||
'@types/d3-ease@3.0.2':
|
|
||||||
resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
|
|
||||||
|
|
||||||
'@types/d3-interpolate@3.0.4':
|
'@types/d3-interpolate@3.0.4':
|
||||||
resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
|
resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
|
||||||
|
|
||||||
'@types/d3-path@3.1.1':
|
|
||||||
resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==}
|
|
||||||
|
|
||||||
'@types/d3-scale@4.0.9':
|
|
||||||
resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==}
|
|
||||||
|
|
||||||
'@types/d3-selection@3.0.11':
|
'@types/d3-selection@3.0.11':
|
||||||
resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==}
|
resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==}
|
||||||
|
|
||||||
'@types/d3-shape@3.1.7':
|
|
||||||
resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==}
|
|
||||||
|
|
||||||
'@types/d3-time@3.0.4':
|
|
||||||
resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==}
|
|
||||||
|
|
||||||
'@types/d3-timer@3.0.2':
|
|
||||||
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
|
|
||||||
|
|
||||||
'@types/d3-transition@3.0.9':
|
'@types/d3-transition@3.0.9':
|
||||||
resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==}
|
resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==}
|
||||||
|
|
||||||
@@ -3024,9 +2999,6 @@ packages:
|
|||||||
'@types/urijs@1.19.25':
|
'@types/urijs@1.19.25':
|
||||||
resolution: {integrity: sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==}
|
resolution: {integrity: sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==}
|
||||||
|
|
||||||
'@types/use-sync-external-store@0.0.6':
|
|
||||||
resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
|
|
||||||
|
|
||||||
'@types/ws@8.18.1':
|
'@types/ws@8.18.1':
|
||||||
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
|
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
|
||||||
|
|
||||||
@@ -3290,6 +3262,10 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
|
|
||||||
|
acorn-walk@8.3.4:
|
||||||
|
resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
|
||||||
|
engines: {node: '>=0.4.0'}
|
||||||
|
|
||||||
acorn@8.15.0:
|
acorn@8.15.0:
|
||||||
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
|
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
@@ -3762,6 +3738,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
commander@7.2.0:
|
||||||
|
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
commander@8.3.0:
|
commander@8.3.0:
|
||||||
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
|
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
|
||||||
engines: {node: '>= 12'}
|
engines: {node: '>= 12'}
|
||||||
@@ -3887,10 +3867,6 @@ packages:
|
|||||||
csstype@3.1.3:
|
csstype@3.1.3:
|
||||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||||
|
|
||||||
d3-array@3.2.4:
|
|
||||||
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
d3-color@3.1.0:
|
d3-color@3.1.0:
|
||||||
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -3907,38 +3883,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
d3-format@3.1.0:
|
|
||||||
resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
d3-interpolate@3.0.1:
|
d3-interpolate@3.0.1:
|
||||||
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
d3-path@3.1.0:
|
|
||||||
resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
d3-scale@4.0.2:
|
|
||||||
resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
d3-selection@3.0.0:
|
d3-selection@3.0.0:
|
||||||
resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
|
resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
d3-shape@3.2.0:
|
|
||||||
resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
d3-time-format@4.1.0:
|
|
||||||
resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
d3-time@3.1.0:
|
|
||||||
resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
d3-timer@3.0.1:
|
d3-timer@3.0.1:
|
||||||
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -3974,6 +3926,9 @@ packages:
|
|||||||
date-fns@4.1.0:
|
date-fns@4.1.0:
|
||||||
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
||||||
|
|
||||||
|
debounce@1.2.1:
|
||||||
|
resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==}
|
||||||
|
|
||||||
debug@3.2.7:
|
debug@3.2.7:
|
||||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -3991,9 +3946,6 @@ packages:
|
|||||||
supports-color:
|
supports-color:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
decimal.js-light@2.5.1:
|
|
||||||
resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
|
|
||||||
|
|
||||||
decode-named-character-reference@1.2.0:
|
decode-named-character-reference@1.2.0:
|
||||||
resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
|
resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
|
||||||
|
|
||||||
@@ -4110,6 +4062,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
duplexer@0.1.2:
|
||||||
|
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
|
||||||
|
|
||||||
eastasianwidth@0.2.0:
|
eastasianwidth@0.2.0:
|
||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
|
|
||||||
@@ -4213,9 +4168,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
|
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
es-toolkit@1.39.10:
|
|
||||||
resolution: {integrity: sha512-E0iGnTtbDhkeczB0T+mxmoVlT4YNweEKBLq7oaU4p11mecdsZpNWOglI4895Vh4usbQ+LsJiuLuI2L0Vdmfm2w==}
|
|
||||||
|
|
||||||
es6-promise@3.3.1:
|
es6-promise@3.3.1:
|
||||||
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
|
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
|
||||||
|
|
||||||
@@ -4386,9 +4338,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
eventemitter3@5.0.1:
|
|
||||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
|
||||||
|
|
||||||
events@3.3.0:
|
events@3.3.0:
|
||||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||||
engines: {node: '>=0.8.x'}
|
engines: {node: '>=0.8.x'}
|
||||||
@@ -4650,6 +4599,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==}
|
resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==}
|
||||||
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
|
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
|
||||||
|
|
||||||
|
gzip-size@6.0.0:
|
||||||
|
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
has-bigints@1.1.0:
|
has-bigints@1.1.0:
|
||||||
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
|
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -4743,6 +4696,9 @@ packages:
|
|||||||
html-entities@2.6.0:
|
html-entities@2.6.0:
|
||||||
resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==}
|
resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==}
|
||||||
|
|
||||||
|
html-escaper@2.0.2:
|
||||||
|
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
|
||||||
|
|
||||||
html-minifier-terser@6.1.0:
|
html-minifier-terser@6.1.0:
|
||||||
resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==}
|
resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -4837,10 +4793,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
|
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
internmap@2.0.3:
|
|
||||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
|
|
||||||
is-alphabetical@2.0.1:
|
is-alphabetical@2.0.1:
|
||||||
resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
|
resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
|
||||||
|
|
||||||
@@ -4958,6 +4910,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
|
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
is-plain-object@5.0.0:
|
||||||
|
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
is-reference@1.2.1:
|
is-reference@1.2.1:
|
||||||
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
|
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
|
||||||
|
|
||||||
@@ -5490,6 +5446,10 @@ packages:
|
|||||||
motion-utils@12.23.6:
|
motion-utils@12.23.6:
|
||||||
resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==}
|
resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==}
|
||||||
|
|
||||||
|
mrmime@2.0.1:
|
||||||
|
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
@@ -5705,6 +5665,10 @@ packages:
|
|||||||
openapi3-ts@4.4.0:
|
openapi3-ts@4.4.0:
|
||||||
resolution: {integrity: sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==}
|
resolution: {integrity: sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==}
|
||||||
|
|
||||||
|
opener@1.5.2:
|
||||||
|
resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -6173,9 +6137,6 @@ packages:
|
|||||||
react-is@17.0.2:
|
react-is@17.0.2:
|
||||||
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
||||||
|
|
||||||
react-is@18.3.1:
|
|
||||||
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
|
|
||||||
|
|
||||||
react-lifecycles-compat@3.0.4:
|
react-lifecycles-compat@3.0.4:
|
||||||
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
|
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
|
||||||
|
|
||||||
@@ -6191,18 +6152,6 @@ packages:
|
|||||||
react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19
|
react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19
|
||||||
react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19
|
react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^19
|
||||||
|
|
||||||
react-redux@9.2.0:
|
|
||||||
resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==}
|
|
||||||
peerDependencies:
|
|
||||||
'@types/react': ^18.2.25 || ^19
|
|
||||||
react: ^18.0 || ^19
|
|
||||||
redux: ^5.0.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
'@types/react':
|
|
||||||
optional: true
|
|
||||||
redux:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
react-refresh@0.14.2:
|
react-refresh@0.14.2:
|
||||||
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
|
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -6281,26 +6230,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==}
|
resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
||||||
recharts@3.1.2:
|
|
||||||
resolution: {integrity: sha512-vhNbYwaxNbk/IATK0Ki29k3qvTkGqwvCgyQAQ9MavvvBwjvKnMTswdbklJpcOAoMPN/qxF3Lyqob0zO+ZXkZ4g==}
|
|
||||||
engines: {node: '>=18'}
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
|
||||||
|
|
||||||
redent@3.0.0:
|
redent@3.0.0:
|
||||||
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
|
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
redux-thunk@3.1.0:
|
|
||||||
resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
|
|
||||||
peerDependencies:
|
|
||||||
redux: ^5.0.0
|
|
||||||
|
|
||||||
redux@5.0.1:
|
|
||||||
resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
|
|
||||||
|
|
||||||
reflect.getprototypeof@1.0.10:
|
reflect.getprototypeof@1.0.10:
|
||||||
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
|
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -6382,9 +6315,6 @@ packages:
|
|||||||
requires-port@1.0.0:
|
requires-port@1.0.0:
|
||||||
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
|
||||||
|
|
||||||
reselect@5.1.1:
|
|
||||||
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
|
|
||||||
|
|
||||||
resolve-from@4.0.0:
|
resolve-from@4.0.0:
|
||||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -6594,6 +6524,10 @@ packages:
|
|||||||
simple-swizzle@0.2.2:
|
simple-swizzle@0.2.2:
|
||||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||||
|
|
||||||
|
sirv@2.0.4:
|
||||||
|
resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
slash@3.0.0:
|
slash@3.0.0:
|
||||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -6883,6 +6817,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
|
|
||||||
|
totalist@3.0.1:
|
||||||
|
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
tough-cookie@4.1.4:
|
tough-cookie@4.1.4:
|
||||||
resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
|
resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -7164,9 +7102,6 @@ packages:
|
|||||||
vfile@6.0.3:
|
vfile@6.0.3:
|
||||||
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
|
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
|
||||||
|
|
||||||
victory-vendor@37.3.6:
|
|
||||||
resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==}
|
|
||||||
|
|
||||||
vm-browserify@1.1.2:
|
vm-browserify@1.1.2:
|
||||||
resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
|
resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
|
||||||
|
|
||||||
@@ -7183,6 +7118,11 @@ packages:
|
|||||||
webidl-conversions@3.0.1:
|
webidl-conversions@3.0.1:
|
||||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
|
||||||
|
webpack-bundle-analyzer@4.10.1:
|
||||||
|
resolution: {integrity: sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==}
|
||||||
|
engines: {node: '>= 10.13.0'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
webpack-dev-middleware@6.1.3:
|
webpack-dev-middleware@6.1.3:
|
||||||
resolution: {integrity: sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==}
|
resolution: {integrity: sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==}
|
||||||
engines: {node: '>= 14.15.0'}
|
engines: {node: '>= 14.15.0'}
|
||||||
@@ -7258,6 +7198,18 @@ packages:
|
|||||||
wrappy@1.0.2:
|
wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
|
ws@7.5.10:
|
||||||
|
resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==}
|
||||||
|
engines: {node: '>=8.3.0'}
|
||||||
|
peerDependencies:
|
||||||
|
bufferutil: ^4.0.1
|
||||||
|
utf-8-validate: ^5.0.2
|
||||||
|
peerDependenciesMeta:
|
||||||
|
bufferutil:
|
||||||
|
optional: true
|
||||||
|
utf-8-validate:
|
||||||
|
optional: true
|
||||||
|
|
||||||
ws@8.18.3:
|
ws@8.18.3:
|
||||||
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
|
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
@@ -8147,6 +8099,8 @@ snapshots:
|
|||||||
|
|
||||||
'@date-fns/tz@1.2.0': {}
|
'@date-fns/tz@1.2.0': {}
|
||||||
|
|
||||||
|
'@discoveryjs/json-ext@0.5.7': {}
|
||||||
|
|
||||||
'@emnapi/core@1.4.5':
|
'@emnapi/core@1.4.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/wasi-threads': 1.0.4
|
'@emnapi/wasi-threads': 1.0.4
|
||||||
@@ -8514,6 +8468,13 @@ snapshots:
|
|||||||
|
|
||||||
'@neoconfetti/react@1.0.0': {}
|
'@neoconfetti/react@1.0.0': {}
|
||||||
|
|
||||||
|
'@next/bundle-analyzer@15.5.2':
|
||||||
|
dependencies:
|
||||||
|
webpack-bundle-analyzer: 4.10.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
'@next/env@15.4.7': {}
|
'@next/env@15.4.7': {}
|
||||||
|
|
||||||
'@next/eslint-plugin-next@15.4.6':
|
'@next/eslint-plugin-next@15.4.6':
|
||||||
@@ -8948,6 +8909,8 @@ snapshots:
|
|||||||
type-fest: 4.41.0
|
type-fest: 4.41.0
|
||||||
webpack-hot-middleware: 2.26.1
|
webpack-hot-middleware: 2.26.1
|
||||||
|
|
||||||
|
'@polka/url@1.0.0-next.29': {}
|
||||||
|
|
||||||
'@prisma/instrumentation@6.11.1(@opentelemetry/api@1.9.0)':
|
'@prisma/instrumentation@6.11.1(@opentelemetry/api@1.9.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@opentelemetry/api': 1.9.0
|
'@opentelemetry/api': 1.9.0
|
||||||
@@ -9494,18 +9457,6 @@ snapshots:
|
|||||||
|
|
||||||
'@radix-ui/rect@1.1.1': {}
|
'@radix-ui/rect@1.1.1': {}
|
||||||
|
|
||||||
'@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@18.3.17)(react@18.3.1)(redux@5.0.1))(react@18.3.1)':
|
|
||||||
dependencies:
|
|
||||||
'@standard-schema/spec': 1.0.0
|
|
||||||
'@standard-schema/utils': 0.3.0
|
|
||||||
immer: 10.1.3
|
|
||||||
redux: 5.0.1
|
|
||||||
redux-thunk: 3.1.0(redux@5.0.1)
|
|
||||||
reselect: 5.1.1
|
|
||||||
optionalDependencies:
|
|
||||||
react: 18.3.1
|
|
||||||
react-redux: 9.2.0(@types/react@18.3.17)(react@18.3.1)(redux@5.0.1)
|
|
||||||
|
|
||||||
'@rollup/plugin-commonjs@28.0.1(rollup@4.46.2)':
|
'@rollup/plugin-commonjs@28.0.1(rollup@4.46.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
|
'@rollup/pluginutils': 5.2.0(rollup@4.46.2)
|
||||||
@@ -9817,8 +9768,6 @@ snapshots:
|
|||||||
|
|
||||||
'@shikijs/vscode-textmate@10.0.2': {}
|
'@shikijs/vscode-textmate@10.0.2': {}
|
||||||
|
|
||||||
'@standard-schema/spec@1.0.0': {}
|
|
||||||
|
|
||||||
'@standard-schema/utils@0.3.0': {}
|
'@standard-schema/utils@0.3.0': {}
|
||||||
|
|
||||||
'@stoplight/better-ajv-errors@1.0.3(ajv@8.17.1)':
|
'@stoplight/better-ajv-errors@1.0.3(ajv@8.17.1)':
|
||||||
@@ -10318,36 +10267,18 @@ snapshots:
|
|||||||
|
|
||||||
'@types/cookie@0.6.0': {}
|
'@types/cookie@0.6.0': {}
|
||||||
|
|
||||||
'@types/d3-array@3.2.1': {}
|
|
||||||
|
|
||||||
'@types/d3-color@3.1.3': {}
|
'@types/d3-color@3.1.3': {}
|
||||||
|
|
||||||
'@types/d3-drag@3.0.7':
|
'@types/d3-drag@3.0.7':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/d3-selection': 3.0.11
|
'@types/d3-selection': 3.0.11
|
||||||
|
|
||||||
'@types/d3-ease@3.0.2': {}
|
|
||||||
|
|
||||||
'@types/d3-interpolate@3.0.4':
|
'@types/d3-interpolate@3.0.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/d3-color': 3.1.3
|
'@types/d3-color': 3.1.3
|
||||||
|
|
||||||
'@types/d3-path@3.1.1': {}
|
|
||||||
|
|
||||||
'@types/d3-scale@4.0.9':
|
|
||||||
dependencies:
|
|
||||||
'@types/d3-time': 3.0.4
|
|
||||||
|
|
||||||
'@types/d3-selection@3.0.11': {}
|
'@types/d3-selection@3.0.11': {}
|
||||||
|
|
||||||
'@types/d3-shape@3.1.7':
|
|
||||||
dependencies:
|
|
||||||
'@types/d3-path': 3.1.1
|
|
||||||
|
|
||||||
'@types/d3-time@3.0.4': {}
|
|
||||||
|
|
||||||
'@types/d3-timer@3.0.2': {}
|
|
||||||
|
|
||||||
'@types/d3-transition@3.0.9':
|
'@types/d3-transition@3.0.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/d3-selection': 3.0.11
|
'@types/d3-selection': 3.0.11
|
||||||
@@ -10478,8 +10409,6 @@ snapshots:
|
|||||||
|
|
||||||
'@types/urijs@1.19.25': {}
|
'@types/urijs@1.19.25': {}
|
||||||
|
|
||||||
'@types/use-sync-external-store@0.0.6': {}
|
|
||||||
|
|
||||||
'@types/ws@8.18.1':
|
'@types/ws@8.18.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 24.2.1
|
'@types/node': 24.2.1
|
||||||
@@ -10787,6 +10716,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
acorn: 8.15.0
|
acorn: 8.15.0
|
||||||
|
|
||||||
|
acorn-walk@8.3.4:
|
||||||
|
dependencies:
|
||||||
|
acorn: 8.15.0
|
||||||
|
|
||||||
acorn@8.15.0: {}
|
acorn@8.15.0: {}
|
||||||
|
|
||||||
adjust-sourcemap-loader@4.0.0:
|
adjust-sourcemap-loader@4.0.0:
|
||||||
@@ -11281,6 +11214,8 @@ snapshots:
|
|||||||
|
|
||||||
commander@4.1.1: {}
|
commander@4.1.1: {}
|
||||||
|
|
||||||
|
commander@7.2.0: {}
|
||||||
|
|
||||||
commander@8.3.0: {}
|
commander@8.3.0: {}
|
||||||
|
|
||||||
common-path-prefix@3.0.0: {}
|
common-path-prefix@3.0.0: {}
|
||||||
@@ -11429,10 +11364,6 @@ snapshots:
|
|||||||
|
|
||||||
csstype@3.1.3: {}
|
csstype@3.1.3: {}
|
||||||
|
|
||||||
d3-array@3.2.4:
|
|
||||||
dependencies:
|
|
||||||
internmap: 2.0.3
|
|
||||||
|
|
||||||
d3-color@3.1.0: {}
|
d3-color@3.1.0: {}
|
||||||
|
|
||||||
d3-dispatch@3.0.1: {}
|
d3-dispatch@3.0.1: {}
|
||||||
@@ -11444,36 +11375,12 @@ snapshots:
|
|||||||
|
|
||||||
d3-ease@3.0.1: {}
|
d3-ease@3.0.1: {}
|
||||||
|
|
||||||
d3-format@3.1.0: {}
|
|
||||||
|
|
||||||
d3-interpolate@3.0.1:
|
d3-interpolate@3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
d3-color: 3.1.0
|
d3-color: 3.1.0
|
||||||
|
|
||||||
d3-path@3.1.0: {}
|
|
||||||
|
|
||||||
d3-scale@4.0.2:
|
|
||||||
dependencies:
|
|
||||||
d3-array: 3.2.4
|
|
||||||
d3-format: 3.1.0
|
|
||||||
d3-interpolate: 3.0.1
|
|
||||||
d3-time: 3.1.0
|
|
||||||
d3-time-format: 4.1.0
|
|
||||||
|
|
||||||
d3-selection@3.0.0: {}
|
d3-selection@3.0.0: {}
|
||||||
|
|
||||||
d3-shape@3.2.0:
|
|
||||||
dependencies:
|
|
||||||
d3-path: 3.1.0
|
|
||||||
|
|
||||||
d3-time-format@4.1.0:
|
|
||||||
dependencies:
|
|
||||||
d3-time: 3.1.0
|
|
||||||
|
|
||||||
d3-time@3.1.0:
|
|
||||||
dependencies:
|
|
||||||
d3-array: 3.2.4
|
|
||||||
|
|
||||||
d3-timer@3.0.1: {}
|
d3-timer@3.0.1: {}
|
||||||
|
|
||||||
d3-transition@3.0.1(d3-selection@3.0.0):
|
d3-transition@3.0.1(d3-selection@3.0.0):
|
||||||
@@ -11517,6 +11424,8 @@ snapshots:
|
|||||||
|
|
||||||
date-fns@4.1.0: {}
|
date-fns@4.1.0: {}
|
||||||
|
|
||||||
|
debounce@1.2.1: {}
|
||||||
|
|
||||||
debug@3.2.7:
|
debug@3.2.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
@@ -11525,8 +11434,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
|
||||||
decimal.js-light@2.5.1: {}
|
|
||||||
|
|
||||||
decode-named-character-reference@1.2.0:
|
decode-named-character-reference@1.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
character-entities: 2.0.2
|
character-entities: 2.0.2
|
||||||
@@ -11638,6 +11545,8 @@ snapshots:
|
|||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
gopd: 1.2.0
|
gopd: 1.2.0
|
||||||
|
|
||||||
|
duplexer@0.1.2: {}
|
||||||
|
|
||||||
eastasianwidth@0.2.0: {}
|
eastasianwidth@0.2.0: {}
|
||||||
|
|
||||||
electron-to-chromium@1.5.200: {}
|
electron-to-chromium@1.5.200: {}
|
||||||
@@ -11816,8 +11725,6 @@ snapshots:
|
|||||||
is-date-object: 1.1.0
|
is-date-object: 1.1.0
|
||||||
is-symbol: 1.1.1
|
is-symbol: 1.1.1
|
||||||
|
|
||||||
es-toolkit@1.39.10: {}
|
|
||||||
|
|
||||||
es6-promise@3.3.1: {}
|
es6-promise@3.3.1: {}
|
||||||
|
|
||||||
esbuild-register@3.6.0(esbuild@0.25.9):
|
esbuild-register@3.6.0(esbuild@0.25.9):
|
||||||
@@ -12088,8 +11995,6 @@ snapshots:
|
|||||||
|
|
||||||
event-target-shim@5.0.1: {}
|
event-target-shim@5.0.1: {}
|
||||||
|
|
||||||
eventemitter3@5.0.1: {}
|
|
||||||
|
|
||||||
events@3.3.0: {}
|
events@3.3.0: {}
|
||||||
|
|
||||||
evp_bytestokey@1.0.3:
|
evp_bytestokey@1.0.3:
|
||||||
@@ -12381,6 +12286,10 @@ snapshots:
|
|||||||
|
|
||||||
graphql@16.11.0: {}
|
graphql@16.11.0: {}
|
||||||
|
|
||||||
|
gzip-size@6.0.0:
|
||||||
|
dependencies:
|
||||||
|
duplexer: 0.1.2
|
||||||
|
|
||||||
has-bigints@1.1.0: {}
|
has-bigints@1.1.0: {}
|
||||||
|
|
||||||
has-flag@4.0.0: {}
|
has-flag@4.0.0: {}
|
||||||
@@ -12523,6 +12432,8 @@ snapshots:
|
|||||||
|
|
||||||
html-entities@2.6.0: {}
|
html-entities@2.6.0: {}
|
||||||
|
|
||||||
|
html-escaper@2.0.2: {}
|
||||||
|
|
||||||
html-minifier-terser@6.1.0:
|
html-minifier-terser@6.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
camel-case: 4.1.2
|
camel-case: 4.1.2
|
||||||
@@ -12577,7 +12488,8 @@ snapshots:
|
|||||||
|
|
||||||
image-size@2.0.2: {}
|
image-size@2.0.2: {}
|
||||||
|
|
||||||
immer@10.1.3: {}
|
immer@10.1.3:
|
||||||
|
optional: true
|
||||||
|
|
||||||
immer@9.0.21: {}
|
immer@9.0.21: {}
|
||||||
|
|
||||||
@@ -12612,8 +12524,6 @@ snapshots:
|
|||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
side-channel: 1.1.0
|
side-channel: 1.1.0
|
||||||
|
|
||||||
internmap@2.0.3: {}
|
|
||||||
|
|
||||||
is-alphabetical@2.0.1: {}
|
is-alphabetical@2.0.1: {}
|
||||||
|
|
||||||
is-alphanumerical@2.0.1:
|
is-alphanumerical@2.0.1:
|
||||||
@@ -12726,6 +12636,8 @@ snapshots:
|
|||||||
|
|
||||||
is-plain-obj@4.1.0: {}
|
is-plain-obj@4.1.0: {}
|
||||||
|
|
||||||
|
is-plain-object@5.0.0: {}
|
||||||
|
|
||||||
is-reference@1.2.1:
|
is-reference@1.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.8
|
'@types/estree': 1.0.8
|
||||||
@@ -13458,6 +13370,8 @@ snapshots:
|
|||||||
|
|
||||||
motion-utils@12.23.6: {}
|
motion-utils@12.23.6: {}
|
||||||
|
|
||||||
|
mrmime@2.0.1: {}
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
msw-storybook-addon@2.0.5(msw@2.10.4(@types/node@24.2.1)(typescript@5.9.2)):
|
msw-storybook-addon@2.0.5(msw@2.10.4(@types/node@24.2.1)(typescript@5.9.2)):
|
||||||
@@ -13721,6 +13635,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
yaml: 2.8.1
|
yaml: 2.8.1
|
||||||
|
|
||||||
|
opener@1.5.2: {}
|
||||||
|
|
||||||
optionator@0.9.4:
|
optionator@0.9.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
deep-is: 0.1.4
|
deep-is: 0.1.4
|
||||||
@@ -14151,8 +14067,6 @@ snapshots:
|
|||||||
|
|
||||||
react-is@17.0.2: {}
|
react-is@17.0.2: {}
|
||||||
|
|
||||||
react-is@18.3.1: {}
|
|
||||||
|
|
||||||
react-lifecycles-compat@3.0.4: {}
|
react-lifecycles-compat@3.0.4: {}
|
||||||
|
|
||||||
react-markdown@9.0.3(@types/react@18.3.17)(react@18.3.1):
|
react-markdown@9.0.3(@types/react@18.3.17)(react@18.3.1):
|
||||||
@@ -14181,15 +14095,6 @@ snapshots:
|
|||||||
react-lifecycles-compat: 3.0.4
|
react-lifecycles-compat: 3.0.4
|
||||||
warning: 4.0.3
|
warning: 4.0.3
|
||||||
|
|
||||||
react-redux@9.2.0(@types/react@18.3.17)(react@18.3.1)(redux@5.0.1):
|
|
||||||
dependencies:
|
|
||||||
'@types/use-sync-external-store': 0.0.6
|
|
||||||
react: 18.3.1
|
|
||||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
|
||||||
optionalDependencies:
|
|
||||||
'@types/react': 18.3.17
|
|
||||||
redux: 5.0.1
|
|
||||||
|
|
||||||
react-refresh@0.14.2: {}
|
react-refresh@0.14.2: {}
|
||||||
|
|
||||||
react-remove-scroll-bar@2.3.8(@types/react@18.3.17)(react@18.3.1):
|
react-remove-scroll-bar@2.3.8(@types/react@18.3.17)(react@18.3.1):
|
||||||
@@ -14279,37 +14184,11 @@ snapshots:
|
|||||||
tiny-invariant: 1.3.3
|
tiny-invariant: 1.3.3
|
||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
|
|
||||||
recharts@3.1.2(@types/react@18.3.17)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(redux@5.0.1):
|
|
||||||
dependencies:
|
|
||||||
'@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@18.3.17)(react@18.3.1)(redux@5.0.1))(react@18.3.1)
|
|
||||||
clsx: 2.1.1
|
|
||||||
decimal.js-light: 2.5.1
|
|
||||||
es-toolkit: 1.39.10
|
|
||||||
eventemitter3: 5.0.1
|
|
||||||
immer: 10.1.3
|
|
||||||
react: 18.3.1
|
|
||||||
react-dom: 18.3.1(react@18.3.1)
|
|
||||||
react-is: 18.3.1
|
|
||||||
react-redux: 9.2.0(@types/react@18.3.17)(react@18.3.1)(redux@5.0.1)
|
|
||||||
reselect: 5.1.1
|
|
||||||
tiny-invariant: 1.3.3
|
|
||||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
|
||||||
victory-vendor: 37.3.6
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- '@types/react'
|
|
||||||
- redux
|
|
||||||
|
|
||||||
redent@3.0.0:
|
redent@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
indent-string: 4.0.0
|
indent-string: 4.0.0
|
||||||
strip-indent: 3.0.0
|
strip-indent: 3.0.0
|
||||||
|
|
||||||
redux-thunk@3.1.0(redux@5.0.1):
|
|
||||||
dependencies:
|
|
||||||
redux: 5.0.1
|
|
||||||
|
|
||||||
redux@5.0.1: {}
|
|
||||||
|
|
||||||
reflect.getprototypeof@1.0.10:
|
reflect.getprototypeof@1.0.10:
|
||||||
dependencies:
|
dependencies:
|
||||||
call-bind: 1.0.8
|
call-bind: 1.0.8
|
||||||
@@ -14457,8 +14336,6 @@ snapshots:
|
|||||||
|
|
||||||
requires-port@1.0.0: {}
|
requires-port@1.0.0: {}
|
||||||
|
|
||||||
reselect@5.1.1: {}
|
|
||||||
|
|
||||||
resolve-from@4.0.0: {}
|
resolve-from@4.0.0: {}
|
||||||
|
|
||||||
resolve-pkg-maps@1.0.0: {}
|
resolve-pkg-maps@1.0.0: {}
|
||||||
@@ -14740,6 +14617,12 @@ snapshots:
|
|||||||
is-arrayish: 0.3.2
|
is-arrayish: 0.3.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
sirv@2.0.4:
|
||||||
|
dependencies:
|
||||||
|
'@polka/url': 1.0.0-next.29
|
||||||
|
mrmime: 2.0.1
|
||||||
|
totalist: 3.0.1
|
||||||
|
|
||||||
slash@3.0.0: {}
|
slash@3.0.0: {}
|
||||||
|
|
||||||
sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||||
@@ -15087,6 +14970,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
|
|
||||||
|
totalist@3.0.1: {}
|
||||||
|
|
||||||
tough-cookie@4.1.4:
|
tough-cookie@4.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
psl: 1.15.0
|
psl: 1.15.0
|
||||||
@@ -15398,23 +15283,6 @@ snapshots:
|
|||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
vfile-message: 4.0.3
|
vfile-message: 4.0.3
|
||||||
|
|
||||||
victory-vendor@37.3.6:
|
|
||||||
dependencies:
|
|
||||||
'@types/d3-array': 3.2.1
|
|
||||||
'@types/d3-ease': 3.0.2
|
|
||||||
'@types/d3-interpolate': 3.0.4
|
|
||||||
'@types/d3-scale': 4.0.9
|
|
||||||
'@types/d3-shape': 3.1.7
|
|
||||||
'@types/d3-time': 3.0.4
|
|
||||||
'@types/d3-timer': 3.0.2
|
|
||||||
d3-array: 3.2.4
|
|
||||||
d3-ease: 3.0.1
|
|
||||||
d3-interpolate: 3.0.1
|
|
||||||
d3-scale: 4.0.2
|
|
||||||
d3-shape: 3.2.0
|
|
||||||
d3-time: 3.1.0
|
|
||||||
d3-timer: 3.0.1
|
|
||||||
|
|
||||||
vm-browserify@1.1.2: {}
|
vm-browserify@1.1.2: {}
|
||||||
|
|
||||||
warning@4.0.3:
|
warning@4.0.3:
|
||||||
@@ -15430,6 +15298,25 @@ snapshots:
|
|||||||
|
|
||||||
webidl-conversions@3.0.1: {}
|
webidl-conversions@3.0.1: {}
|
||||||
|
|
||||||
|
webpack-bundle-analyzer@4.10.1:
|
||||||
|
dependencies:
|
||||||
|
'@discoveryjs/json-ext': 0.5.7
|
||||||
|
acorn: 8.15.0
|
||||||
|
acorn-walk: 8.3.4
|
||||||
|
commander: 7.2.0
|
||||||
|
debounce: 1.2.1
|
||||||
|
escape-string-regexp: 4.0.0
|
||||||
|
gzip-size: 6.0.0
|
||||||
|
html-escaper: 2.0.2
|
||||||
|
is-plain-object: 5.0.0
|
||||||
|
opener: 1.5.2
|
||||||
|
picocolors: 1.1.1
|
||||||
|
sirv: 2.0.4
|
||||||
|
ws: 7.5.10
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
webpack-dev-middleware@6.1.3(webpack@5.101.1(esbuild@0.25.9)):
|
webpack-dev-middleware@6.1.3(webpack@5.101.1(esbuild@0.25.9)):
|
||||||
dependencies:
|
dependencies:
|
||||||
colorette: 2.0.20
|
colorette: 2.0.20
|
||||||
@@ -15556,6 +15443,8 @@ snapshots:
|
|||||||
|
|
||||||
wrappy@1.0.2: {}
|
wrappy@1.0.2: {}
|
||||||
|
|
||||||
|
ws@7.5.10: {}
|
||||||
|
|
||||||
ws@8.18.3: {}
|
ws@8.18.3: {}
|
||||||
|
|
||||||
xmlbuilder@15.1.1: {}
|
xmlbuilder@15.1.1: {}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import FlowEditor from "@/components/Flow";
|
import FlowEditor from "@/components/FlowLazy";
|
||||||
import { useOnboarding } from "@/components/onboarding/onboarding-provider";
|
import { useOnboarding } from "@/components/onboarding/onboarding-provider";
|
||||||
import LoadingBox from "@/components/ui/loading";
|
import LoadingBox from "@/components/ui/loading";
|
||||||
import { GraphID } from "@/lib/autogpt-server-api/types";
|
import { GraphID } from "@/lib/autogpt-server-api/types";
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ export function useRunDetailHeader(
|
|||||||
mutation: {
|
mutation: {
|
||||||
onSuccess: async (res) => {
|
onSuccess: async (res) => {
|
||||||
toast({ title: "Run started" });
|
toast({ title: "Run started" });
|
||||||
const newRunId = res?.status === 200 ? (res?.data?.id ?? "") : "";
|
const newRunId =
|
||||||
|
res?.status === 200 ? (res?.data?.graph_exec_id ?? "") : "";
|
||||||
|
|
||||||
await queryClient.invalidateQueries({
|
await queryClient.invalidateQueries({
|
||||||
queryKey:
|
queryKey:
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
Graph,
|
Graph,
|
||||||
GraphExecution,
|
GraphExecution,
|
||||||
GraphExecutionID,
|
GraphExecutionID,
|
||||||
GraphExecutionMeta,
|
|
||||||
GraphID,
|
GraphID,
|
||||||
LibraryAgent,
|
LibraryAgent,
|
||||||
LibraryAgentID,
|
LibraryAgentID,
|
||||||
@@ -45,7 +44,7 @@ import {
|
|||||||
import { AgentRunDetailsView } from "./components/agent-run-details-view";
|
import { AgentRunDetailsView } from "./components/agent-run-details-view";
|
||||||
import { AgentRunDraftView } from "./components/agent-run-draft-view";
|
import { AgentRunDraftView } from "./components/agent-run-draft-view";
|
||||||
import { CreatePresetDialog } from "./components/create-preset-dialog";
|
import { CreatePresetDialog } from "./components/create-preset-dialog";
|
||||||
import { useAgentRunsInfinite } from "./use-agent-runs";
|
import { useAgentRunsInfinite, GraphExecutionMeta } from "./use-agent-runs";
|
||||||
import { AgentRunsSelectorList } from "./components/agent-runs-selector-list";
|
import { AgentRunsSelectorList } from "./components/agent-runs-selector-list";
|
||||||
import { AgentScheduleDetailsView } from "./components/agent-schedule-details-view";
|
import { AgentScheduleDetailsView } from "./components/agent-schedule-details-view";
|
||||||
|
|
||||||
@@ -70,9 +69,7 @@ export function OldAgentLibraryView() {
|
|||||||
| { type: "preset"; id: LibraryAgentPresetID }
|
| { type: "preset"; id: LibraryAgentPresetID }
|
||||||
| { type: "schedule"; id: ScheduleID }
|
| { type: "schedule"; id: ScheduleID }
|
||||||
>({ type: "run" });
|
>({ type: "run" });
|
||||||
const [selectedRun, setSelectedRun] = useState<
|
const [selectedRun, setSelectedRun] = useState<GraphExecution | null>(null);
|
||||||
GraphExecution | GraphExecutionMeta | null
|
|
||||||
>(null);
|
|
||||||
const selectedSchedule =
|
const selectedSchedule =
|
||||||
selectedView.type == "schedule"
|
selectedView.type == "schedule"
|
||||||
? schedules.find((s) => s.id == selectedView.id)
|
? schedules.find((s) => s.id == selectedView.id)
|
||||||
@@ -289,7 +286,24 @@ export function OldAgentLibraryView() {
|
|||||||
incrementRuns();
|
incrementRuns();
|
||||||
}
|
}
|
||||||
|
|
||||||
agentRunsQuery.upsertAgentRun(data);
|
// Convert GraphExecution to the expected GraphExecutionMeta type
|
||||||
|
// which includes inputs and other fields from the generated API
|
||||||
|
const executionMeta = {
|
||||||
|
id: data.id,
|
||||||
|
user_id: data.user_id,
|
||||||
|
graph_id: data.graph_id,
|
||||||
|
graph_version: data.graph_version,
|
||||||
|
preset_id: data.preset_id,
|
||||||
|
status: data.status,
|
||||||
|
started_at: data.started_at,
|
||||||
|
ended_at: data.ended_at,
|
||||||
|
stats: data.stats,
|
||||||
|
inputs: data.inputs || {},
|
||||||
|
credential_inputs: {},
|
||||||
|
nodes_input_masks: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
agentRunsQuery.upsertAgentRun(executionMeta);
|
||||||
if (data.id === selectedView.id) {
|
if (data.id === selectedView.id) {
|
||||||
// Update currently viewed run
|
// Update currently viewed run
|
||||||
setSelectedRun(data);
|
setSelectedRun(data);
|
||||||
@@ -306,10 +320,10 @@ export function OldAgentLibraryView() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedView.type != "run" || !selectedView.id) return;
|
if (selectedView.type != "run" || !selectedView.id) return;
|
||||||
|
|
||||||
const newSelectedRun = agentRuns.find((run) => run.id == selectedView.id);
|
const _newSelectedRun = agentRuns.find((run) => run.id == selectedView.id);
|
||||||
if (selectedView.id !== selectedRun?.id) {
|
if (selectedView.id !== selectedRun?.id) {
|
||||||
// Pull partial data from "cache" while waiting for the rest to load
|
// Pull partial data from "cache" while waiting for the rest to load
|
||||||
setSelectedRun((newSelectedRun as GraphExecutionMeta) ?? null);
|
setSelectedRun(null);
|
||||||
}
|
}
|
||||||
}, [api, selectedView, agentRuns, selectedRun?.id]);
|
}, [api, selectedView, agentRuns, selectedRun?.id]);
|
||||||
|
|
||||||
@@ -516,7 +530,7 @@ export function OldAgentLibraryView() {
|
|||||||
onSelectPreset={selectPreset}
|
onSelectPreset={selectPreset}
|
||||||
onSelectSchedule={selectSchedule}
|
onSelectSchedule={selectSchedule}
|
||||||
onSelectDraftNewRun={openRunDraftView}
|
onSelectDraftNewRun={openRunDraftView}
|
||||||
doDeleteRun={setConfirmingDeleteAgentRun}
|
doDeleteRun={(run) => setConfirmingDeleteAgentRun(run as any)}
|
||||||
doDeletePreset={setConfirmingDeleteAgentPreset}
|
doDeletePreset={setConfirmingDeleteAgentPreset}
|
||||||
doDeleteSchedule={deleteSchedule}
|
doDeleteSchedule={deleteSchedule}
|
||||||
doCreatePresetFromRun={setCreatingPresetFromExecutionID}
|
doCreatePresetFromRun={setCreatingPresetFromExecutionID}
|
||||||
@@ -544,7 +558,26 @@ export function OldAgentLibraryView() {
|
|||||||
run={selectedRun}
|
run={selectedRun}
|
||||||
agentActions={agentActions}
|
agentActions={agentActions}
|
||||||
onRun={selectRun}
|
onRun={selectRun}
|
||||||
doDeleteRun={() => setConfirmingDeleteAgentRun(selectedRun)}
|
doDeleteRun={() => {
|
||||||
|
if (selectedRun) {
|
||||||
|
// Convert GraphExecution to GraphExecutionMeta format
|
||||||
|
const runMeta: any = {
|
||||||
|
id: selectedRun.id,
|
||||||
|
user_id: selectedRun.user_id,
|
||||||
|
graph_id: selectedRun.graph_id,
|
||||||
|
graph_version: selectedRun.graph_version,
|
||||||
|
preset_id: selectedRun.preset_id,
|
||||||
|
status: selectedRun.status,
|
||||||
|
started_at: selectedRun.started_at,
|
||||||
|
ended_at: selectedRun.ended_at,
|
||||||
|
stats: selectedRun.stats,
|
||||||
|
inputs: selectedRun.inputs || {},
|
||||||
|
credential_inputs: {},
|
||||||
|
nodes_input_masks: {},
|
||||||
|
};
|
||||||
|
setConfirmingDeleteAgentRun(runMeta);
|
||||||
|
}
|
||||||
|
}}
|
||||||
doCreatePresetFromRun={() =>
|
doCreatePresetFromRun={() =>
|
||||||
setCreatingPresetFromExecutionID(selectedRun.id)
|
setCreatingPresetFromExecutionID(selectedRun.id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,11 +43,9 @@ export function AgentScheduleDetailsView({
|
|||||||
const toastOnFail = useToastOnFail();
|
const toastOnFail = useToastOnFail();
|
||||||
|
|
||||||
// Get user's timezone for displaying schedule times
|
// Get user's timezone for displaying schedule times
|
||||||
const { data: userTimezone } = useGetV1GetUserTimezone({
|
const { data: timezoneData } = useGetV1GetUserTimezone();
|
||||||
query: {
|
const userTimezone =
|
||||||
select: (res) => (res.status === 200 ? res.data.timezone : undefined),
|
timezoneData?.status === 200 ? timezoneData.data.timezone : "UTC";
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const infoStats: { label: string; value: React.ReactNode }[] = useMemo(() => {
|
const infoStats: { label: string; value: React.ReactNode }[] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
import { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent";
|
import { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent";
|
||||||
@@ -8,7 +9,7 @@ interface LibraryAgentCardProps {
|
|||||||
agent: LibraryAgent;
|
agent: LibraryAgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function LibraryAgentCard({
|
const LibraryAgentCard = React.memo(function LibraryAgentCard({
|
||||||
agent: {
|
agent: {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
@@ -103,4 +104,6 @@ export default function LibraryAgentCard({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
|
export default LibraryAgentCard;
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
import AgentFlowListSkeleton from "@/components/monitor/skeletons/AgentFlowListSkeleton";
|
|
||||||
import React from "react";
|
|
||||||
import FlowRunsListSkeleton from "@/components/monitor/skeletons/FlowRunsListSkeleton";
|
|
||||||
import FlowRunsStatusSkeleton from "@/components/monitor/skeletons/FlowRunsStatusSkeleton";
|
|
||||||
|
|
||||||
export default function MonitorLoadingSkeleton() {
|
|
||||||
return (
|
|
||||||
<div className="space-y-4 p-4">
|
|
||||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
|
||||||
{/* Agents Section */}
|
|
||||||
<AgentFlowListSkeleton />
|
|
||||||
|
|
||||||
{/* Runs Section */}
|
|
||||||
<FlowRunsListSkeleton />
|
|
||||||
|
|
||||||
{/* Stats Section */}
|
|
||||||
<FlowRunsStatusSkeleton />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
"use client";
|
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
|
||||||
|
|
||||||
import {
|
|
||||||
GraphExecutionMeta,
|
|
||||||
Schedule,
|
|
||||||
LibraryAgent,
|
|
||||||
ScheduleID,
|
|
||||||
} from "@/lib/autogpt-server-api";
|
|
||||||
|
|
||||||
import { Card } from "@/components/ui/card";
|
|
||||||
import {
|
|
||||||
AgentFlowList,
|
|
||||||
FlowInfo,
|
|
||||||
FlowRunInfo,
|
|
||||||
FlowRunsList,
|
|
||||||
FlowRunsStats,
|
|
||||||
} from "@/components/monitor";
|
|
||||||
import { SchedulesTable } from "@/components/monitor/scheduleTable";
|
|
||||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
|
||||||
|
|
||||||
const Monitor = () => {
|
|
||||||
const [flows, setFlows] = useState<LibraryAgent[]>([]);
|
|
||||||
const [executions, setExecutions] = useState<GraphExecutionMeta[]>([]);
|
|
||||||
const [schedules, setSchedules] = useState<Schedule[]>([]);
|
|
||||||
const [selectedFlow, setSelectedFlow] = useState<LibraryAgent | null>(null);
|
|
||||||
const [selectedRun, setSelectedRun] = useState<GraphExecutionMeta | null>(
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
const [sortColumn, setSortColumn] = useState<keyof Schedule>("id");
|
|
||||||
const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc");
|
|
||||||
const api = useBackendAPI();
|
|
||||||
|
|
||||||
const fetchSchedules = useCallback(async () => {
|
|
||||||
setSchedules(await api.listAllGraphsExecutionSchedules());
|
|
||||||
}, [api]);
|
|
||||||
|
|
||||||
const removeSchedule = useCallback(
|
|
||||||
async (scheduleId: ScheduleID) => {
|
|
||||||
const removedSchedule =
|
|
||||||
await api.deleteGraphExecutionSchedule(scheduleId);
|
|
||||||
setSchedules(schedules.filter((s) => s.id !== removedSchedule.id));
|
|
||||||
},
|
|
||||||
[schedules, api],
|
|
||||||
);
|
|
||||||
|
|
||||||
const fetchAgents = useCallback(() => {
|
|
||||||
api.listLibraryAgents().then((response) => {
|
|
||||||
setFlows(response.agents);
|
|
||||||
});
|
|
||||||
api.getExecutions().then((executions) => {
|
|
||||||
setExecutions(executions);
|
|
||||||
});
|
|
||||||
}, [api]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchAgents();
|
|
||||||
}, [fetchAgents]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchSchedules();
|
|
||||||
}, [fetchSchedules]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const intervalId = setInterval(() => fetchAgents(), 5000);
|
|
||||||
return () => clearInterval(intervalId);
|
|
||||||
}, [fetchAgents, flows]);
|
|
||||||
|
|
||||||
const column1 = "md:col-span-2 xl:col-span-3 xxl:col-span-2";
|
|
||||||
const column2 = "md:col-span-3 lg:col-span-2 xl:col-span-3";
|
|
||||||
const column3 = "col-span-full xl:col-span-4 xxl:col-span-5";
|
|
||||||
|
|
||||||
const handleSort = (column: keyof Schedule) => {
|
|
||||||
if (sortColumn === column) {
|
|
||||||
setSortDirection(sortDirection === "asc" ? "desc" : "asc");
|
|
||||||
} else {
|
|
||||||
setSortColumn(column);
|
|
||||||
setSortDirection("asc");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="grid grid-cols-1 gap-4 p-4 md:grid-cols-5 lg:grid-cols-4 xl:grid-cols-10"
|
|
||||||
data-testid="monitor-page"
|
|
||||||
>
|
|
||||||
<AgentFlowList
|
|
||||||
className={column1}
|
|
||||||
flows={flows}
|
|
||||||
executions={executions}
|
|
||||||
selectedFlow={selectedFlow}
|
|
||||||
onSelectFlow={(f) => {
|
|
||||||
setSelectedRun(null);
|
|
||||||
setSelectedFlow(f.id == selectedFlow?.id ? null : f);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<FlowRunsList
|
|
||||||
className={column2}
|
|
||||||
flows={flows}
|
|
||||||
executions={[
|
|
||||||
...(selectedFlow
|
|
||||||
? executions.filter((v) => v.graph_id == selectedFlow.graph_id)
|
|
||||||
: executions),
|
|
||||||
].sort((a, b) => b.started_at.getTime() - a.started_at.getTime())}
|
|
||||||
selectedRun={selectedRun}
|
|
||||||
onSelectRun={(r) => setSelectedRun(r.id == selectedRun?.id ? null : r)}
|
|
||||||
/>
|
|
||||||
{(selectedRun && (
|
|
||||||
<FlowRunInfo
|
|
||||||
agent={
|
|
||||||
selectedFlow ||
|
|
||||||
flows.find((f) => f.graph_id == selectedRun.graph_id)!
|
|
||||||
}
|
|
||||||
execution={selectedRun}
|
|
||||||
className={column3}
|
|
||||||
/>
|
|
||||||
)) ||
|
|
||||||
(selectedFlow && (
|
|
||||||
<FlowInfo
|
|
||||||
flow={selectedFlow}
|
|
||||||
executions={executions.filter(
|
|
||||||
(e) => e.graph_id == selectedFlow.graph_id,
|
|
||||||
)}
|
|
||||||
className={column3}
|
|
||||||
refresh={() => {
|
|
||||||
fetchAgents();
|
|
||||||
setSelectedFlow(null);
|
|
||||||
setSelectedRun(null);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)) || (
|
|
||||||
<Card className={`p-6 ${column3}`}>
|
|
||||||
<FlowRunsStats flows={flows} executions={executions} />
|
|
||||||
</Card>
|
|
||||||
)}
|
|
||||||
<div className="col-span-full xl:col-span-6">
|
|
||||||
<SchedulesTable
|
|
||||||
schedules={schedules} // all schedules
|
|
||||||
agents={flows} // for filtering purpose
|
|
||||||
onRemoveSchedule={removeSchedule}
|
|
||||||
sortColumn={sortColumn}
|
|
||||||
sortDirection={sortDirection}
|
|
||||||
onSort={handleSort}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Monitor;
|
|
||||||
@@ -40,7 +40,7 @@ export default function SettingsPage() {
|
|||||||
redirect("/login");
|
redirect("/login");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preferencesError || !preferences || !preferences.preferences) {
|
if (preferencesError || !preferences || !("preferences" in preferences)) {
|
||||||
return "Error..."; // TODO: Will use a Error reusable components from Block Menu redesign
|
return "Error..."; // TODO: Will use a Error reusable components from Block Menu redesign
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1729,7 +1729,9 @@
|
|||||||
"description": "Successful Response",
|
"description": "Successful Response",
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": { "$ref": "#/components/schemas/GraphExecutionMeta" }
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ExecuteGraphResponse"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3922,7 +3924,11 @@
|
|||||||
"description": "Successful Response",
|
"description": "Successful Response",
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": { "$ref": "#/components/schemas/GraphExecutionMeta" }
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true,
|
||||||
|
"title": "Response Postv2Execute A Preset"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4388,6 +4394,379 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v2/chat/sessions": {
|
||||||
|
"post": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "Create Session",
|
||||||
|
"description": "Create a new chat session for the authenticated or anonymous user.\n\nArgs:\n request: Session creation parameters\n user_id: Optional authenticated user ID\n\nReturns:\n Created session details",
|
||||||
|
"operationId": "postV2CreateSession",
|
||||||
|
"security": [{ "HTTPBearer": [] }],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/CreateSessionRequest" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CreateSessionResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": { "description": "Unauthorized" },
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/HTTPValidationError" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "List Sessions",
|
||||||
|
"description": "List chat sessions for the authenticated user.\n\nArgs:\n limit: Maximum number of sessions to return\n offset: Number of sessions to skip\n include_last_message: Whether to include the last message\n user_id: Authenticated user ID\n\nReturns:\n List of user's chat sessions",
|
||||||
|
"operationId": "getV2ListSessions",
|
||||||
|
"security": [{ "HTTPBearerJWT": [] }],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "limit",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 100,
|
||||||
|
"minimum": 1,
|
||||||
|
"default": 50,
|
||||||
|
"title": "Limit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "offset",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"default": 0,
|
||||||
|
"title": "Offset"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "include_last_message",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"title": "Include Last Message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/SessionListResponse" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/components/responses/HTTP401NotAuthenticatedError"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/HTTPValidationError" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/chat/sessions/{session_id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "Get Session",
|
||||||
|
"description": "Get details of a specific chat session.\n\nArgs:\n session_id: ID of the session to retrieve\n include_messages: Whether to include all messages\n user_id: Authenticated user ID\n\nReturns:\n Session details with optional messages",
|
||||||
|
"operationId": "getV2GetSession",
|
||||||
|
"security": [{ "HTTPBearer": [] }],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "session_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": { "type": "string", "title": "Session Id" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "include_messages",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"title": "Include Messages"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SessionDetailResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": { "description": "Unauthorized" },
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/HTTPValidationError" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "Delete Session",
|
||||||
|
"description": "Delete a chat session and all its messages.\n\nArgs:\n session_id: ID of the session to delete\n user_id: Authenticated user ID\n\nReturns:\n Deletion confirmation",
|
||||||
|
"operationId": "deleteV2DeleteSession",
|
||||||
|
"security": [{ "HTTPBearerJWT": [] }],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "session_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": { "type": "string", "title": "Session Id" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true,
|
||||||
|
"title": "Response Deletev2Deletesession"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/components/responses/HTTP401NotAuthenticatedError"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/HTTPValidationError" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/chat/sessions/{session_id}/messages": {
|
||||||
|
"post": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "Send Message",
|
||||||
|
"description": "Send a message to a chat session (non-streaming).\n\nThis endpoint processes the message and returns the complete response.\nFor streaming responses, use the /stream endpoint.\n\nArgs:\n session_id: ID of the session\n request: Message parameters\n user_id: Authenticated user ID\n\nReturns:\n Complete assistant response",
|
||||||
|
"operationId": "postV2SendMessage",
|
||||||
|
"security": [{ "HTTPBearerJWT": [] }],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "session_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": { "type": "string", "title": "Session Id" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/SendMessageRequest" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/SendMessageResponse" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/components/responses/HTTP401NotAuthenticatedError"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/HTTPValidationError" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/chat/sessions/{session_id}/stream": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "Stream Chat",
|
||||||
|
"description": "Stream chat responses using Server-Sent Events (SSE).\n\nThis endpoint streams the AI response in real-time, including:\n- Text chunks as they're generated\n- Tool call UI elements\n- Tool execution results\n\nArgs:\n session_id: ID of the session\n message: User's message\n model: AI model to use\n max_context: Maximum context messages\n user_id: Optional authenticated user ID\n\nReturns:\n SSE stream of response chunks",
|
||||||
|
"operationId": "getV2StreamChat",
|
||||||
|
"security": [{ "HTTPBearer": [] }],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "session_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": { "type": "string", "title": "Session Id" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "message",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 10000,
|
||||||
|
"title": "Message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "model",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "gpt-4o",
|
||||||
|
"title": "Model"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "max_context",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 100,
|
||||||
|
"minimum": 1,
|
||||||
|
"default": 50,
|
||||||
|
"title": "Max Context"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": { "application/json": { "schema": {} } }
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": { "description": "Unauthorized" },
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/HTTPValidationError" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/chat/sessions/{session_id}/assign-user": {
|
||||||
|
"patch": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "Assign User To Session",
|
||||||
|
"description": "Assign an authenticated user to an anonymous session.\n\nThis is called after a user logs in to claim their anonymous session.\n\nArgs:\n session_id: ID of the anonymous session\n user_id: Authenticated user ID\n\nReturns:\n Success status",
|
||||||
|
"operationId": "patchV2AssignUserToSession",
|
||||||
|
"security": [{ "HTTPBearerJWT": [] }],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "session_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": { "type": "string", "title": "Session Id" }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true,
|
||||||
|
"title": "Response Patchv2Assignusertosession"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": {
|
||||||
|
"$ref": "#/components/responses/HTTP401NotAuthenticatedError"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": { "$ref": "#/components/schemas/HTTPValidationError" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v2/chat/health": {
|
||||||
|
"get": {
|
||||||
|
"tags": ["v2", "chat", "chat"],
|
||||||
|
"summary": "Health Check",
|
||||||
|
"description": "Check if the chat service is healthy.\n\nReturns:\n Health status",
|
||||||
|
"operationId": "getV2HealthCheck",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"additionalProperties": true,
|
||||||
|
"type": "object",
|
||||||
|
"title": "Response Getv2Healthcheck"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": { "description": "Resource not found" },
|
||||||
|
"401": { "description": "Unauthorized" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/email/unsubscribe": {
|
"/api/email/unsubscribe": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": ["v1", "email"],
|
"tags": ["v1", "email"],
|
||||||
@@ -4857,13 +5236,6 @@
|
|||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"title": "Inputs"
|
"title": "Inputs"
|
||||||
},
|
|
||||||
"credential_inputs": {
|
|
||||||
"additionalProperties": {
|
|
||||||
"$ref": "#/components/schemas/CredentialsMetaInput"
|
|
||||||
},
|
|
||||||
"type": "object",
|
|
||||||
"title": "Credential Inputs"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -4957,6 +5329,32 @@
|
|||||||
"required": ["graph"],
|
"required": ["graph"],
|
||||||
"title": "CreateGraph"
|
"title": "CreateGraph"
|
||||||
},
|
},
|
||||||
|
"CreateSessionRequest": {
|
||||||
|
"properties": {
|
||||||
|
"metadata": {
|
||||||
|
"anyOf": [
|
||||||
|
{ "additionalProperties": true, "type": "object" },
|
||||||
|
{ "type": "null" }
|
||||||
|
],
|
||||||
|
"title": "Metadata",
|
||||||
|
"description": "Optional metadata"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"title": "CreateSessionRequest",
|
||||||
|
"description": "Request model for creating a new chat session."
|
||||||
|
},
|
||||||
|
"CreateSessionResponse": {
|
||||||
|
"properties": {
|
||||||
|
"id": { "type": "string", "title": "Id" },
|
||||||
|
"created_at": { "type": "string", "title": "Created At" },
|
||||||
|
"user_id": { "type": "string", "title": "User Id" }
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "created_at", "user_id"],
|
||||||
|
"title": "CreateSessionResponse",
|
||||||
|
"description": "Response model for created chat session."
|
||||||
|
},
|
||||||
"Creator": {
|
"Creator": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": { "type": "string", "title": "Name" },
|
"name": { "type": "string", "title": "Name" },
|
||||||
@@ -5144,6 +5542,14 @@
|
|||||||
"required": ["url", "relevance_score"],
|
"required": ["url", "relevance_score"],
|
||||||
"title": "Document"
|
"title": "Document"
|
||||||
},
|
},
|
||||||
|
"ExecuteGraphResponse": {
|
||||||
|
"properties": {
|
||||||
|
"graph_exec_id": { "type": "string", "title": "Graph Exec Id" }
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": ["graph_exec_id"],
|
||||||
|
"title": "ExecuteGraphResponse"
|
||||||
|
},
|
||||||
"Graph": {
|
"Graph": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": { "type": "string", "title": "Id" },
|
"id": { "type": "string", "title": "Id" },
|
||||||
@@ -7039,6 +7445,98 @@
|
|||||||
"required": ["items", "total_items", "page", "more_pages"],
|
"required": ["items", "total_items", "page", "more_pages"],
|
||||||
"title": "SearchResponse"
|
"title": "SearchResponse"
|
||||||
},
|
},
|
||||||
|
"SendMessageRequest": {
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 10000,
|
||||||
|
"minLength": 1,
|
||||||
|
"title": "Message",
|
||||||
|
"description": "Message content"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Model",
|
||||||
|
"description": "AI model to use",
|
||||||
|
"default": "gpt-4o"
|
||||||
|
},
|
||||||
|
"max_context_messages": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 100.0,
|
||||||
|
"minimum": 1.0,
|
||||||
|
"title": "Max Context Messages",
|
||||||
|
"description": "Max context messages",
|
||||||
|
"default": 50
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": ["message"],
|
||||||
|
"title": "SendMessageRequest",
|
||||||
|
"description": "Request model for sending a chat message."
|
||||||
|
},
|
||||||
|
"SendMessageResponse": {
|
||||||
|
"properties": {
|
||||||
|
"message_id": { "type": "string", "title": "Message Id" },
|
||||||
|
"content": { "type": "string", "title": "Content" },
|
||||||
|
"role": { "type": "string", "title": "Role" },
|
||||||
|
"tokens_used": {
|
||||||
|
"anyOf": [
|
||||||
|
{ "additionalProperties": true, "type": "object" },
|
||||||
|
{ "type": "null" }
|
||||||
|
],
|
||||||
|
"title": "Tokens Used"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": ["message_id", "content", "role"],
|
||||||
|
"title": "SendMessageResponse",
|
||||||
|
"description": "Response model for non-streaming message."
|
||||||
|
},
|
||||||
|
"SessionDetailResponse": {
|
||||||
|
"properties": {
|
||||||
|
"id": { "type": "string", "title": "Id" },
|
||||||
|
"created_at": { "type": "string", "title": "Created At" },
|
||||||
|
"updated_at": { "type": "string", "title": "Updated At" },
|
||||||
|
"user_id": { "type": "string", "title": "User Id" },
|
||||||
|
"messages": {
|
||||||
|
"items": { "additionalProperties": true, "type": "object" },
|
||||||
|
"type": "array",
|
||||||
|
"title": "Messages"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"additionalProperties": true,
|
||||||
|
"type": "object",
|
||||||
|
"title": "Metadata"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"user_id",
|
||||||
|
"messages",
|
||||||
|
"metadata"
|
||||||
|
],
|
||||||
|
"title": "SessionDetailResponse",
|
||||||
|
"description": "Response model for session details."
|
||||||
|
},
|
||||||
|
"SessionListResponse": {
|
||||||
|
"properties": {
|
||||||
|
"sessions": {
|
||||||
|
"items": { "additionalProperties": true, "type": "object" },
|
||||||
|
"type": "array",
|
||||||
|
"title": "Sessions"
|
||||||
|
},
|
||||||
|
"total": { "type": "integer", "title": "Total" },
|
||||||
|
"limit": { "type": "integer", "title": "Limit" },
|
||||||
|
"offset": { "type": "integer", "title": "Offset" }
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": ["sessions", "total", "limit", "offset"],
|
||||||
|
"title": "SessionListResponse",
|
||||||
|
"description": "Response model for session list."
|
||||||
|
},
|
||||||
"SetGraphActiveVersion": {
|
"SetGraphActiveVersion": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"active_graph_version": {
|
"active_graph_version": {
|
||||||
@@ -9102,6 +9600,7 @@
|
|||||||
"scheme": "bearer",
|
"scheme": "bearer",
|
||||||
"bearerFormat": "jwt"
|
"bearerFormat": "jwt"
|
||||||
},
|
},
|
||||||
|
"HTTPBearer": { "type": "http", "scheme": "bearer" },
|
||||||
"APIKeyAuthenticator-X-Postmark-Webhook-Token": {
|
"APIKeyAuthenticator-X-Postmark-Webhook-Token": {
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"in": "header",
|
"in": "header",
|
||||||
|
|||||||
18
autogpt_platform/frontend/src/components/FlowLazy.tsx
Normal file
18
autogpt_platform/frontend/src/components/FlowLazy.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import dynamic from "next/dynamic";
|
||||||
|
|
||||||
|
// Lazy load the Flow component which includes the heavy @xyflow/react library
|
||||||
|
const FlowEditor = dynamic(() => import("./Flow"), {
|
||||||
|
loading: () => (
|
||||||
|
<div className="flex h-full items-center justify-center">
|
||||||
|
<div className="flex flex-col items-center gap-4">
|
||||||
|
<div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent"></div>
|
||||||
|
<p className="text-sm text-muted-foreground">
|
||||||
|
Loading workflow editor...
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
ssr: false, // Disable SSR for this component
|
||||||
|
});
|
||||||
|
|
||||||
|
export default FlowEditor;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import Image from "next/image";
|
||||||
import { Text } from "../../../../atoms/Text/Text";
|
import { Text } from "../../../../atoms/Text/Text";
|
||||||
import { Button } from "../../../../atoms/Button/Button";
|
import { Button } from "../../../../atoms/Button/Button";
|
||||||
import { StepHeader } from "../StepHeader";
|
import { StepHeader } from "../StepHeader";
|
||||||
@@ -147,11 +148,13 @@ export function AgentSelectStep({
|
|||||||
aria-pressed={selectedAgentId === agent.id}
|
aria-pressed={selectedAgentId === agent.id}
|
||||||
>
|
>
|
||||||
<div className="relative h-32 bg-zinc-400 sm:h-40">
|
<div className="relative h-32 bg-zinc-400 sm:h-40">
|
||||||
<img
|
<Image
|
||||||
src={agent.imageSrc}
|
src={agent.imageSrc}
|
||||||
alt={agent.name}
|
alt={agent.name}
|
||||||
className="h-full w-full object-cover"
|
fill
|
||||||
|
className="object-cover"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
sizes="(max-width: 640px) 100vw, (max-width: 768px) 50vw, 33vw"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-2 p-3">
|
<div className="flex flex-col gap-2 p-3">
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { IconLaptop } from "@/components/ui/icons";
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import {
|
import {
|
||||||
CubeIcon,
|
CubeIcon,
|
||||||
@@ -47,14 +46,6 @@ export function NavbarLink({ name, href }: Props) {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{href === "/monitor" && (
|
|
||||||
<IconLaptop
|
|
||||||
className={cn(
|
|
||||||
iconWidthClass,
|
|
||||||
isActive && "text-white dark:text-black",
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{href === "/library" && (
|
{href === "/library" && (
|
||||||
<HouseIcon
|
<HouseIcon
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
@@ -81,9 +81,7 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
|||||||
? IconType.Library
|
? IconType.Library
|
||||||
: link.name === "Build"
|
: link.name === "Build"
|
||||||
? IconType.Builder
|
? IconType.Builder
|
||||||
: link.name === "Monitor"
|
: IconType.LayoutDashboard,
|
||||||
? IconType.Library
|
|
||||||
: IconType.LayoutDashboard,
|
|
||||||
text: link.name,
|
text: link.name,
|
||||||
href: link.href,
|
href: link.href,
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -1,170 +0,0 @@
|
|||||||
import { GraphExecutionMeta, LibraryAgent } from "@/lib/autogpt-server-api";
|
|
||||||
import React from "react";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { TextRenderer } from "@/components/ui/render";
|
|
||||||
import Link from "next/link";
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/components/ui/dropdown-menu";
|
|
||||||
import { ChevronDownIcon, EnterIcon } from "@radix-ui/react-icons";
|
|
||||||
import { AgentImportForm } from "@/components/agent-import-form";
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "@/components/ui/table";
|
|
||||||
import moment from "moment/moment";
|
|
||||||
import { DialogTitle } from "@/components/ui/dialog";
|
|
||||||
|
|
||||||
export const AgentFlowList = ({
|
|
||||||
flows,
|
|
||||||
executions,
|
|
||||||
selectedFlow,
|
|
||||||
onSelectFlow,
|
|
||||||
className,
|
|
||||||
}: {
|
|
||||||
flows: LibraryAgent[];
|
|
||||||
executions?: GraphExecutionMeta[];
|
|
||||||
selectedFlow: LibraryAgent | null;
|
|
||||||
onSelectFlow: (f: LibraryAgent) => void;
|
|
||||||
className?: string;
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<Card className={className}>
|
|
||||||
<CardHeader className="flex-row items-center justify-between space-x-3 space-y-0">
|
|
||||||
<CardTitle>Agents</CardTitle>
|
|
||||||
|
|
||||||
<div className="flex items-center">
|
|
||||||
{/* Split "Create" button */}
|
|
||||||
<Button variant="outline" className="rounded-r-none" asChild>
|
|
||||||
<Link href="/build">Create</Link>
|
|
||||||
</Button>
|
|
||||||
<Dialog>
|
|
||||||
{/* https://ui.shadcn.com/docs/components/dialog#notes */}
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
className={"rounded-l-none border-l-0 px-2"}
|
|
||||||
data-testid="create-agent-dropdown"
|
|
||||||
>
|
|
||||||
<ChevronDownIcon />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
|
|
||||||
<DropdownMenuContent>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<DropdownMenuItem data-testid="import-agent-from-file">
|
|
||||||
<EnterIcon className="mr-2" /> Import from file
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DialogTrigger>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
|
|
||||||
<DialogContent>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle className="sr-only">Import Agent</DialogTitle>
|
|
||||||
<h2 className="text-lg font-semibold">
|
|
||||||
Import an Agent from a file
|
|
||||||
</h2>
|
|
||||||
</DialogHeader>
|
|
||||||
<AgentImportForm />
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</div>
|
|
||||||
</CardHeader>
|
|
||||||
|
|
||||||
<CardContent>
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead>Name</TableHead>
|
|
||||||
{/* <TableHead>Status</TableHead> */}
|
|
||||||
{/* <TableHead>Last updated</TableHead> */}
|
|
||||||
{executions && (
|
|
||||||
<TableHead className="md:hidden lg:table-cell">
|
|
||||||
# of runs
|
|
||||||
</TableHead>
|
|
||||||
)}
|
|
||||||
{executions && <TableHead>Last run</TableHead>}
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody data-testid="agent-flow-list-body">
|
|
||||||
{flows
|
|
||||||
.map((flow) => {
|
|
||||||
let runCount = 0,
|
|
||||||
lastRun: GraphExecutionMeta | null = null;
|
|
||||||
if (executions) {
|
|
||||||
const _flowRuns = executions.filter(
|
|
||||||
(r) => r.graph_id == flow.graph_id,
|
|
||||||
);
|
|
||||||
runCount = _flowRuns.length;
|
|
||||||
lastRun =
|
|
||||||
runCount == 0
|
|
||||||
? null
|
|
||||||
: _flowRuns.reduce((a, c) =>
|
|
||||||
a.started_at > c.started_at ? a : c,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return { flow, runCount, lastRun };
|
|
||||||
})
|
|
||||||
.sort((a, b) => {
|
|
||||||
if (!a.lastRun && !b.lastRun) return 0;
|
|
||||||
if (!a.lastRun) return 1;
|
|
||||||
if (!b.lastRun) return -1;
|
|
||||||
return (
|
|
||||||
b.lastRun.started_at.getTime() -
|
|
||||||
a.lastRun.started_at.getTime()
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.map(({ flow, runCount, lastRun }) => (
|
|
||||||
<TableRow
|
|
||||||
key={flow.id}
|
|
||||||
data-testid={flow.id}
|
|
||||||
data-name={flow.name}
|
|
||||||
className="cursor-pointer"
|
|
||||||
onClick={() => onSelectFlow(flow)}
|
|
||||||
data-state={selectedFlow?.id == flow.id ? "selected" : null}
|
|
||||||
>
|
|
||||||
<TableCell>
|
|
||||||
<TextRenderer value={flow.name} truncateLengthLimit={30} />
|
|
||||||
</TableCell>
|
|
||||||
{/* <TableCell><FlowStatusBadge status={flow.status ?? "active"} /></TableCell> */}
|
|
||||||
{/* <TableCell>
|
|
||||||
{flow.updatedAt ?? "???"}
|
|
||||||
</TableCell> */}
|
|
||||||
{executions && (
|
|
||||||
<TableCell className="md:hidden lg:table-cell">
|
|
||||||
{runCount}
|
|
||||||
</TableCell>
|
|
||||||
)}
|
|
||||||
{executions &&
|
|
||||||
(!lastRun ? (
|
|
||||||
<TableCell />
|
|
||||||
) : (
|
|
||||||
<TableCell title={moment(lastRun.started_at).toString()}>
|
|
||||||
{moment(lastRun.started_at).fromNow()}
|
|
||||||
</TableCell>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default AgentFlowList;
|
|
||||||
@@ -1,238 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import {
|
|
||||||
Graph,
|
|
||||||
GraphExecutionMeta,
|
|
||||||
LibraryAgent,
|
|
||||||
} from "@/lib/autogpt-server-api";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuRadioGroup,
|
|
||||||
DropdownMenuRadioItem,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/components/ui/dropdown-menu";
|
|
||||||
import { Button, buttonVariants } from "@/components/ui/button";
|
|
||||||
import {
|
|
||||||
ClockIcon,
|
|
||||||
ExitIcon,
|
|
||||||
Pencil2Icon,
|
|
||||||
PlayIcon,
|
|
||||||
TrashIcon,
|
|
||||||
} from "@radix-ui/react-icons";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { exportAsJSONFile } from "@/lib/utils";
|
|
||||||
import { FlowRunsStats } from "@/components/monitor/index";
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogDescription,
|
|
||||||
DialogFooter,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import useAgentGraph from "@/hooks/useAgentGraph";
|
|
||||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
|
||||||
import { RunnerInputDialog } from "@/components/runner-ui/RunnerInputUI";
|
|
||||||
|
|
||||||
export const FlowInfo: React.FC<
|
|
||||||
React.HTMLAttributes<HTMLDivElement> & {
|
|
||||||
flow: LibraryAgent;
|
|
||||||
executions: GraphExecutionMeta[];
|
|
||||||
flowVersion?: number | "all";
|
|
||||||
refresh: () => void;
|
|
||||||
}
|
|
||||||
> = ({ flow, executions, flowVersion, refresh, ...props }) => {
|
|
||||||
const { savedAgent, saveAndRun, stopRun, isRunning } = useAgentGraph(
|
|
||||||
flow.graph_id,
|
|
||||||
flow.graph_version,
|
|
||||||
undefined,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
const api = useBackendAPI();
|
|
||||||
|
|
||||||
const [flowVersions, setFlowVersions] = useState<Graph[] | null>(null);
|
|
||||||
const [selectedVersion, setSelectedFlowVersion] = useState(
|
|
||||||
flowVersion ?? "all",
|
|
||||||
);
|
|
||||||
const selectedFlowVersion: Graph | undefined = flowVersions?.find(
|
|
||||||
(v) =>
|
|
||||||
v.version ==
|
|
||||||
(selectedVersion == "all" ? flow.graph_version : selectedVersion),
|
|
||||||
);
|
|
||||||
|
|
||||||
const hasInputs = Object.keys(flow.input_schema.properties).length > 0;
|
|
||||||
const hasCredentialsInputs =
|
|
||||||
Object.keys(flow.credentials_input_schema.properties).length > 0;
|
|
||||||
|
|
||||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
|
||||||
const [isRunDialogOpen, setIsRunDialogOpen] = useState(false);
|
|
||||||
const isDisabled = !selectedFlowVersion;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
api
|
|
||||||
.getGraphAllVersions(flow.graph_id)
|
|
||||||
.then((result) => setFlowVersions(result));
|
|
||||||
}, [flow.graph_id, api]);
|
|
||||||
|
|
||||||
const openRunDialog = () => setIsRunDialogOpen(true);
|
|
||||||
|
|
||||||
const runOrOpenInput = () => {
|
|
||||||
if (hasInputs || hasCredentialsInputs) {
|
|
||||||
openRunDialog();
|
|
||||||
} else {
|
|
||||||
saveAndRun({}, {});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Card {...props}>
|
|
||||||
<CardHeader className="">
|
|
||||||
<CardTitle>
|
|
||||||
{flow.name} <span className="font-light">v{flow.graph_version}</span>
|
|
||||||
</CardTitle>
|
|
||||||
<div className="flex flex-col space-y-2 py-6">
|
|
||||||
{(flowVersions?.length ?? 0) > 1 && (
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="outline">
|
|
||||||
<ClockIcon className="mr-2" />
|
|
||||||
{selectedVersion == "all"
|
|
||||||
? "All versions"
|
|
||||||
: `Version ${selectedVersion}`}
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent className="w-56">
|
|
||||||
<DropdownMenuLabel>Choose a version</DropdownMenuLabel>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuRadioGroup
|
|
||||||
value={String(selectedVersion)}
|
|
||||||
onValueChange={(choice: string) =>
|
|
||||||
setSelectedFlowVersion(
|
|
||||||
choice == "all" ? choice : Number(choice),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<DropdownMenuRadioItem value="all">
|
|
||||||
All versions
|
|
||||||
</DropdownMenuRadioItem>
|
|
||||||
{flowVersions?.map((v) => (
|
|
||||||
<DropdownMenuRadioItem
|
|
||||||
key={v.version}
|
|
||||||
value={v.version.toString()}
|
|
||||||
>
|
|
||||||
Version {v.version}
|
|
||||||
{v.is_active ? " (active)" : ""}
|
|
||||||
</DropdownMenuRadioItem>
|
|
||||||
))}
|
|
||||||
</DropdownMenuRadioGroup>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
)}
|
|
||||||
{flow.can_access_graph && (
|
|
||||||
<Link
|
|
||||||
className={buttonVariants({ variant: "default" })}
|
|
||||||
href={`/build?flowID=${flow.graph_id}&flowVersion=${flow.graph_version}`}
|
|
||||||
>
|
|
||||||
<Pencil2Icon className="mr-2" />
|
|
||||||
Open in Builder
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
{flow.can_access_graph && (
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
className="px-2.5"
|
|
||||||
title="Export to a JSON-file"
|
|
||||||
data-testid="export-button"
|
|
||||||
onClick={() =>
|
|
||||||
api
|
|
||||||
.getGraph(flow.graph_id, selectedFlowVersion!.version, true)
|
|
||||||
.then((graph) =>
|
|
||||||
exportAsJSONFile(
|
|
||||||
graph,
|
|
||||||
`${flow.name}_v${selectedFlowVersion!.version}.json`,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ExitIcon className="mr-2" /> Export
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
className="bg-purple-500 text-white hover:bg-purple-700"
|
|
||||||
onClick={!isRunning ? runOrOpenInput : stopRun}
|
|
||||||
disabled={isDisabled}
|
|
||||||
title={!isRunning ? "Run Agent" : "Stop Agent"}
|
|
||||||
>
|
|
||||||
<PlayIcon className="mr-2" />
|
|
||||||
{isRunning ? "Stop Agent" : "Run Agent"}
|
|
||||||
</Button>
|
|
||||||
{flow.can_access_graph && (
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
onClick={() => setIsDeleteModalOpen(true)}
|
|
||||||
data-testid="delete-button"
|
|
||||||
>
|
|
||||||
<TrashIcon className="mr-2" />
|
|
||||||
Delete Agent
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<FlowRunsStats
|
|
||||||
flows={[flow]}
|
|
||||||
executions={executions.filter(
|
|
||||||
(execution) =>
|
|
||||||
execution.graph_id == flow.graph_id &&
|
|
||||||
(selectedVersion == "all" ||
|
|
||||||
execution.graph_version == selectedVersion),
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</CardContent>
|
|
||||||
<Dialog open={isDeleteModalOpen} onOpenChange={setIsDeleteModalOpen}>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>Delete Agent</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
Are you sure you want to delete this agent? <br />
|
|
||||||
This action cannot be undone.
|
|
||||||
</DialogDescription>
|
|
||||||
</DialogHeader>
|
|
||||||
<DialogFooter>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
onClick={() => setIsDeleteModalOpen(false)}
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="destructive"
|
|
||||||
onClick={() => {
|
|
||||||
api.deleteLibraryAgent(flow.id).then(() => {
|
|
||||||
setIsDeleteModalOpen(false);
|
|
||||||
refresh();
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</Button>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
{savedAgent && (
|
|
||||||
<RunnerInputDialog
|
|
||||||
isOpen={isRunDialogOpen}
|
|
||||||
doClose={() => setIsRunDialogOpen(false)}
|
|
||||||
graph={savedAgent}
|
|
||||||
doRun={saveAndRun}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default FlowInfo;
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
import React, { useCallback, useEffect, useState } from "react";
|
|
||||||
import { GraphExecutionMeta, LibraryAgent } from "@/lib/autogpt-server-api";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { Button, buttonVariants } from "@/components/ui/button";
|
|
||||||
import { IconSquare } from "@/components/ui/icons";
|
|
||||||
import { ExitIcon, Pencil2Icon } from "@radix-ui/react-icons";
|
|
||||||
import moment from "moment/moment";
|
|
||||||
import { FlowRunStatusBadge } from "@/components/monitor/FlowRunStatusBadge";
|
|
||||||
import RunnerOutputUI, { OutputNodeInfo } from "../runner-ui/RunnerOutputUI";
|
|
||||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
|
||||||
|
|
||||||
export const FlowRunInfo: React.FC<
|
|
||||||
React.HTMLAttributes<HTMLDivElement> & {
|
|
||||||
agent: LibraryAgent;
|
|
||||||
execution: GraphExecutionMeta;
|
|
||||||
}
|
|
||||||
> = ({ agent, execution, ...props }) => {
|
|
||||||
const [isOutputOpen, setIsOutputOpen] = useState(false);
|
|
||||||
const [blockOutputs, setBlockOutputs] = useState<OutputNodeInfo[]>([]);
|
|
||||||
const api = useBackendAPI();
|
|
||||||
|
|
||||||
const fetchBlockResults = useCallback(async () => {
|
|
||||||
const graph = await api.getGraph(agent.graph_id, agent.graph_version);
|
|
||||||
const graphExecution = await api.getGraphExecutionInfo(
|
|
||||||
agent.graph_id,
|
|
||||||
execution.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Transform results to BlockOutput format
|
|
||||||
setBlockOutputs(
|
|
||||||
Object.entries(graphExecution.outputs).flatMap(([key, values]) =>
|
|
||||||
values.map(
|
|
||||||
(value) =>
|
|
||||||
({
|
|
||||||
metadata: {
|
|
||||||
name: graph.output_schema.properties[key].title || "Output",
|
|
||||||
description:
|
|
||||||
graph.output_schema.properties[key].description ||
|
|
||||||
"Output from the agent",
|
|
||||||
},
|
|
||||||
result: value,
|
|
||||||
}) satisfies OutputNodeInfo,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}, [api, agent.graph_id, agent.graph_version, execution.id]);
|
|
||||||
|
|
||||||
// Fetch graph and execution data
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isOutputOpen) return;
|
|
||||||
fetchBlockResults();
|
|
||||||
}, [isOutputOpen, fetchBlockResults]);
|
|
||||||
|
|
||||||
if (execution.graph_id != agent.graph_id) {
|
|
||||||
throw new Error(
|
|
||||||
`FlowRunInfo can't be used with non-matching execution.graph_id and flow.id`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleStopRun = useCallback(() => {
|
|
||||||
api.stopGraphExecution(agent.graph_id, execution.id);
|
|
||||||
}, [api, agent.graph_id, execution.id]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Card {...props}>
|
|
||||||
<CardHeader className="flex-row items-center justify-between space-x-3 space-y-0">
|
|
||||||
<div>
|
|
||||||
<CardTitle>
|
|
||||||
{agent.name}{" "}
|
|
||||||
<span className="font-light">v{execution.graph_version}</span>
|
|
||||||
</CardTitle>
|
|
||||||
</div>
|
|
||||||
<div className="flex space-x-2">
|
|
||||||
{execution.status === "RUNNING" && (
|
|
||||||
<Button onClick={handleStopRun} variant="destructive">
|
|
||||||
<IconSquare className="mr-2" /> Stop Run
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<Button onClick={() => setIsOutputOpen(true)} variant="outline">
|
|
||||||
<ExitIcon className="mr-2" /> View Outputs
|
|
||||||
</Button>
|
|
||||||
{agent.can_access_graph && (
|
|
||||||
<Link
|
|
||||||
className={buttonVariants({ variant: "default" })}
|
|
||||||
href={`/build?flowID=${execution.graph_id}&flowVersion=${execution.graph_version}&flowExecutionID=${execution.id}`}
|
|
||||||
>
|
|
||||||
<Pencil2Icon className="mr-2" /> Open in Builder
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<p className="hidden">
|
|
||||||
<strong>Agent ID:</strong> <code>{agent.graph_id}</code>
|
|
||||||
</p>
|
|
||||||
<p className="hidden">
|
|
||||||
<strong>Run ID:</strong> <code>{execution.id}</code>
|
|
||||||
</p>
|
|
||||||
<div>
|
|
||||||
<strong>Status:</strong>{" "}
|
|
||||||
<FlowRunStatusBadge status={execution.status} />
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
<strong>Started:</strong>{" "}
|
|
||||||
{moment(execution.started_at).format("YYYY-MM-DD HH:mm:ss")}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>Finished:</strong>{" "}
|
|
||||||
{moment(execution.ended_at).format("YYYY-MM-DD HH:mm:ss")}
|
|
||||||
</p>
|
|
||||||
{execution.stats && (
|
|
||||||
<p>
|
|
||||||
<strong>Duration (run time):</strong>{" "}
|
|
||||||
{execution.stats.duration.toFixed(1)} (
|
|
||||||
{execution.stats.node_exec_time.toFixed(1)}) seconds
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
<RunnerOutputUI
|
|
||||||
isOpen={isOutputOpen}
|
|
||||||
doClose={() => setIsOutputOpen(false)}
|
|
||||||
outputs={blockOutputs}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FlowRunInfo;
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { Badge } from "@/components/ui/badge";
|
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { GraphExecutionMeta } from "@/lib/autogpt-server-api";
|
|
||||||
|
|
||||||
export const FlowRunStatusBadge: React.FC<{
|
|
||||||
status: GraphExecutionMeta["status"];
|
|
||||||
className?: string;
|
|
||||||
}> = ({ status, className }) => (
|
|
||||||
<Badge
|
|
||||||
variant="default"
|
|
||||||
className={cn(
|
|
||||||
status === "RUNNING"
|
|
||||||
? "bg-blue-500 dark:bg-blue-700"
|
|
||||||
: status === "QUEUED"
|
|
||||||
? "bg-yellow-500 dark:bg-yellow-600"
|
|
||||||
: status === "COMPLETED"
|
|
||||||
? "bg-green-500 dark:bg-green-600"
|
|
||||||
: "bg-red-500 dark:bg-red-700",
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{status}
|
|
||||||
</Badge>
|
|
||||||
);
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { GraphExecutionMeta, LibraryAgent } from "@/lib/autogpt-server-api";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
||||||
import {
|
|
||||||
Table,
|
|
||||||
TableBody,
|
|
||||||
TableCell,
|
|
||||||
TableHead,
|
|
||||||
TableHeader,
|
|
||||||
TableRow,
|
|
||||||
} from "@/components/ui/table";
|
|
||||||
import moment from "moment/moment";
|
|
||||||
import { FlowRunStatusBadge } from "@/components/monitor/FlowRunStatusBadge";
|
|
||||||
import { TextRenderer } from "../ui/render";
|
|
||||||
|
|
||||||
export const FlowRunsList: React.FC<{
|
|
||||||
flows: LibraryAgent[];
|
|
||||||
executions: GraphExecutionMeta[];
|
|
||||||
className?: string;
|
|
||||||
selectedRun?: GraphExecutionMeta | null;
|
|
||||||
onSelectRun: (r: GraphExecutionMeta) => void;
|
|
||||||
}> = ({ flows, executions, selectedRun, onSelectRun, className }) => (
|
|
||||||
<Card className={className}>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>Runs</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<Table>
|
|
||||||
<TableHeader>
|
|
||||||
<TableRow>
|
|
||||||
<TableHead>Agent</TableHead>
|
|
||||||
<TableHead>Started</TableHead>
|
|
||||||
<TableHead>Status</TableHead>
|
|
||||||
<TableHead>Duration</TableHead>
|
|
||||||
</TableRow>
|
|
||||||
</TableHeader>
|
|
||||||
<TableBody data-testid="flow-runs-list-body">
|
|
||||||
{executions.map((execution) => (
|
|
||||||
<TableRow
|
|
||||||
key={execution.id}
|
|
||||||
data-testid={`flow-run-${execution.id}-graph-${execution.graph_id}`}
|
|
||||||
data-runid={execution.id}
|
|
||||||
data-graphid={execution.graph_id}
|
|
||||||
className="cursor-pointer"
|
|
||||||
onClick={() => onSelectRun(execution)}
|
|
||||||
data-state={selectedRun?.id == execution.id ? "selected" : null}
|
|
||||||
>
|
|
||||||
<TableCell>
|
|
||||||
<TextRenderer
|
|
||||||
value={
|
|
||||||
flows.find((f) => f.graph_id == execution.graph_id)?.name
|
|
||||||
}
|
|
||||||
truncateLengthLimit={30}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
{moment(execution.started_at).format("HH:mm")}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
<FlowRunStatusBadge
|
|
||||||
status={execution.status}
|
|
||||||
className="w-full justify-center"
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>
|
|
||||||
{execution.stats
|
|
||||||
? formatDuration(execution.stats.duration)
|
|
||||||
: ""}
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
|
|
||||||
function formatDuration(seconds: number): string {
|
|
||||||
return (
|
|
||||||
(seconds < 100 ? seconds.toPrecision(2) : Math.round(seconds)).toString() +
|
|
||||||
"s"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FlowRunsList;
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
import React, { useState } from "react";
|
|
||||||
import { GraphExecutionMeta, LibraryAgent } from "@/lib/autogpt-server-api";
|
|
||||||
import { CardTitle } from "@/components/ui/card";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import {
|
|
||||||
Popover,
|
|
||||||
PopoverContent,
|
|
||||||
PopoverTrigger,
|
|
||||||
} from "@/components/ui/popover";
|
|
||||||
import { Calendar } from "@/components/ui/calendar";
|
|
||||||
import { FlowRunsTimeline } from "@/components/monitor/FlowRunsTimeline";
|
|
||||||
|
|
||||||
export const FlowRunsStatus: React.FC<{
|
|
||||||
flows: LibraryAgent[];
|
|
||||||
executions: GraphExecutionMeta[];
|
|
||||||
title?: string;
|
|
||||||
className?: string;
|
|
||||||
}> = ({ flows, executions: executions, title, className }) => {
|
|
||||||
/* "dateMin": since the first flow in the dataset
|
|
||||||
* number > 0: custom date (unix timestamp)
|
|
||||||
* number < 0: offset relative to Date.now() (in seconds) */
|
|
||||||
const [selected, setSelected] = useState<Date>();
|
|
||||||
const [statsSince, setStatsSince] = useState<number | "dataMin">(-24 * 3600);
|
|
||||||
const statsSinceTimestamp = // unix timestamp or null
|
|
||||||
typeof statsSince == "string"
|
|
||||||
? null
|
|
||||||
: statsSince < 0
|
|
||||||
? Date.now() + statsSince * 1000
|
|
||||||
: statsSince;
|
|
||||||
const filteredFlowRuns =
|
|
||||||
statsSinceTimestamp != null
|
|
||||||
? executions.filter((fr) => fr.started_at.getTime() > statsSinceTimestamp)
|
|
||||||
: executions;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={className}>
|
|
||||||
<div className="flex flex-row items-center justify-between">
|
|
||||||
<CardTitle>{title || "Stats"}</CardTitle>
|
|
||||||
<div className="flex flex-wrap space-x-2">
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setStatsSince(-2 * 3600)}
|
|
||||||
>
|
|
||||||
2h
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setStatsSince(-8 * 3600)}
|
|
||||||
>
|
|
||||||
8h
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setStatsSince(-24 * 3600)}
|
|
||||||
>
|
|
||||||
24h
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setStatsSince(-7 * 24 * 3600)}
|
|
||||||
>
|
|
||||||
7d
|
|
||||||
</Button>
|
|
||||||
<Popover>
|
|
||||||
<PopoverTrigger asChild>
|
|
||||||
<Button variant={"outline"} size="sm">
|
|
||||||
Custom
|
|
||||||
</Button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent className="w-auto p-0" align="start">
|
|
||||||
<Calendar
|
|
||||||
mode="single"
|
|
||||||
selected={selected}
|
|
||||||
onSelect={(_, selectedDay) => {
|
|
||||||
setSelected(selectedDay);
|
|
||||||
setStatsSince(selectedDay.getTime());
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => setStatsSince("dataMin")}
|
|
||||||
>
|
|
||||||
All
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<FlowRunsTimeline
|
|
||||||
flows={flows}
|
|
||||||
executions={executions}
|
|
||||||
dataMin={statsSince}
|
|
||||||
className="mt-3"
|
|
||||||
/>
|
|
||||||
<hr className="my-4" />
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<strong>Total runs:</strong> {filteredFlowRuns.length}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>Total run time:</strong>{" "}
|
|
||||||
{filteredFlowRuns.reduce(
|
|
||||||
(total, run) => total + (run.stats?.node_exec_time ?? 0),
|
|
||||||
0,
|
|
||||||
)}{" "}
|
|
||||||
seconds
|
|
||||||
</p>
|
|
||||||
{filteredFlowRuns.some((r) => r.stats) && (
|
|
||||||
<p>
|
|
||||||
<strong>Total cost:</strong>{" "}
|
|
||||||
{filteredFlowRuns.reduce(
|
|
||||||
(total, run) => total + (run.stats?.cost ?? 0),
|
|
||||||
0,
|
|
||||||
)}{" "}
|
|
||||||
seconds
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default FlowRunsStatus;
|
|
||||||
@@ -1,184 +0,0 @@
|
|||||||
import { GraphExecutionMeta, LibraryAgent } from "@/lib/autogpt-server-api";
|
|
||||||
import {
|
|
||||||
ComposedChart,
|
|
||||||
DefaultLegendContentProps,
|
|
||||||
Legend,
|
|
||||||
Line,
|
|
||||||
ResponsiveContainer,
|
|
||||||
Scatter,
|
|
||||||
Tooltip,
|
|
||||||
XAxis,
|
|
||||||
YAxis,
|
|
||||||
} from "recharts";
|
|
||||||
import moment from "moment/moment";
|
|
||||||
import { Card } from "@/components/ui/card";
|
|
||||||
import { cn, hashString } from "@/lib/utils";
|
|
||||||
import React from "react";
|
|
||||||
import { FlowRunStatusBadge } from "@/components/monitor/FlowRunStatusBadge";
|
|
||||||
|
|
||||||
export const FlowRunsTimeline = ({
|
|
||||||
flows,
|
|
||||||
executions,
|
|
||||||
dataMin,
|
|
||||||
className,
|
|
||||||
}: {
|
|
||||||
flows: LibraryAgent[];
|
|
||||||
executions: GraphExecutionMeta[];
|
|
||||||
dataMin: "dataMin" | number;
|
|
||||||
className?: string;
|
|
||||||
}) => (
|
|
||||||
/* TODO: make logarithmic? */
|
|
||||||
<ResponsiveContainer width="100%" height={120} className={className}>
|
|
||||||
<ComposedChart>
|
|
||||||
<XAxis
|
|
||||||
dataKey="time"
|
|
||||||
type="number"
|
|
||||||
domain={[
|
|
||||||
typeof dataMin == "string"
|
|
||||||
? dataMin
|
|
||||||
: dataMin < 0
|
|
||||||
? Date.now() + dataMin * 1000
|
|
||||||
: dataMin,
|
|
||||||
Date.now(),
|
|
||||||
]}
|
|
||||||
allowDataOverflow={true}
|
|
||||||
tickFormatter={(unixTime) => {
|
|
||||||
const now = moment();
|
|
||||||
const time = moment(unixTime);
|
|
||||||
return now.diff(time, "hours") < 24
|
|
||||||
? time.format("HH:mm")
|
|
||||||
: time.format("YYYY-MM-DD HH:mm");
|
|
||||||
}}
|
|
||||||
name="Time"
|
|
||||||
scale="time"
|
|
||||||
/>
|
|
||||||
<YAxis
|
|
||||||
dataKey="_duration"
|
|
||||||
name="Duration (s)"
|
|
||||||
tickFormatter={(s) => (s > 90 ? `${Math.round(s / 60)}m` : `${s}s`)}
|
|
||||||
/>
|
|
||||||
<Tooltip
|
|
||||||
content={({ payload }) => {
|
|
||||||
if (payload && payload.length) {
|
|
||||||
const data: GraphExecutionMeta & {
|
|
||||||
time: number;
|
|
||||||
_duration: number;
|
|
||||||
} = payload[0].payload;
|
|
||||||
const flow = flows.find((f) => f.graph_id === data.graph_id);
|
|
||||||
return (
|
|
||||||
<Card className="p-2 text-xs leading-normal">
|
|
||||||
<p>
|
|
||||||
<strong>Agent:</strong> {flow ? flow.name : "Unknown"}
|
|
||||||
</p>
|
|
||||||
<div>
|
|
||||||
<strong>Status:</strong>
|
|
||||||
<FlowRunStatusBadge
|
|
||||||
status={data.status}
|
|
||||||
className="px-1.5 py-0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
<strong>Started:</strong>{" "}
|
|
||||||
{moment(data.started_at).format("YYYY-MM-DD HH:mm:ss")}
|
|
||||||
</p>
|
|
||||||
{data.stats && (
|
|
||||||
<p>
|
|
||||||
<strong>Duration / run time:</strong>{" "}
|
|
||||||
{formatDuration(data.stats.duration)} /{" "}
|
|
||||||
{formatDuration(data.stats.node_exec_time)}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{flows.map((flow) => (
|
|
||||||
<Scatter
|
|
||||||
key={flow.id}
|
|
||||||
data={executions
|
|
||||||
.filter((e) => e.graph_id == flow.graph_id)
|
|
||||||
.map((e) => ({
|
|
||||||
...e,
|
|
||||||
time:
|
|
||||||
e.started_at.getTime() + (e.stats?.node_exec_time ?? 0) * 1000,
|
|
||||||
_duration: e.stats?.node_exec_time ?? 0,
|
|
||||||
}))}
|
|
||||||
name={flow.name}
|
|
||||||
fill={`hsl(${(hashString(flow.id) * 137.5) % 360}, 70%, 50%)`}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
{executions.map((execution) => (
|
|
||||||
<Line
|
|
||||||
key={execution.id}
|
|
||||||
type="linear"
|
|
||||||
dataKey="_duration"
|
|
||||||
data={[
|
|
||||||
{
|
|
||||||
...execution,
|
|
||||||
time: execution.started_at.getTime(),
|
|
||||||
_duration: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
...execution,
|
|
||||||
time: execution.ended_at.getTime(),
|
|
||||||
_duration: execution.stats?.node_exec_time ?? 0,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
stroke={`hsl(${(hashString(execution.graph_id) * 137.5) % 360}, 70%, 50%)`}
|
|
||||||
strokeWidth={2}
|
|
||||||
dot={false}
|
|
||||||
legendType="none"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
<Legend
|
|
||||||
content={<ScrollableLegend />}
|
|
||||||
wrapperStyle={{
|
|
||||||
bottom: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
width: "100%",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</ComposedChart>
|
|
||||||
</ResponsiveContainer>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default FlowRunsTimeline;
|
|
||||||
|
|
||||||
const ScrollableLegend: React.FC<
|
|
||||||
DefaultLegendContentProps & { className?: string }
|
|
||||||
> = ({ payload, className }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"space-x-3 overflow-x-auto whitespace-nowrap px-4 text-sm",
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
style={{ scrollbarWidth: "none" }}
|
|
||||||
>
|
|
||||||
{payload?.map((entry, index) => {
|
|
||||||
if (entry.type == "none") return;
|
|
||||||
return (
|
|
||||||
<span key={`item-${index}`} className="inline-flex items-center">
|
|
||||||
<span
|
|
||||||
className="mr-1 inline-block size-2.5 rounded-full"
|
|
||||||
style={{ backgroundColor: entry.color }}
|
|
||||||
/>
|
|
||||||
<span>{entry.value}</span>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function formatDuration(seconds: number): string {
|
|
||||||
return (
|
|
||||||
(seconds < 100 ? seconds.toPrecision(2) : Math.round(seconds)).toString() +
|
|
||||||
"s"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
export { default as AgentFlowList } from "./AgentFlowList";
|
|
||||||
export { default as FlowRunsList } from "./FlowRunsList";
|
|
||||||
export { default as FlowInfo } from "./FlowInfo";
|
|
||||||
export { default as FlowRunInfo } from "./FlowRunInfo";
|
|
||||||
export { default as FlowRunsStats } from "./FlowRunsStatus";
|
|
||||||
export { default as FlowRunsTimeline } from "./FlowRunsTimeline";
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
export default function AgentsFlowListSkeleton() {
|
|
||||||
return (
|
|
||||||
<div className="mx-auto max-w-4xl p-4">
|
|
||||||
<div className="mb-4 flex items-center justify-between">
|
|
||||||
<h1 className="text-2xl font-bold">Agents</h1>
|
|
||||||
<div className="h-10 w-24 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
</div>
|
|
||||||
<div className="rounded-lg bg-white p-4 shadow">
|
|
||||||
<div className="mb-4 grid grid-cols-3 gap-4 font-medium text-gray-500">
|
|
||||||
<div>Name</div>
|
|
||||||
<div># of runs</div>
|
|
||||||
<div>Last run</div>
|
|
||||||
</div>
|
|
||||||
{[...Array(3)].map((_, index) => (
|
|
||||||
<div key={index} className="mb-4 grid grid-cols-3 gap-4">
|
|
||||||
<div className="h-6 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
<div className="h-6 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
<div className="h-6 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
export default function FlowRunsListSkeleton() {
|
|
||||||
return (
|
|
||||||
<div className="mx-auto max-w-4xl p-4">
|
|
||||||
<div className="rounded-lg bg-white p-4 shadow">
|
|
||||||
<h2 className="mb-4 text-xl font-semibold">Runs</h2>
|
|
||||||
<div className="mb-4 grid grid-cols-4 gap-4 text-sm font-medium text-gray-500">
|
|
||||||
<div>Agent</div>
|
|
||||||
<div>Started</div>
|
|
||||||
<div>Status</div>
|
|
||||||
<div>Duration</div>
|
|
||||||
</div>
|
|
||||||
{[...Array(4)].map((_, index) => (
|
|
||||||
<div key={index} className="mb-4 grid grid-cols-4 gap-4">
|
|
||||||
<div className="h-5 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
<div className="h-5 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
<div className="h-5 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
<div className="h-5 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
export default function FlowRunsStatusSkeleton() {
|
|
||||||
return (
|
|
||||||
<div className="mx-auto max-w-4xl p-4">
|
|
||||||
<div className="rounded-lg bg-white p-4 shadow">
|
|
||||||
<div className="mb-6 flex items-center justify-between">
|
|
||||||
<h2 className="text-xl font-semibold">Stats</h2>
|
|
||||||
<div className="flex space-x-2">
|
|
||||||
{["2h", "8h", "24h", "7d", "Custom", "All"].map((btn) => (
|
|
||||||
<div
|
|
||||||
key={btn}
|
|
||||||
className="h-8 w-16 animate-pulse rounded bg-gray-200"
|
|
||||||
></div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Placeholder for the line chart */}
|
|
||||||
<div className="mb-6 h-64 w-full animate-pulse rounded bg-gray-200"></div>
|
|
||||||
|
|
||||||
{/* Placeholders for total runs and total run time */}
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div className="h-6 w-1/3 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
<div className="h-6 w-1/2 animate-pulse rounded bg-gray-200"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
const getYouTubeVideoId = (url: string) => {
|
const getYouTubeVideoId = (url: string) => {
|
||||||
const regExp =
|
const regExp =
|
||||||
@@ -75,12 +76,13 @@ const ImageRenderer: React.FC<{ imageUrl: string }> = ({ imageUrl }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="w-full p-2">
|
<div className="w-full p-2">
|
||||||
<picture>
|
<picture>
|
||||||
<img
|
<Image
|
||||||
src={imageUrl}
|
src={imageUrl}
|
||||||
alt="Image"
|
alt="Image"
|
||||||
className="h-auto max-w-full"
|
className="h-auto max-w-full"
|
||||||
width="100%"
|
width={800}
|
||||||
height="auto"
|
height={600}
|
||||||
|
style={{ width: "100%", height: "auto" }}
|
||||||
/>
|
/>
|
||||||
</picture>
|
</picture>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -909,9 +909,9 @@ export default function useAgentGraph(
|
|||||||
title: "Agent scheduling successful",
|
title: "Agent scheduling successful",
|
||||||
});
|
});
|
||||||
|
|
||||||
// if scheduling is done from the monitor page, then redirect to monitor page after successful scheduling
|
// if scheduling is done from another page, redirect to library
|
||||||
if (searchParams.get("open_scheduling") === "true") {
|
if (searchParams.get("open_scheduling") === "true") {
|
||||||
router.push("/monitoring");
|
router.push("/library");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error scheduling agent:", error);
|
console.error("Error scheduling agent:", error);
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import { useMemo, useCallback, useRef, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom hook for debouncing a value
|
||||||
|
*/
|
||||||
|
export function useDebounce<T>(value: T, delay: number): T {
|
||||||
|
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handler = setTimeout(() => {
|
||||||
|
setDebouncedValue(value);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearTimeout(handler);
|
||||||
|
};
|
||||||
|
}, [value, delay]);
|
||||||
|
|
||||||
|
return debouncedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom hook for throttling a callback
|
||||||
|
*/
|
||||||
|
export function useThrottle<T extends (...args: any[]) => any>(
|
||||||
|
callback: T,
|
||||||
|
delay: number,
|
||||||
|
): T {
|
||||||
|
const lastRan = useRef(Date.now());
|
||||||
|
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||||
|
|
||||||
|
return useCallback(
|
||||||
|
(...args: Parameters<T>) => {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (now - lastRan.current >= delay) {
|
||||||
|
lastRan.current = now;
|
||||||
|
callback(...args);
|
||||||
|
} else {
|
||||||
|
clearTimeout(timeoutRef.current);
|
||||||
|
timeoutRef.current = setTimeout(
|
||||||
|
() => {
|
||||||
|
lastRan.current = Date.now();
|
||||||
|
callback(...args);
|
||||||
|
},
|
||||||
|
delay - (now - lastRan.current),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[callback, delay],
|
||||||
|
) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom hook for intersection observer (lazy loading)
|
||||||
|
*/
|
||||||
|
export function useIntersectionObserver(
|
||||||
|
ref: React.RefObject<Element>,
|
||||||
|
options?: IntersectionObserverInit,
|
||||||
|
) {
|
||||||
|
const [isIntersecting, setIsIntersecting] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new IntersectionObserver(([entry]) => {
|
||||||
|
setIsIntersecting(entry.isIntersecting);
|
||||||
|
}, options);
|
||||||
|
|
||||||
|
if (ref.current) {
|
||||||
|
observer.observe(ref.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
|
}, [ref, options]);
|
||||||
|
|
||||||
|
return isIntersecting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom hook for virtual scrolling
|
||||||
|
*/
|
||||||
|
export function useVirtualScroll<T>(
|
||||||
|
items: T[],
|
||||||
|
itemHeight: number,
|
||||||
|
containerHeight: number,
|
||||||
|
overscan = 5,
|
||||||
|
) {
|
||||||
|
const [scrollTop, setScrollTop] = useState(0);
|
||||||
|
|
||||||
|
const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
|
||||||
|
const endIndex = Math.min(
|
||||||
|
items.length - 1,
|
||||||
|
Math.ceil((scrollTop + containerHeight) / itemHeight) + overscan,
|
||||||
|
);
|
||||||
|
|
||||||
|
const visibleItems = useMemo(
|
||||||
|
() => items.slice(startIndex, endIndex + 1),
|
||||||
|
[items, startIndex, endIndex],
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalHeight = items.length * itemHeight;
|
||||||
|
const offsetY = startIndex * itemHeight;
|
||||||
|
|
||||||
|
return {
|
||||||
|
visibleItems,
|
||||||
|
totalHeight,
|
||||||
|
offsetY,
|
||||||
|
onScroll: (e: React.UIEvent<HTMLDivElement>) => {
|
||||||
|
setScrollTop(e.currentTarget.scrollTop);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,17 +4,31 @@ function makeQueryClient() {
|
|||||||
return new QueryClient({
|
return new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
// Added this because if staleTime is 0 (default), the data fetched on the server becomes stale immediately on the client, and it refetches again.
|
// Increase stale time to 5 minutes for better caching
|
||||||
staleTime: 60 * 1000,
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||||
|
|
||||||
|
// Keep data in cache for 30 minutes (was 5 minutes default)
|
||||||
|
gcTime: 30 * 60 * 1000, // 30 minutes
|
||||||
|
|
||||||
|
// Reduce refetch frequency
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: "always",
|
||||||
|
|
||||||
|
// Retry configuration
|
||||||
|
retry: 2, // Reduce from 3 to 2 retries
|
||||||
|
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
|
||||||
|
|
||||||
// Highlighting some important defaults to avoid confusion
|
// Highlighting some important defaults to avoid confusion
|
||||||
// Queries are stale by default → triggers background refetch
|
// Queries are stale by default → triggers background refetch
|
||||||
// Refetch triggers: on mount, window focus, reconnect
|
// Failed queries retry with exponential backoff
|
||||||
// Failed queries retry 3 times with exponential backoff
|
|
||||||
// Inactive queries are GC'd after 5 mins (gcTime = 5 * 60 * 1000)
|
|
||||||
// Structural sharing is enabled for efficient data comparison
|
// Structural sharing is enabled for efficient data comparison
|
||||||
// For more info, visit https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults
|
// For more info, visit https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults
|
||||||
},
|
},
|
||||||
|
mutations: {
|
||||||
|
// Mutation defaults
|
||||||
|
retry: 1,
|
||||||
|
retryDelay: 1000,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,140 +0,0 @@
|
|||||||
import test, { expect, TestInfo } from "@playwright/test";
|
|
||||||
|
|
||||||
import { BuildPage } from "./pages/build.page";
|
|
||||||
import { MonitorPage } from "./pages/monitor.page";
|
|
||||||
import { v4 as uuidv4 } from "uuid";
|
|
||||||
import * as fs from "fs/promises";
|
|
||||||
import path from "path";
|
|
||||||
import { LoginPage } from "./pages/login.page";
|
|
||||||
import { getTestUser } from "./utils/auth";
|
|
||||||
import { hasUrl } from "./utils/assertion";
|
|
||||||
import {
|
|
||||||
navigateToLibrary,
|
|
||||||
clickFirstAgent,
|
|
||||||
runAgent,
|
|
||||||
waitForAgentPageLoad,
|
|
||||||
} from "./pages/library.page";
|
|
||||||
|
|
||||||
test.describe.configure({
|
|
||||||
mode: "parallel",
|
|
||||||
timeout: 30000,
|
|
||||||
});
|
|
||||||
// --8<-- [start:AttachAgentId]
|
|
||||||
test.beforeEach(async ({ page }, testInfo: TestInfo) => {
|
|
||||||
const loginPage = new LoginPage(page);
|
|
||||||
const testUser = await getTestUser();
|
|
||||||
const monitorPage = new MonitorPage(page);
|
|
||||||
|
|
||||||
// Start each test with login using worker auth
|
|
||||||
await page.goto("/login");
|
|
||||||
await loginPage.login(testUser.email, testUser.password);
|
|
||||||
await hasUrl(page, "/marketplace");
|
|
||||||
|
|
||||||
// Navigate to library and run the first agent
|
|
||||||
await navigateToLibrary(page);
|
|
||||||
await clickFirstAgent(page);
|
|
||||||
await waitForAgentPageLoad(page);
|
|
||||||
await runAgent(page);
|
|
||||||
|
|
||||||
// Navigate to monitoring page
|
|
||||||
await page.goto("/monitoring");
|
|
||||||
await test.expect(monitorPage.isLoaded()).resolves.toBeTruthy();
|
|
||||||
|
|
||||||
// Generate a test ID for tracking
|
|
||||||
const id = uuidv4();
|
|
||||||
testInfo.attach("agent-id", { body: id });
|
|
||||||
});
|
|
||||||
// --8<-- [end:AttachAgentId]
|
|
||||||
|
|
||||||
test.afterAll(async () => {
|
|
||||||
// clear out the downloads folder
|
|
||||||
const downloadsFolder = process.cwd() + "/downloads";
|
|
||||||
console.log(`clearing out the downloads folder ${downloadsFolder}/monitor`);
|
|
||||||
|
|
||||||
await fs.rm(`${downloadsFolder}/monitor`, {
|
|
||||||
recursive: true,
|
|
||||||
force: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test.skip("user can export and import agents", async ({
|
|
||||||
page,
|
|
||||||
}, testInfo: TestInfo) => {
|
|
||||||
const monitorPage = new MonitorPage(page);
|
|
||||||
const buildPage = new BuildPage(page);
|
|
||||||
|
|
||||||
// --8<-- [start:ReadAgentId]
|
|
||||||
if (testInfo.attachments.length === 0 || !testInfo.attachments[0].body) {
|
|
||||||
throw new Error("No agent id attached to the test");
|
|
||||||
}
|
|
||||||
|
|
||||||
const testAttachName = testInfo.attachments[0].body.toString();
|
|
||||||
// --8<-- [end:ReadAgentId]
|
|
||||||
const agents = await monitorPage.listAgents();
|
|
||||||
|
|
||||||
const downloadPromise = page.waitForEvent("download");
|
|
||||||
|
|
||||||
const agent = agents.find(
|
|
||||||
(a: any) => a.name === `test-agent-${testAttachName}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!agent) throw new Error(`Agent ${testAttachName} not found`);
|
|
||||||
|
|
||||||
await monitorPage.exportToFile(agent);
|
|
||||||
const download = await downloadPromise;
|
|
||||||
|
|
||||||
// Wait for the download process to complete and save the downloaded file somewhere.
|
|
||||||
await download.saveAs(
|
|
||||||
`${monitorPage.downloadsFolder}/monitor/${download.suggestedFilename()}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(`downloaded file to ${download.suggestedFilename()}`);
|
|
||||||
|
|
||||||
expect(download.suggestedFilename()).toBeDefined();
|
|
||||||
expect(download.suggestedFilename()).toContain("test-agent-");
|
|
||||||
expect(download.suggestedFilename()).toContain("v1.json");
|
|
||||||
|
|
||||||
// import the agent
|
|
||||||
const preImportAgents = await monitorPage.listAgents();
|
|
||||||
|
|
||||||
const filesInFolder = await fs.readdir(
|
|
||||||
`${monitorPage.downloadsFolder}/monitor`,
|
|
||||||
);
|
|
||||||
|
|
||||||
const importFile = filesInFolder.find((f) => f.includes(testAttachName));
|
|
||||||
if (!importFile) {
|
|
||||||
throw new Error(`No import file found for agent ${testAttachName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseName = importFile.split(".")[0];
|
|
||||||
|
|
||||||
await monitorPage.importFromFile(
|
|
||||||
path.resolve(monitorPage.downloadsFolder, "monitor"),
|
|
||||||
importFile,
|
|
||||||
baseName + "-imported",
|
|
||||||
);
|
|
||||||
|
|
||||||
// You'll be dropped at the build page, so hit run and then go back to monitor
|
|
||||||
await buildPage.runAgent();
|
|
||||||
await monitorPage.navbar.clickMonitorLink();
|
|
||||||
|
|
||||||
const postImportAgents = await monitorPage.listAgents();
|
|
||||||
|
|
||||||
expect(postImportAgents.length).toBeGreaterThan(preImportAgents.length);
|
|
||||||
|
|
||||||
console.log(`postImportAgents: ${JSON.stringify(postImportAgents)}`);
|
|
||||||
|
|
||||||
const importedAgent = postImportAgents.find(
|
|
||||||
(a: any) => a.name === `${baseName}-imported`,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(importedAgent).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
test.skip("user can view runs and agents", async ({ page }) => {
|
|
||||||
const monitorPage = new MonitorPage(page);
|
|
||||||
// const runs = await monitorPage.listRuns();
|
|
||||||
const agents = await monitorPage.listAgents();
|
|
||||||
|
|
||||||
expect(agents.length).toBeGreaterThan(0);
|
|
||||||
});
|
|
||||||
@@ -238,21 +238,6 @@ export class LibraryPage extends BasePage {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickMonitoringLink(): Promise<void> {
|
|
||||||
console.log(`clicking monitoring link in alert`);
|
|
||||||
await this.page.getByRole("link", { name: "here" }).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async isMonitoringAlertVisible(): Promise<boolean> {
|
|
||||||
console.log(`checking if monitoring alert is visible`);
|
|
||||||
try {
|
|
||||||
const alertText = this.page.locator("text=/Prefer the old experience/");
|
|
||||||
return await alertText.isVisible();
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSearchValue(): Promise<string> {
|
async getSearchValue(): Promise<string> {
|
||||||
console.log(`getting search input value`);
|
console.log(`getting search input value`);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
import { Page } from "@playwright/test";
|
|
||||||
import { BasePage } from "./base.page";
|
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
interface Agent {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
runCount: number;
|
|
||||||
lastRun: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Run {
|
|
||||||
id: string;
|
|
||||||
agentId: string;
|
|
||||||
agentName: string;
|
|
||||||
started: string;
|
|
||||||
duration: number;
|
|
||||||
status: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Schedule {
|
|
||||||
id: string;
|
|
||||||
graphName: string;
|
|
||||||
nextExecution: string;
|
|
||||||
schedule: string;
|
|
||||||
actions: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ImportType {
|
|
||||||
AGENT = "agent",
|
|
||||||
TEMPLATE = "template",
|
|
||||||
}
|
|
||||||
|
|
||||||
export class MonitorPage extends BasePage {
|
|
||||||
constructor(page: Page) {
|
|
||||||
super(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
async isLoaded(): Promise<boolean> {
|
|
||||||
console.log(`checking if monitor page is loaded`);
|
|
||||||
try {
|
|
||||||
// Wait for the monitor page
|
|
||||||
await this.page.getByTestId("monitor-page").waitFor({
|
|
||||||
state: "visible",
|
|
||||||
timeout: 10_000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait for table headers to be visible (indicates table structure is ready)
|
|
||||||
await this.page.locator("thead th").first().waitFor({
|
|
||||||
state: "visible",
|
|
||||||
timeout: 15_000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait for either a table row or an empty tbody to be present
|
|
||||||
await Promise.race([
|
|
||||||
// Wait for at least one row
|
|
||||||
this.page.locator("tbody tr[data-testid]").first().waitFor({
|
|
||||||
state: "visible",
|
|
||||||
timeout: 15_000,
|
|
||||||
}),
|
|
||||||
// OR wait for an empty tbody (indicating no agents but table is loaded)
|
|
||||||
this.page
|
|
||||||
.locator("tbody[data-testid='agent-flow-list-body']:empty")
|
|
||||||
.waitFor({
|
|
||||||
state: "visible",
|
|
||||||
timeout: 15_000,
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async listAgents(): Promise<Agent[]> {
|
|
||||||
console.log(`listing agents`);
|
|
||||||
// Wait for table rows to be available
|
|
||||||
const rows = await this.page.locator("tbody tr[data-testid]").all();
|
|
||||||
|
|
||||||
const agents: Agent[] = [];
|
|
||||||
|
|
||||||
for (const row of rows) {
|
|
||||||
// Get the id from data-testid attribute
|
|
||||||
const id = (await row.getAttribute("data-testid")) || "";
|
|
||||||
|
|
||||||
// Get columns - there are 3 cells per row (name, run count, last run)
|
|
||||||
const cells = await row.locator("td").all();
|
|
||||||
|
|
||||||
// Extract name from first cell
|
|
||||||
const name = (await row.getAttribute("data-name")) || "";
|
|
||||||
|
|
||||||
// Extract run count from second cell
|
|
||||||
const runCountText = (await cells[1].textContent()) || "0";
|
|
||||||
const runCount = parseInt(runCountText, 10);
|
|
||||||
|
|
||||||
// Extract last run from third cell's title attribute (contains full timestamp)
|
|
||||||
// If no title, the cell will be empty indicating no last run
|
|
||||||
const lastRunCell = cells[2];
|
|
||||||
const lastRun = (await lastRunCell.getAttribute("title")) || "";
|
|
||||||
|
|
||||||
agents.push({
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
runCount,
|
|
||||||
lastRun,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
agents.reduce((acc, agent) => {
|
|
||||||
if (!agent.id.includes("flow-run")) {
|
|
||||||
acc.push(agent);
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, [] as Agent[]);
|
|
||||||
|
|
||||||
return agents;
|
|
||||||
}
|
|
||||||
|
|
||||||
async listRuns(filter?: Agent): Promise<Run[]> {
|
|
||||||
console.log(`listing runs`);
|
|
||||||
// Wait for the runs table to be loaded - look for table header "Agent"
|
|
||||||
await this.page.locator("[data-testid='flow-runs-list-body']").waitFor({
|
|
||||||
timeout: 10000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get all run rows
|
|
||||||
const rows = await this.page
|
|
||||||
.locator('tbody tr[data-testid^="flow-run-"]')
|
|
||||||
.all();
|
|
||||||
|
|
||||||
const runs: Run[] = [];
|
|
||||||
|
|
||||||
for (const row of rows) {
|
|
||||||
const runId = (await row.getAttribute("data-runid")) || "";
|
|
||||||
const agentId = (await row.getAttribute("data-graphid")) || "";
|
|
||||||
|
|
||||||
// Get columns
|
|
||||||
const cells = await row.locator("td").all();
|
|
||||||
|
|
||||||
// Parse data from cells
|
|
||||||
const agentName = (await cells[0].textContent()) || "";
|
|
||||||
const started = (await cells[1].textContent()) || "";
|
|
||||||
const status = (await cells[2].locator("div").textContent()) || "";
|
|
||||||
const duration = (await cells[3].textContent()) || "";
|
|
||||||
|
|
||||||
// Only add if no filter or if matches filter
|
|
||||||
if (!filter || filter.id === agentId) {
|
|
||||||
runs.push({
|
|
||||||
id: runId,
|
|
||||||
agentId: agentId,
|
|
||||||
agentName: agentName.trim(),
|
|
||||||
started: started.trim(),
|
|
||||||
duration: parseFloat(duration.replace("s", "")),
|
|
||||||
status: status.toLowerCase().trim(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return runs;
|
|
||||||
}
|
|
||||||
async listSchedules(): Promise<Schedule[]> {
|
|
||||||
console.log(`listing schedules`);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
async clickAgent(id: string) {
|
|
||||||
console.log(`selecting agent ${id}`);
|
|
||||||
await this.page.getByTestId(id).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async clickCreateAgent(): Promise<void> {
|
|
||||||
console.log(`clicking create agent`);
|
|
||||||
await this.page.getByRole("link", { name: "Create" }).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async importFromFile(
|
|
||||||
directory: string,
|
|
||||||
file: string,
|
|
||||||
name?: string,
|
|
||||||
description?: string,
|
|
||||||
importType: ImportType = ImportType.AGENT,
|
|
||||||
) {
|
|
||||||
console.log(
|
|
||||||
`importing from directory: ${directory} file: ${file} name: ${name} description: ${description} importType: ${importType}`,
|
|
||||||
);
|
|
||||||
await this.page.getByTestId("create-agent-dropdown").click();
|
|
||||||
await this.page.getByTestId("import-agent-from-file").click();
|
|
||||||
|
|
||||||
await this.page
|
|
||||||
.getByTestId("import-agent-file-input")
|
|
||||||
.setInputFiles(path.join(directory, file));
|
|
||||||
if (name) {
|
|
||||||
console.log(`filling agent name: ${name}`);
|
|
||||||
await this.page.getByTestId("agent-name-input").fill(name);
|
|
||||||
}
|
|
||||||
if (description) {
|
|
||||||
console.log(`filling agent description: ${description}`);
|
|
||||||
await this.page.getByTestId("agent-description-input").fill(description);
|
|
||||||
}
|
|
||||||
if (importType === ImportType.TEMPLATE) {
|
|
||||||
console.log(`clicking import as template switch`);
|
|
||||||
await this.page.getByTestId("import-as-template-switch").click();
|
|
||||||
}
|
|
||||||
console.log(`clicking import agent submit`);
|
|
||||||
await this.page.getByTestId("import-agent-submit").click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteAgent(agent: Agent) {
|
|
||||||
console.log(`deleting agent ${agent.id} ${agent.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async clickAllVersions(agent: Agent) {
|
|
||||||
console.log(`clicking all versions for agent ${agent.id} ${agent.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async openInBuilder(agent: Agent) {
|
|
||||||
console.log(`opening agent ${agent.id} ${agent.name} in builder`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async exportToFile(agent: Agent) {
|
|
||||||
await this.clickAgent(agent.id);
|
|
||||||
|
|
||||||
console.log(`exporting agent id: ${agent.id} name: ${agent.name} to file`);
|
|
||||||
await this.page.getByTestId("export-button").click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async selectRun(agent: Agent, run: Run) {
|
|
||||||
console.log(`selecting run ${run.id} for agent ${agent.id} ${agent.name}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async openOutputs(agent: Agent, run: Run) {
|
|
||||||
console.log(
|
|
||||||
`opening outputs for run ${run.id} of agent ${agent.id} ${agent.name}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,10 +8,6 @@ export class NavBar {
|
|||||||
await this.page.getByRole("link", { name: "Edit profile" }).click();
|
await this.page.getByRole("link", { name: "Edit profile" }).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickMonitorLink() {
|
|
||||||
await this.page.getByTestId("navbar-link-library").click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async clickBuildLink() {
|
async clickBuildLink() {
|
||||||
const link = this.page.getByTestId("navbar-link-build");
|
const link = this.page.getByTestId("navbar-link-build");
|
||||||
await link.waitFor({ state: "visible", timeout: 15000 });
|
await link.waitFor({ state: "visible", timeout: 15000 });
|
||||||
|
|||||||
Reference in New Issue
Block a user