diff --git a/package.json b/package.json index c1b6c96..de5928e 100644 --- a/package.json +++ b/package.json @@ -357,35 +357,35 @@ "@hookform/resolvers": "^3.9.0", "@ianvs/prettier-plugin-sort-imports": "^4.3.1", "@langchain/anthropic": "^0.3.3", - "@langchain/community": "^0.3.3", - "@langchain/core": "0.3.3", - "@langchain/langgraph": "^0.2.9", - "@langchain/openai": "^0.3.2", + "@langchain/community": "^0.3.5", + "@langchain/core": "0.3.10", + "@langchain/langgraph": "^0.2.14", + "@langchain/openai": "^0.3.7", "@langchain/textsplitters": "^0.1.0", "@lexical/react": "^0.18.0", - "@radix-ui/react-accordion": "^1.2.0", - "@radix-ui/react-alert-dialog": "^1.1.1", - "@radix-ui/react-checkbox": "^1.1.1", - "@radix-ui/react-context-menu": "^2.2.1", - "@radix-ui/react-dialog": "^1.1.1", - "@radix-ui/react-dropdown-menu": "^2.1.1", - "@radix-ui/react-hover-card": "^1.1.1", + "@radix-ui/react-accordion": "^1.2.1", + "@radix-ui/react-alert-dialog": "^1.1.2", + "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-context-menu": "^2.2.2", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-hover-card": "^1.1.2", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-menubar": "^1.1.1", - "@radix-ui/react-popover": "^1.1.1", + "@radix-ui/react-menubar": "^1.1.2", + "@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-progress": "^1.1.0", - "@radix-ui/react-radio-group": "^1.2.0", - "@radix-ui/react-scroll-area": "^1.1.0", - "@radix-ui/react-select": "^2.1.1", - "@radix-ui/react-slider": "^1.2.0", + "@radix-ui/react-radio-group": "^1.2.1", + "@radix-ui/react-scroll-area": "^1.2.0", + "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-slider": "^1.2.1", "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-switch": "^1.1.0", - "@radix-ui/react-tabs": "^1.1.0", - "@radix-ui/react-tooltip": "^1.1.2", + "@radix-ui/react-switch": "^1.1.1", + "@radix-ui/react-tabs": "^1.1.1", + "@radix-ui/react-tooltip": "^1.1.3", "@radix-ui/react-visually-hidden": "^1.1.0", - "@tanstack/react-query": "^5.56.2", - "@tomjs/vite-plugin-vscode": "^2.6.0", + "@tanstack/react-query": "^5.59.11", + "@tomjs/vite-plugin-vscode": "^3.0.0", "@types/fs-extra": "^11.0.4", "@types/global-agent": "^2.1.3", "@types/node": "^22.5.1", @@ -397,8 +397,8 @@ "@types/vscode-webview": "^1.57.5", "@typescript-eslint/eslint-plugin": "^7.17.0", "@typescript-eslint/parser": "^7.17.0", - "@vitejs/plugin-react": "^4.3.1", - "@vscode/vsce": "^3.1.0", + "@vitejs/plugin-react": "^4.3.2", + "@vscode/vsce": "^3.1.1", "@xenova/transformers": "^2.17.2", "apache-arrow": "^17.0.0", "autoprefixer": "^10.4.20", @@ -412,52 +412,52 @@ "comment-json": "^4.2.5", "commitizen": "^4.3.1", "cpy": "10.1.0", - "es-toolkit": "^1.21.0", + "es-toolkit": "^1.24.0", "eslint": "^8.57.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^18.0.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^3.6.3", - "eslint-plugin-import": "^2.30.0", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-json": "^4.0.1", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react-compiler": "latest", "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-unused-imports": "^3.2.0", - "esno": "^4.7.0", + "esno": "^4.8.0", "execa": "^9.4.0", "find-free-ports": "^3.1.1", "flexsearch": "^0.7.43", - "framer-motion": "^11.8.0", + "framer-motion": "^11.11.8", "fs-extra": "^11.2.0", "glob": "^11.0.0", "global-agent": "^3.0.0", - "html-react-parser": "^5.1.16", + "html-react-parser": "^5.1.18", "husky": "^9.1.6", "ignore": "^6.0.2", "immer": "^10.1.1", "inquirer": "^9.3.4", - "js-tiktoken": "^1.0.14", - "knip": "^5.30.5", + "js-tiktoken": "^1.0.15", + "knip": "^5.33.3", "langchain": "^0.3.2", "lexical": "^0.18.0", "lint-staged": "^15.2.10", "lowdb": "^7.0.1", - "mermaid": "^11.2.1", + "mermaid": "^11.3.0", "minimatch": "^10.0.1", "next-themes": "^0.3.0", "p-limit": "^6.1.0", - "pnpm": "^9.11.0", + "pnpm": "^9.12.1", "postcss": "^8.4.47", "prettier": "^3.3.3", "react": "19.0.0-rc-d6cb4e77-20240911", "react-dom": "19.0.0-rc-d6cb4e77-20240911", "react-hook-form": "^7.53.0", "react-markdown": "^9.0.1", - "react-resizable-panels": "^2.1.3", - "react-router": "^6.26.2", - "react-router-dom": "^6.26.2", + "react-resizable-panels": "^2.1.4", + "react-router": "^6.27.0", + "react-router-dom": "^6.27.0", "react-shiki": "^0.1.2", "react-use": "^17.5.1", "rehype-katex": "^7.0.1", @@ -467,37 +467,37 @@ "remark-math": "^6.0.0", "rimraf": "^6.0.1", "shell-quote": "^1.8.1", - "shiki": "^1.20.0", + "shiki": "^1.22.0", "simple-git": "^3.27.0", "socket.io": "^4.8.0", "socket.io-client": "^4.8.0", "sonner": "^1.5.0", - "tailwind-merge": "^2.5.2", + "tailwind-merge": "^2.5.3", "tailwindcss": "^3.4.13", "tailwindcss-animate": "^1.0.7", "tree-sitter-wasms": "^0.1.12", "tsup": "^8.3.0", "turndown": "^7.2.0", "typescript": "5.4.5", - "undici": "^6.19.8", + "undici": "^6.20.0", "unified": "^11.0.5", "use-immer": "^0.10.0", "use-resize-observer": "^9.1.0", "uuid": "^10.0.0", "vaul": "^1.0.0", - "vectordb": "^0.10.0", + "vectordb": "^0.11.0", "vite": "^5.4.8", "vite-plugin-pages": "^0.32.3", "vite-plugin-svgr": "^4.2.0", "vite-tsconfig-paths": "^5.0.1", - "vitest": "^2.1.1", - "web-tree-sitter": "^0.23.0", + "vitest": "^2.1.2", + "web-tree-sitter": "^0.24.3", "zod": "^3.23.8", "zustand": "^4.5.5" }, "pnpm": { "overrides": { - "@langchain/core": "0.3.3", + "@langchain/core": "0.3.10", "lexical": "^0.18.0", "shiki": "^1.20.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e1bdb3..a6084b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 lexical: ^0.18.0 shiki: ^1.20.0 @@ -33,46 +33,46 @@ importers: version: 4.3.1(@vue/compiler-sfc@3.4.36)(prettier@3.3.3) '@langchain/anthropic': specifier: ^0.3.3 - version: 0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) + version: 0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) '@langchain/community': - specifier: ^0.3.3 - version: 0.3.3(@langchain/anthropic@0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))))(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))(@xenova/transformers@2.17.2)(axios@1.7.7)(cheerio@1.0.0)(ignore@6.0.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.58.1(zod@3.23.8))(vectordb@0.10.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0))(ws@8.18.0) + specifier: ^0.3.5 + version: 0.3.5(@langchain/anthropic@0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))))(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))(@xenova/transformers@2.17.2)(axios@1.7.7)(cheerio@1.0.0)(ignore@6.0.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.67.3(zod@3.23.8))(vectordb@0.11.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0))(ws@8.18.0) '@langchain/core': - specifier: 0.3.3 - version: 0.3.3(openai@4.58.1(zod@3.23.8)) + specifier: 0.3.10 + version: 0.3.10(openai@4.67.3(zod@3.23.8)) '@langchain/langgraph': - specifier: ^0.2.9 - version: 0.2.9(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) + specifier: ^0.2.14 + version: 0.2.14(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) '@langchain/openai': - specifier: ^0.3.2 - version: 0.3.2(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) + specifier: ^0.3.7 + version: 0.3.7(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) '@langchain/textsplitters': specifier: ^0.1.0 - version: 0.1.0(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) + version: 0.1.0(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) '@lexical/react': specifier: ^0.18.0 version: 0.18.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(yjs@13.6.18) '@radix-ui/react-accordion': - specifier: ^1.2.0 - version: 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.2.1 + version: 1.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-alert-dialog': - specifier: ^1.1.1 - version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.2 + version: 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-checkbox': - specifier: ^1.1.1 - version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.2 + version: 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-context-menu': - specifier: ^2.2.1 - version: 2.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^2.2.2 + version: 2.2.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-dialog': - specifier: ^1.1.1 - version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.2 + version: 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-dropdown-menu': - specifier: ^2.1.1 - version: 2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^2.1.2 + version: 2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-hover-card': - specifier: ^1.1.1 - version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.2 + version: 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-icons': specifier: ^1.3.0 version: 1.3.0(react@19.0.0-rc-d6cb4e77-20240911) @@ -80,47 +80,47 @@ importers: specifier: ^2.1.0 version: 2.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-menubar': - specifier: ^1.1.1 - version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.2 + version: 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-popover': - specifier: ^1.1.1 - version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.2 + version: 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-progress': specifier: ^1.1.0 version: 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-radio-group': + specifier: ^1.2.1 + version: 1.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-scroll-area': specifier: ^1.2.0 version: 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-scroll-area': - specifier: ^1.1.0 - version: 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-select': - specifier: ^2.1.1 - version: 2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^2.1.2 + version: 2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slider': - specifier: ^1.2.0 - version: 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.2.1 + version: 1.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-switch': - specifier: ^1.1.0 - version: 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.1 + version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-tabs': - specifier: ^1.1.0 - version: 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.1 + version: 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-tooltip': - specifier: ^1.1.2 - version: 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + specifier: ^1.1.3 + version: 1.1.3(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-visually-hidden': specifier: ^1.1.0 version: 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@tanstack/react-query': - specifier: ^5.56.2 - version: 5.56.2(react@19.0.0-rc-d6cb4e77-20240911) + specifier: ^5.59.11 + version: 5.59.11(react@19.0.0-rc-d6cb4e77-20240911) '@tomjs/vite-plugin-vscode': - specifier: ^2.6.0 - version: 2.6.0(@swc/core@1.7.10)(postcss@8.4.47)(typescript@5.4.5)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) + specifier: ^3.0.0 + version: 3.0.0(@swc/core@1.7.10)(postcss@8.4.47)(typescript@5.4.5)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) '@types/fs-extra': specifier: ^11.0.4 version: 11.0.4 @@ -155,11 +155,11 @@ importers: specifier: ^7.17.0 version: 7.18.0(eslint@8.57.0)(typescript@5.4.5) '@vitejs/plugin-react': - specifier: ^4.3.1 - version: 4.3.1(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) + specifier: ^4.3.2 + version: 4.3.2(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) '@vscode/vsce': - specifier: ^3.1.0 - version: 3.1.0 + specifier: ^3.1.1 + version: 3.1.1 '@xenova/transformers': specifier: ^2.17.2 version: 2.17.2 @@ -171,7 +171,7 @@ importers: version: 10.4.20(postcss@8.4.47) babel-plugin-react-compiler: specifier: latest - version: 0.0.0-experimental-27e0f40-20241002 + version: 0.0.0-experimental-ad3b12a-20241011 chalk: specifier: ^5.3.0 version: 5.3.0 @@ -200,29 +200,29 @@ importers: specifier: 10.1.0 version: 10.1.0 es-toolkit: - specifier: ^1.21.0 - version: 1.21.0 + specifier: ^1.24.0 + version: 1.24.0 eslint: specifier: ^8.57.0 version: 8.57.0 eslint-config-airbnb: specifier: ^19.0.4 - version: 19.0.4(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.35.0(eslint@8.57.0))(eslint@8.57.0) + version: 19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.35.0(eslint@8.57.0))(eslint@8.57.0) eslint-config-airbnb-typescript: specifier: ^18.0.0 - version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0) + version: 18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0) eslint-config-prettier: specifier: ^9.1.0 version: 9.1.0(eslint@8.57.0) eslint-import-resolver-alias: specifier: ^1.1.2 - version: 1.1.2(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0)) + version: 1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0)) eslint-import-resolver-typescript: specifier: ^3.6.3 - version: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0) + version: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0) eslint-plugin-import: - specifier: ^2.30.0 - version: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) eslint-plugin-json: specifier: ^4.0.1 version: 4.0.1 @@ -231,7 +231,7 @@ importers: version: 5.2.1(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3) eslint-plugin-react-compiler: specifier: latest - version: 0.0.0-experimental-1e98da5-20241002(eslint@8.57.0) + version: 0.0.0-experimental-45ae4c3-20241011(eslint@8.57.0) eslint-plugin-simple-import-sort: specifier: ^12.1.1 version: 12.1.1(eslint@8.57.0) @@ -239,8 +239,8 @@ importers: specifier: ^3.2.0 version: 3.2.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) esno: - specifier: ^4.7.0 - version: 4.7.0 + specifier: ^4.8.0 + version: 4.8.0 execa: specifier: ^9.4.0 version: 9.4.0 @@ -251,8 +251,8 @@ importers: specifier: ^0.7.43 version: 0.7.43 framer-motion: - specifier: ^11.8.0 - version: 11.8.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911) + specifier: ^11.11.8 + version: 11.11.8(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911) fs-extra: specifier: ^11.2.0 version: 11.2.0 @@ -263,8 +263,8 @@ importers: specifier: ^3.0.0 version: 3.0.0 html-react-parser: - specifier: ^5.1.16 - version: 5.1.16(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + specifier: ^5.1.18 + version: 5.1.18(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) husky: specifier: ^9.1.6 version: 9.1.6 @@ -278,14 +278,14 @@ importers: specifier: ^9.3.4 version: 9.3.4 js-tiktoken: - specifier: ^1.0.14 - version: 1.0.14 + specifier: ^1.0.15 + version: 1.0.15 knip: - specifier: ^5.30.5 - version: 5.30.5(@types/node@22.5.1)(typescript@5.4.5) + specifier: ^5.33.3 + version: 5.33.3(@types/node@22.5.1)(typescript@5.4.5) langchain: specifier: ^0.3.2 - version: 0.3.2(@langchain/anthropic@0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))))(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))(axios@1.7.7)(cheerio@1.0.0)(openai@4.58.1(zod@3.23.8)) + version: 0.3.2(@langchain/anthropic@0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))))(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))(axios@1.7.7)(cheerio@1.0.0)(openai@4.67.3(zod@3.23.8)) lexical: specifier: ^0.18.0 version: 0.18.0 @@ -296,8 +296,8 @@ importers: specifier: ^7.0.1 version: 7.0.1 mermaid: - specifier: ^11.2.1 - version: 11.2.1 + specifier: ^11.3.0 + version: 11.3.0 minimatch: specifier: ^10.0.1 version: 10.0.1 @@ -308,8 +308,8 @@ importers: specifier: ^6.1.0 version: 6.1.0 pnpm: - specifier: ^9.11.0 - version: 9.11.0 + specifier: ^9.12.1 + version: 9.12.1 postcss: specifier: ^8.4.47 version: 8.4.47 @@ -329,14 +329,14 @@ importers: specifier: ^9.0.1 version: 9.0.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) react-resizable-panels: - specifier: ^2.1.3 - version: 2.1.3(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911) + specifier: ^2.1.4 + version: 2.1.4(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911) react-router: - specifier: ^6.26.2 - version: 6.26.2(react@19.0.0-rc-d6cb4e77-20240911) + specifier: ^6.27.0 + version: 6.27.0(react@19.0.0-rc-d6cb4e77-20240911) react-router-dom: - specifier: ^6.26.2 - version: 6.26.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911) + specifier: ^6.27.0 + version: 6.27.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911) react-shiki: specifier: ^0.1.2 version: 0.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -380,8 +380,8 @@ importers: specifier: ^1.5.0 version: 1.5.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911) tailwind-merge: - specifier: ^2.5.2 - version: 2.5.2 + specifier: ^2.5.3 + version: 2.5.3 tailwindcss: specifier: ^3.4.13 version: 3.4.13 @@ -393,7 +393,7 @@ importers: version: 0.1.12 tsup: specifier: ^8.3.0 - version: 8.3.0(@swc/core@1.7.10)(jiti@1.21.6)(postcss@8.4.47)(tsx@4.16.3)(typescript@5.4.5)(yaml@2.5.0) + version: 8.3.0(@swc/core@1.7.10)(jiti@2.3.3)(postcss@8.4.47)(tsx@4.19.1)(typescript@5.4.5)(yaml@2.5.0) turndown: specifier: ^7.2.0 version: 7.2.0 @@ -401,8 +401,8 @@ importers: specifier: 5.4.5 version: 5.4.5 undici: - specifier: ^6.19.8 - version: 6.19.8 + specifier: ^6.20.0 + version: 6.20.0 unified: specifier: ^11.0.5 version: 11.0.5 @@ -419,14 +419,14 @@ importers: specifier: ^1.0.0 version: 1.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) vectordb: - specifier: ^0.10.0 - version: 0.10.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0) + specifier: ^0.11.0 + version: 0.11.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0) vite: specifier: ^5.4.8 version: 5.4.8(@types/node@22.5.1)(less@4.2.0) vite-plugin-pages: specifier: ^0.32.3 - version: 0.32.3(@vue/compiler-sfc@3.4.36)(react-router@6.26.2(react@19.0.0-rc-d6cb4e77-20240911))(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) + version: 0.32.3(@vue/compiler-sfc@3.4.36)(react-router@6.27.0(react@19.0.0-rc-d6cb4e77-20240911))(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) vite-plugin-svgr: specifier: ^4.2.0 version: 4.2.0(rollup@4.21.1)(typescript@5.4.5)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) @@ -434,11 +434,11 @@ importers: specifier: ^5.0.1 version: 5.0.1(typescript@5.4.5)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) vitest: - specifier: ^2.1.1 - version: 2.1.1(@types/node@22.5.1)(less@4.2.0) + specifier: ^2.1.2 + version: 2.1.2(@types/node@22.5.1)(less@4.2.0) web-tree-sitter: - specifier: ^0.23.0 - version: 0.23.0 + specifier: ^0.24.3 + version: 0.24.3 zod: specifier: ^3.23.8 version: 3.23.8 @@ -719,12 +719,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.24.9': - resolution: {integrity: sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.25.2': resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} engines: {node: '>=6.9.0'} @@ -864,10 +858,6 @@ packages: resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.24.8': - resolution: {integrity: sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==} - engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.3': resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} engines: {node: '>=6.9.0'} @@ -997,12 +987,6 @@ packages: search-insights: optional: true - '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -1021,12 +1005,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} @@ -1045,12 +1023,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} @@ -1069,12 +1041,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} @@ -1093,12 +1059,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} @@ -1117,12 +1077,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} @@ -1141,12 +1095,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} @@ -1165,12 +1113,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} @@ -1189,12 +1131,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} @@ -1213,12 +1149,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} @@ -1237,12 +1167,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} @@ -1261,12 +1185,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} @@ -1285,12 +1203,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} @@ -1309,12 +1221,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} @@ -1333,12 +1239,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} @@ -1357,12 +1257,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} @@ -1381,12 +1275,6 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} @@ -1405,12 +1293,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} @@ -1435,12 +1317,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} @@ -1459,12 +1335,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} @@ -1483,12 +1353,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} @@ -1507,12 +1371,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} @@ -1531,12 +1389,6 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} @@ -1679,28 +1531,28 @@ packages: '@kwsites/promise-deferred@1.1.1': resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - '@lancedb/vectordb-darwin-arm64@0.4.20': - resolution: {integrity: sha512-ffP2K4sA5mQTgePyARw1y8dPN996FmpvyAYoWO+TSItaXlhcXvc+KVa5udNMCZMDYeEnEv2Xpj6k4PwW3oBz+A==} + '@lancedb/vectordb-darwin-arm64@0.11.0': + resolution: {integrity: sha512-ffI9sLdlJ0L0FjKVy5QpznRTgVaEGL2INJVcJauuzsYY2aOC3weNfE+v58n/cm9I/NulTdu1BemwzFpESoZf5A==} cpu: [arm64] os: [darwin] - '@lancedb/vectordb-darwin-x64@0.4.20': - resolution: {integrity: sha512-GSYsXE20RIehDu30FjREhJdEzhnwOTV7ZsrSXagStzLY1gr7pyd7sfqxmmUtdD09di7LnQoiM71AOpPTa01YwQ==} + '@lancedb/vectordb-darwin-x64@0.11.0': + resolution: {integrity: sha512-sMGKVmTj7Gt1z+1Sy24toCV8UgcQkX0ljQU1QunVEzJvoP9yah/DN5rw5Ozxiv8Obk6Pz3BMZYqV3BPmL9AiAg==} cpu: [x64] os: [darwin] - '@lancedb/vectordb-linux-arm64-gnu@0.4.20': - resolution: {integrity: sha512-FpNOjOsz3nJVm6EBGyNgbOW2aFhsWZ/igeY45Z8hbZaaK2YBwrg/DASoNlUzgv6IR8cUaGJ2irNVJfsKR2cG6g==} + '@lancedb/vectordb-linux-arm64-gnu@0.11.0': + resolution: {integrity: sha512-BQTiTbvJfNKEye9FRomItlFcbOoYCV8frBrQMIfli4q9GECwgBmXQaWP+rEZZrdqfG0DivTQJ0YSSHgAy3wCcA==} cpu: [arm64] os: [linux] - '@lancedb/vectordb-linux-x64-gnu@0.4.20': - resolution: {integrity: sha512-pOqWjrRZQSrLTlQPkjidRii7NZDw8Xu9pN6ouVu2JAK8n81FXaPtFCyAI+Y3v9GpnYDN0rvD4eQ36aHAVPsa2g==} + '@lancedb/vectordb-linux-x64-gnu@0.11.0': + resolution: {integrity: sha512-+RHu6YY311N21ZBM8OYbBFNuW+rqq0AC7Vp5eBvWKTOeNIf1Lz2vFAKhDPOgJt+ROoT/nzKRbksIEeIvnYQJNw==} cpu: [x64] os: [linux] - '@lancedb/vectordb-win32-x64-msvc@0.4.20': - resolution: {integrity: sha512-5J5SsYSJ7jRCmU/sgwVHdrGz43B/7R2T9OEoFTKyVAtqTZdu75rkytXyn9SyEayXVhlUOaw76N0ASm0hAoDS/A==} + '@lancedb/vectordb-win32-x64-msvc@0.11.0': + resolution: {integrity: sha512-IWdhJdiYIkJW+njNlRVNGG1bnGlQs+Wbrjy/NIZhVxch2yCj9gknZqWCuSHNR43a2oAdUY/kXgWL2AKEOfK1CQ==} cpu: [x64] os: [win32] @@ -1708,10 +1560,10 @@ packages: resolution: {integrity: sha512-OvnSV3Tjhb87n7CxWzIcJqcJEM4qoFDYYt6Rua7glQF/Ud5FBTurlzoMunLPTQeF5GdPiaOwP3nUw6I9gF7ppw==} engines: {node: '>=18'} peerDependencies: - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 - '@langchain/community@0.3.3': - resolution: {integrity: sha512-445g9hBeBNndNC8ruQIO/sNbHYBL3jjrPuDW+/S6e/RAXo8whJA/02CWRcSMDYX3o4+1Brrg6rFimipOuM9M9w==} + '@langchain/community@0.3.5': + resolution: {integrity: sha512-zcVzQQJpJaqJsxgr5AaNpI/MHCWRo2kpzrHuxgnVlq0WZ7zp9hZ2PVMfFtXN/0R86UkRCHcTe5/ARfv+BXje9Q==} engines: {node: '>=18'} peerDependencies: '@arcjet/redact': ^v1.0.0-alpha.23 @@ -1741,8 +1593,9 @@ packages: '@google-cloud/storage': ^6.10.1 || ^7.7.0 '@gradientai/nodejs-sdk': ^1.2.0 '@huggingface/inference': ^2.6.4 - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 '@layerup/layerup-security': ^1.5.12 + '@libsql/client': ^0.14.0 '@mendable/firecrawl-js': ^0.0.13 '@mlc-ai/web-llm': '*' '@mozilla/readability': '*' @@ -1785,7 +1638,6 @@ packages: closevector-web: 0.1.6 cohere-ai: '*' convex: ^1.3.1 - couchbase: ^4.3.0 crypto-js: ^4.2.0 d3-dsv: ^2.0.0 discord.js: ^14.14.1 @@ -1811,7 +1663,6 @@ packages: mongodb: '>=5.2.0' mysql2: ^3.9.8 neo4j-driver: '*' - node-llama-cpp: '*' notion-to-md: ^3.1.0 officeparser: ^4.0.4 pdf-parse: 1.1.1 @@ -1893,6 +1744,8 @@ packages: optional: true '@layerup/layerup-security': optional: true + '@libsql/client': + optional: true '@mendable/firecrawl-js': optional: true '@mlc-ai/web-llm': @@ -1977,8 +1830,6 @@ packages: optional: true convex: optional: true - couchbase: - optional: true crypto-js: optional: true d3-dsv: @@ -2029,8 +1880,6 @@ packages: optional: true neo4j-driver: optional: true - node-llama-cpp: - optional: true notion-to-md: optional: true officeparser: @@ -2080,33 +1929,33 @@ packages: youtubei.js: optional: true - '@langchain/core@0.3.3': - resolution: {integrity: sha512-WAtkmhbdl2T41qzimTzhb3pXCHQxO4onqxzPxgdf3KftQdTwLq0YYBDhozRMZLNAd/+cfH0ymZGaZSsnc9Ogsg==} + '@langchain/core@0.3.10': + resolution: {integrity: sha512-MBGDcNeMLRFsEtfzYrqFpome9M2KI7wa4VcFoHPrjf5cvw1gaEAWiMST0jq42tgV3XmukiueCog6kj9Q/hxw2w==} engines: {node: '>=18'} - '@langchain/langgraph-checkpoint@0.0.6': - resolution: {integrity: sha512-hQsznlUMFKyOCaN9VtqNSSemfKATujNy5ePM6NX7lruk/Mmi2t7R9SsBnf9G2Yts+IaIwv3vJJaAFYEHfqbc5g==} + '@langchain/langgraph-checkpoint@0.0.10': + resolution: {integrity: sha512-BMfJD5Eg39pM0iJmEv50qJL5dJJI5U2oHuNXixWlQ1BKsvtbSs713+EHc21uuvcJUct1MPiv7RdfvwXycLM/aQ==} engines: {node: '>=18'} peerDependencies: - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 - '@langchain/langgraph@0.2.9': - resolution: {integrity: sha512-vwIxABPUIFUusEM8TPXGWhJIQNdiqUwAq9fp4clZ2QPxRGJNvAL0skemU45YUVmgBnzyoBd+KypHMPQJI0FObw==} + '@langchain/langgraph@0.2.14': + resolution: {integrity: sha512-gvneCZDzYzpt+P6ye7pveiRZtlGKWFKk3XAck31yxSf5D/++lP8s6ocMY1x+UaFEfAYd5Qj6jNPI9aPp9Y75jQ==} engines: {node: '>=18'} peerDependencies: - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 - '@langchain/openai@0.3.2': - resolution: {integrity: sha512-p513TVHkZ+mMV4dGloprPFKaukOuOZxyPXY/IWReQK34c1dpnywmjrXg8ydcnfncNbq+kJ/kKe671NK9bic4WA==} + '@langchain/openai@0.3.7': + resolution: {integrity: sha512-3Jhyy2uKkymYu1iVK18sG2ASZVg0EQcmtTuEPVnrrFGYJ0EIPufejm6bE1ebOHZRc50kSxQwRFCAGrMatNtUiQ==} engines: {node: '>=18'} peerDependencies: - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 '@langchain/textsplitters@0.1.0': resolution: {integrity: sha512-djI4uw9rlkAb5iMhtLED+xJebDdAG935AdP4eRTB02R7OB/act55Bj9wsskhZsvuyQRpO4O1wQOp85s6T6GWmw==} engines: {node: '>=18'} peerDependencies: - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 '@lexical/clipboard@0.18.0': resolution: {integrity: sha512-ybc+hx14wj0n2ZjdOkLcZ02MRB3UprXjpLDXlByFIuVcZpUxVcp3NzA0UBPOKXYKvdt0bmgjnAsFWM5OSbwS0w==} @@ -2265,8 +2114,8 @@ packages: '@radix-ui/primitive@1.1.0': resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} - '@radix-ui/react-accordion@1.2.0': - resolution: {integrity: sha512-HJOzSX8dQqtsp/3jVxCU3CXEONF7/2jlGAB28oX8TTw1Dz8JYbEI1UcL8355PuLBE41/IRRMvCw7VkiK/jcUOQ==} + '@radix-ui/react-accordion@1.2.1': + resolution: {integrity: sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2278,8 +2127,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-alert-dialog@1.1.1': - resolution: {integrity: sha512-wmCoJwj7byuVuiLKqDLlX7ClSUU0vd9sdCeM+2Ls+uf13+cpSJoMgwysHq1SGVVkJj5Xn0XWi1NoRCdkMpr6Mw==} + '@radix-ui/react-alert-dialog@1.1.2': + resolution: {integrity: sha512-eGSlLzPhKO+TErxkiGcCZGuvbVMnLA1MTnyBksGOeGRGkxHiiJUujsjmNTdWTm4iHVSRaUao9/4Ur671auMghQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2304,8 +2153,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-checkbox@1.1.1': - resolution: {integrity: sha512-0i/EKJ222Afa1FE0C6pNJxDq1itzcl3HChE9DwskA4th4KRse8ojx8a1nVcOjwJdbpDLcz7uol77yYnQNMHdKw==} + '@radix-ui/react-checkbox@1.1.2': + resolution: {integrity: sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2317,8 +2166,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-collapsible@1.1.0': - resolution: {integrity: sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==} + '@radix-ui/react-collapsible@1.1.1': + resolution: {integrity: sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2361,8 +2210,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-context-menu@2.2.1': - resolution: {integrity: sha512-wvMKKIeb3eOrkJ96s722vcidZ+2ZNfcYZWBPRHIB1VWrF+fiF851Io6LX0kmK5wTDQFKdulCCKJk2c3SBaQHvA==} + '@radix-ui/react-context-menu@2.2.2': + resolution: {integrity: sha512-99EatSTpW+hRYHt7m8wdDlLtkmTovEe8Z/hnxUPV+SKuuNL5HWNhQI4QSdjZqNSgXHay2z4M3Dym73j9p2Gx5Q==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2392,6 +2241,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-dialog@1.0.5': resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: @@ -2405,8 +2263,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dialog@1.1.1': - resolution: {integrity: sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==} + '@radix-ui/react-dialog@1.1.2': + resolution: {integrity: sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2440,8 +2298,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dismissable-layer@1.1.0': - resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} + '@radix-ui/react-dismissable-layer@1.1.1': + resolution: {integrity: sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2453,8 +2311,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dropdown-menu@2.1.1': - resolution: {integrity: sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==} + '@radix-ui/react-dropdown-menu@2.1.2': + resolution: {integrity: sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2475,8 +2333,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-focus-guards@1.1.0': - resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} + '@radix-ui/react-focus-guards@1.1.1': + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -2510,8 +2368,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-hover-card@1.1.1': - resolution: {integrity: sha512-IwzAOP97hQpDADYVKrEEHUH/b2LA+9MgB0LgdmnbFO2u/3M5hmEofjjr2M6CyzUblaAqJdFm6B7oFtU72DPXrA==} + '@radix-ui/react-hover-card@1.1.2': + resolution: {integrity: sha512-Y5w0qGhysvmqsIy6nQxaPa6mXNKznfoGjOfBgzOjocLxr2XlSjqBMYQQL+FfyogsMuX+m8cZyQGYhJxvxUzO4w==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2559,8 +2417,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menu@2.1.1': - resolution: {integrity: sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==} + '@radix-ui/react-menu@2.1.2': + resolution: {integrity: sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2572,8 +2430,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menubar@1.1.1': - resolution: {integrity: sha512-V05Hryq/BE2m+rs8d5eLfrS0jmSWSDHEbG7jEyLA5D5J9jTvWj/o3v3xDN9YsOlH6QIkJgiaNDaP+S4T1rdykw==} + '@radix-ui/react-menubar@1.1.2': + resolution: {integrity: sha512-cKmj5Gte7LVyuz+8gXinxZAZECQU+N7aq5pw7kUPpx3xjnDXDbsdzHtCCD2W72bwzy74AvrqdYnKYS42ueskUQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2585,8 +2443,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popover@1.1.1': - resolution: {integrity: sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g==} + '@radix-ui/react-popover@1.1.2': + resolution: {integrity: sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2624,8 +2482,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-portal@1.1.1': - resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} + '@radix-ui/react-portal@1.1.2': + resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2650,8 +2508,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-presence@1.1.0': - resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + '@radix-ui/react-presence@1.1.1': + resolution: {integrity: sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2702,8 +2560,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-radio-group@1.2.0': - resolution: {integrity: sha512-yv+oiLaicYMBpqgfpSPw6q+RyXlLdIpQWDHZbUKURxe+nEh53hFXPPlfhfQQtYkS5MMK/5IWIa76SksleQZSzw==} + '@radix-ui/react-radio-group@1.2.1': + resolution: {integrity: sha512-kdbv54g4vfRjja9DNWPMxKvXblzqbpEC8kspEkZ6dVP7kQksGCn+iZHkcCz2nb00+lPdRvxrqy4WrvvV1cNqrQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2728,8 +2586,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-scroll-area@1.1.0': - resolution: {integrity: sha512-9ArIZ9HWhsrfqS765h+GZuLoxaRHD/j0ZWOWilsCvYTpYJp8XwCqNG7Dt9Nu/TItKOdgLGkOPCodQvDc+UMwYg==} + '@radix-ui/react-scroll-area@1.2.0': + resolution: {integrity: sha512-q2jMBdsJ9zB7QG6ngQNzNwlvxLQqONyL58QbEGwuyRZZb/ARQwk3uQVbCF7GvQVOtV6EU/pDxAw3zRzJZI3rpQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2741,8 +2599,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-select@2.1.1': - resolution: {integrity: sha512-8iRDfyLtzxlprOo9IicnzvpsO1wNCkuwzzCM+Z5Rb5tNOpCdMvcc2AkzX0Fz+Tz9v6NJ5B/7EEgyZveo4FBRfQ==} + '@radix-ui/react-select@2.1.2': + resolution: {integrity: sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2754,8 +2612,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-slider@1.2.0': - resolution: {integrity: sha512-dAHCDA4/ySXROEPaRtaMV5WHL8+JB/DbtyTbJjYkY0RXmKMO2Ln8DFZhywG5/mVQ4WqHDBc8smc14yPXPqZHYA==} + '@radix-ui/react-slider@1.2.1': + resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2785,8 +2643,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-switch@1.1.0': - resolution: {integrity: sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw==} + '@radix-ui/react-switch@1.1.1': + resolution: {integrity: sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2798,8 +2656,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-tabs@1.1.0': - resolution: {integrity: sha512-bZgOKB/LtZIij75FSuPzyEti/XBhJH52ExgtdVqjCIh+Nx/FW+LhnbXtbCzIi34ccyMsyOja8T0thCzoHFXNKA==} + '@radix-ui/react-tabs@1.1.1': + resolution: {integrity: sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2811,8 +2669,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-tooltip@1.1.2': - resolution: {integrity: sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==} + '@radix-ui/react-tooltip@1.1.3': + resolution: {integrity: sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -2939,8 +2797,8 @@ packages: '@radix-ui/rect@1.1.0': resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} - '@remix-run/router@1.19.2': - resolution: {integrity: sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==} + '@remix-run/router@1.20.0': + resolution: {integrity: sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==} engines: {node: '>=14.0.0'} '@rollup/pluginutils@5.1.0': @@ -3297,11 +3155,11 @@ packages: '@swc/types@0.1.12': resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} - '@tanstack/query-core@5.56.2': - resolution: {integrity: sha512-gor0RI3/R5rVV3gXfddh1MM+hgl0Z4G7tj6Xxpq6p2I03NGPaJ8dITY9Gz05zYYb/EJq9vPas/T4wn9EaDPd4Q==} + '@tanstack/query-core@5.59.10': + resolution: {integrity: sha512-XxvnKeBWqDTHstyjA1qmSD5VS/FZ2g/qYvPMhFM7IZF0JnMqMxtzbiUkiTFaZ4YZo/Q84LS0hZi0UncKJ3vIhg==} - '@tanstack/react-query@5.56.2': - resolution: {integrity: sha512-SR0GzHVo6yzhN72pnRhkEFRAHMsUo5ZPzAxfTMvUxFIDVS6W9LYUp6nXW3fcHVdg0ZJl8opSH85jqahvm6DSVg==} + '@tanstack/react-query@5.59.11': + resolution: {integrity: sha512-m5I4+4NHy6p0uzKLiq30EdRGk37CHHjXJsfMT0bty/Z/aO11LgXUgDBCq/xma4eO5RlV95sFVmi2QB9nVaLlxg==} peerDependencies: react: ^18 || ^19 @@ -3309,8 +3167,8 @@ packages: resolution: {integrity: sha512-objFTMXbLKoHbN8WIPz25gy/H16VewH5qcdEu2wrbAYtNid4d3s3C/F1PfXUiSYpzd7YoKh2yRUkTFl03btgRw==} engines: {node: '>=16'} - '@tomjs/vite-plugin-vscode@2.6.0': - resolution: {integrity: sha512-WWifuMj6bcjpYUTcyVAstENGxEw3+zrmwgHeHok4zEAdi8mhbj4hS6M7D2nt3tBeBOz+VCcDMghNKljzy59UZQ==} + '@tomjs/vite-plugin-vscode@3.0.0': + resolution: {integrity: sha512-mHIF+SngggVoTPQNGvx6UIz5emaBqXSQEuDZUF0NoaSe3ZxfGMYiTxJnL0saw3OU8NHpbaaqY+6v918eNkMZpg==} engines: {node: '>=16'} peerDependencies: vite: '>=2' @@ -3432,9 +3290,6 @@ packages: '@types/prop-types@15.7.12': resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} - '@types/qs@6.9.15': - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} - '@types/react@18.3.4': resolution: {integrity: sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==} @@ -3618,8 +3473,8 @@ packages: peerDependencies: vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 - '@vitejs/plugin-react@4.3.1': - resolution: {integrity: sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==} + '@vitejs/plugin-react@4.3.2': + resolution: {integrity: sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^4.2.0 || ^5.0.0 @@ -3631,13 +3486,13 @@ packages: vite: ^5.0.0 vue: ^3.2.25 - '@vitest/expect@2.1.1': - resolution: {integrity: sha512-YeueunS0HiHiQxk+KEOnq/QMzlUuOzbU1Go+PgAsHvvv3tUkJPm9xWt+6ITNTlzsMXUjmgm5T+U7KBPK2qQV6w==} + '@vitest/expect@2.1.2': + resolution: {integrity: sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==} - '@vitest/mocker@2.1.1': - resolution: {integrity: sha512-LNN5VwOEdJqCmJ/2XJBywB11DLlkbY0ooDJW3uRX5cZyYCrc4PI/ePX0iQhE3BiEGiQmK4GE7Q/PqCkkaiPnrA==} + '@vitest/mocker@2.1.2': + resolution: {integrity: sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==} peerDependencies: - '@vitest/spy': 2.1.1 + '@vitest/spy': 2.1.2 msw: ^2.3.5 vite: ^5.0.0 peerDependenciesMeta: @@ -3646,20 +3501,20 @@ packages: vite: optional: true - '@vitest/pretty-format@2.1.1': - resolution: {integrity: sha512-SjxPFOtuINDUW8/UkElJYQSFtnWX7tMksSGW0vfjxMneFqxVr8YJ979QpMbDW7g+BIiq88RAGDjf7en6rvLPPQ==} + '@vitest/pretty-format@2.1.2': + resolution: {integrity: sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==} - '@vitest/runner@2.1.1': - resolution: {integrity: sha512-uTPuY6PWOYitIkLPidaY5L3t0JJITdGTSwBtwMjKzo5O6RCOEncz9PUN+0pDidX8kTHYjO0EwUIvhlGpnGpxmA==} + '@vitest/runner@2.1.2': + resolution: {integrity: sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==} - '@vitest/snapshot@2.1.1': - resolution: {integrity: sha512-BnSku1WFy7r4mm96ha2FzN99AZJgpZOWrAhtQfoxjUU5YMRpq1zmHRq7a5K9/NjqonebO7iVDla+VvZS8BOWMw==} + '@vitest/snapshot@2.1.2': + resolution: {integrity: sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==} - '@vitest/spy@2.1.1': - resolution: {integrity: sha512-ZM39BnZ9t/xZ/nF4UwRH5il0Sw93QnZXd9NAZGRpIgj0yvVwPpLd702s/Cx955rGaMlyBQkZJ2Ir7qyY48VZ+g==} + '@vitest/spy@2.1.2': + resolution: {integrity: sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==} - '@vitest/utils@2.1.1': - resolution: {integrity: sha512-Y6Q9TsI+qJ2CC0ZKj6VBb+T8UPz593N113nnUykqwANqhgf3QkZeHFlusgKLTqrnVHbj/XDKZcDHol+dxVT+rQ==} + '@vitest/utils@2.1.2': + resolution: {integrity: sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==} '@vscode/vsce-sign-alpine-arm64@2.0.2': resolution: {integrity: sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==} @@ -3709,8 +3564,8 @@ packages: '@vscode/vsce-sign@2.0.4': resolution: {integrity: sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==} - '@vscode/vsce@3.1.0': - resolution: {integrity: sha512-fwdfp1Ol+bZtlSGkpcd/nztfo6+SVsTOMWjZ/+a88lVtUn7gXNbSu7dbniecl5mz4vINl+oaVDVtVdGbJDApmw==} + '@vscode/vsce@3.1.1': + resolution: {integrity: sha512-N62Ca9ElRPLUUzf7l9CeEBlLrYzFPRQq7huKk4pVW+LjIOSXfFIPudixn5QvZcz+yXDOh15IopI3K2o3y9666Q==} engines: {node: '>= 20'} hasBin: true @@ -4017,8 +3872,8 @@ packages: b4a@1.6.6: resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==} - babel-plugin-react-compiler@0.0.0-experimental-27e0f40-20241002: - resolution: {integrity: sha512-hMOwSqoI0gxyjgGVhsMqPsVV4bjCqJ2WTUFsQyrk+KAkDqK/o7Th9XRl/xhVApPbE4VzQeiutC60rbBGqNebHQ==} + babel-plugin-react-compiler@0.0.0-experimental-ad3b12a-20241011: + resolution: {integrity: sha512-nKOKInm8musJDa45Q9rCLJ8H0PMw1hSBWjEWoTvm+jRnufOdck2mVG3i8e5r5VRJatP6jdfbfXo/Q9iNUotz8g==} bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -4921,8 +4776,8 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} - es-toolkit@1.21.0: - resolution: {integrity: sha512-d1T3yyOBPYVbmLtjxsuzuIInuJaw7kcbtu/7sQyfM04hT98X8Z0bLKhYYYePdCBYH4GoA5AnWUyodV5xDcdrOw==} + es-toolkit@1.24.0: + resolution: {integrity: sha512-nZM+MRSGhKjCdjvqWEFr5Jns6vxoXtBcsl4/cEsGMgsMx8Z2ato4vBTGMUSIQBZJgEdKyNcgGh42yu9xiuNYtQ==} es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} @@ -4932,11 +4787,6 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -5015,8 +4865,8 @@ packages: eslint-plugin-import-x: optional: true - eslint-module-utils@2.11.0: - resolution: {integrity: sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==} + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -5057,12 +4907,12 @@ packages: eslint-import-resolver-webpack: optional: true - eslint-plugin-import@2.30.0: - resolution: {integrity: sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==} + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 peerDependenciesMeta: '@typescript-eslint/parser': optional: true @@ -5091,8 +4941,8 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-react-compiler@0.0.0-experimental-1e98da5-20241002: - resolution: {integrity: sha512-+wA20cShsWWf0DNuj4PIcbsomnn9emcyGncNzGNesP/tXMXmYy/yH+i2STv/fFG1Ap9FeTVeFhwciWtvpcauRA==} + eslint-plugin-react-compiler@0.0.0-experimental-45ae4c3-20241011: + resolution: {integrity: sha512-m+BmeFtVWzrHt87sb5g5jLttHdo9YScPiuiingdEqLYtUv7pdVi6pQgY3nCOI4h09C4wmWS9xzpaVNEgiODOBg==} engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0} peerDependencies: eslint: '>=7' @@ -5141,8 +4991,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true - esno@4.7.0: - resolution: {integrity: sha512-81owrjxIxOwqcABt20U09Wn8lpBo9K6ttqbGvQcB3VYNLJyaV1fvKkDtpZd3Rj5BX3WXiGiJCjUevKQGNICzJg==} + esno@4.8.0: + resolution: {integrity: sha512-acMtooReAQGzLU0zcuEDHa8S62meh5aIyi8jboYxyvAePdmuWx2Mpwmt0xjwO0bs9/SXf+dvXJ0QJoDWw814Iw==} hasBin: true espree@9.6.1: @@ -5371,8 +5221,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@11.8.0: - resolution: {integrity: sha512-q/axN/PFRdKmzPK6PO2OhbLUMWXXZuiejdM1/3FhC2hm4YIetc+qeco2EvWm4u1/UTFmevclE492wGFNfSZ4eQ==} + framer-motion@11.11.8: + resolution: {integrity: sha512-mnGQNEoz99GtFXBBPw+Ag5K4FcfP5XrXxrxHz+iE4Lmg7W3sf2gKmGuvfkZCW/yIfcdv5vJd6KiSPETH1Pw68Q==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 @@ -5644,8 +5494,8 @@ packages: html-dom-parser@5.0.10: resolution: {integrity: sha512-GwArYL3V3V8yU/mLKoFF7HlLBv80BZ2Ey1BzfVNRpAci0cEKhFHI/Qh8o8oyt3qlAMLlK250wsxLdYX4viedvg==} - html-react-parser@5.1.16: - resolution: {integrity: sha512-OtVPEQRwa4eelyMbHmUfMSw5VwJsVGSVsfa8I+M8xuV87n91cF3PHpvT/z0Frf1uG34atqh3dxgjaGIsmqVsRA==} + html-react-parser@5.1.18: + resolution: {integrity: sha512-65BwC0zzrdeW96jB2FRr5f1ovBhRMpLPJNvwkY5kA8Ay5xdL9t/RH2/uUTM7p+cl5iM88i6dDk4LXtfMnRmaJQ==} peerDependencies: '@types/react': 0.14 || 15 || 16 || 17 || 18 react: 0.14 || 15 || 16 || 17 || 18 @@ -5759,6 +5609,9 @@ packages: inline-style-parser@0.2.3: resolution: {integrity: sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==} + inline-style-parser@0.2.4: + resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + inline-style-prefixer@7.0.1: resolution: {integrity: sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==} @@ -6013,6 +5866,10 @@ packages: resolution: {integrity: sha512-c+PHQZakiQuMKbnhvrjZUvrK6E/AfmTOf4P+E3Y4FNVHcNMX9e/XrnbEvO+m4wS6ZjsvhHh/POQTlfy8uXFc0A==} hasBin: true + jiti@2.3.3: + resolution: {integrity: sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==} + hasBin: true + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -6020,8 +5877,8 @@ packages: js-cookie@2.2.1: resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} - js-tiktoken@1.0.14: - resolution: {integrity: sha512-Pk3l3WOgM9joguZY2k52+jH82RtABRgB5RdGFZNUGbOKGMVlNmafcPA3b0ITcCZPu1L9UclP1tne6aw7ZI4Myg==} + js-tiktoken@1.0.15: + resolution: {integrity: sha512-65ruOWWXDEZHHbAo7EjOcNxOGasQKbL4Fq3jEr2xsCqSsoOo6VVSqzWQb6PRIqypFSDcma4jO90YP0w5X8qVXQ==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -6117,8 +5974,8 @@ packages: khroma@2.1.0: resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} - knip@5.30.5: - resolution: {integrity: sha512-opta1VVKAfIzhvj1iyOr/3SgSDC6jYPoUaYkvjftNqMTeURppYY5VqrAa5DOcJnIsdcAdyoIKHUFg9NRiFaM5w==} + knip@5.33.3: + resolution: {integrity: sha512-saUxedVDCa/8p3w445at66vLmYKretzYsX7+elMJ5ROWGzU+1aTRm3EmKELTaho1ue7BlwJB5BxLJROy43+LtQ==} engines: {node: '>=18.6.0'} hasBin: true peerDependencies: @@ -6135,7 +5992,7 @@ packages: '@langchain/anthropic': '*' '@langchain/aws': '*' '@langchain/cohere': '*' - '@langchain/core': 0.3.3 + '@langchain/core': 0.3.10 '@langchain/google-genai': '*' '@langchain/google-vertexai': '*' '@langchain/groq': '*' @@ -6186,6 +6043,14 @@ packages: openai: optional: true + langsmith@0.1.65: + resolution: {integrity: sha512-+aBft8/jUQbVPv3MWVwFwW/rMxyyA8xSRIsjWl773Nc7LDniczuf2rxZEUslV02RB36EIBgCJPNX7jz2L5YsIQ==} + peerDependencies: + openai: '*' + peerDependenciesMeta: + openai: + optional: true + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -6478,8 +6343,8 @@ packages: merge@2.1.1: resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==} - mermaid@11.2.1: - resolution: {integrity: sha512-F8TEaLVVyxTUmvKswVFyOkjPrlJA5h5vNR1f7ZnSWSpqxgEZG1hggtn/QCa7znC28bhlcrNh10qYaIiill7q4A==} + mermaid@11.3.0: + resolution: {integrity: sha512-fFmf2gRXLtlGzug4wpIGN+rQdZ30M8IZEB1D3eZkXNqC7puhqeURBcD/9tbwXsqBO+A6Nzzo3MSSepmnw5xSeg==} micromark-core-commonmark@2.0.1: resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} @@ -6831,8 +6696,8 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - openai@4.58.1: - resolution: {integrity: sha512-n9fN4RIjbj4PbZU6IN/FOBBbxHbHEcW18rDZ4nW2cDNfZP2+upm/FM20UCmRNMQTvhOvw/2Tw4vgioQyQb5nlA==} + openai@4.67.3: + resolution: {integrity: sha512-HT2tZgjLgRqbLQNKmYtjdF/4TQuiBvg1oGvTDhwpSEQzxo6/oM1us8VQ53vBK2BiKvCxFuq6gKGG70qfwrNhKg==} hasBin: true peerDependencies: zod: ^3.23.8 @@ -7052,8 +6917,8 @@ packages: platform@1.3.6: resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} - pnpm@9.11.0: - resolution: {integrity: sha512-CiA/+u1aP2MkLNBkyPtYkjZsED4ygHkxj3gGLyTqjJ1QvGpHqjVnyr79gk0XDnj6J0XtHxaxMuFkNhRrdojxmw==} + pnpm@9.12.1: + resolution: {integrity: sha512-5aflKkGDoC1ZMQV/eg2/+dXpzjFh4z+miuOSElt5KCqKikcKUd/IoO2GIhRC6y+1cBmwmQ7ST6tRm/DhvFzPxA==} engines: {node: '>=18.12'} hasBin: true @@ -7258,8 +7123,8 @@ packages: '@types/react': optional: true - react-remove-scroll@2.5.7: - resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + react-remove-scroll@2.6.0: + resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==} engines: {node: '>=10'} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -7268,21 +7133,21 @@ packages: '@types/react': optional: true - react-resizable-panels@2.1.3: - resolution: {integrity: sha512-Zz0sCro6aUubL+hYh67eTnn5vxAu+HUZ7+IXvGjsBCBaudDEpIyZyDGE3vcgKi2w6IN3rYH+WXO+MwpgMSOpaQ==} + react-resizable-panels@2.1.4: + resolution: {integrity: sha512-kzue8lsoSBdyyd2IfXLQMMhNujOxRoGVus+63K95fQqleGxTfvgYLTzbwYMOODeAHqnkjb3WV/Ks7f5+gDYZuQ==} peerDependencies: react: ^16.14.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 - react-router-dom@6.26.2: - resolution: {integrity: sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==} + react-router-dom@6.27.0: + resolution: {integrity: sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' - react-router@6.26.2: - resolution: {integrity: sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==} + react-router@6.27.0: + resolution: {integrity: sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' @@ -7810,14 +7675,14 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - style-to-js@1.1.14: - resolution: {integrity: sha512-+FGNddHGLPY4NOPneEEdFj8dIy+oV4mHGrPZpB38P+YXrCAG9mp70dbcsAWnM8BFZULkJRvMqD0CXRjZLOYJFA==} + style-to-js@1.1.16: + resolution: {integrity: sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==} style-to-object@1.0.6: resolution: {integrity: sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==} - style-to-object@1.0.7: - resolution: {integrity: sha512-uSjr59G5u6fbxUfKbb8GcqMGT3Xs9v5IbPkjb0S16GyOeBLAzSRK0CixBv5YrYvzO6TDLzIS6QCn78tkqWngPw==} + style-to-object@1.0.8: + resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} stylis@4.3.4: resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} @@ -7865,8 +7730,8 @@ packages: engines: {node: '>=12.17'} hasBin: true - tailwind-merge@2.5.2: - resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==} + tailwind-merge@2.5.3: + resolution: {integrity: sha512-d9ZolCAIzom1nf/5p4LdD5zvjmgSxY0BGgdSvmXIoMYAiPdAW/dSpP7joCDYFY7r/HkEa2qmPtkgsu0xjQeQtw==} tailwindcss-animate@1.0.7: resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} @@ -8058,13 +7923,13 @@ packages: typescript: optional: true - tsx@4.10.5: - resolution: {integrity: sha512-twDSbf7Gtea4I2copqovUiNTEDrT8XNFXsuHpfGbdpW/z9ZW4fTghzzhAG0WfrCuJmJiOEY1nLIjq4u3oujRWQ==} + tsx@4.16.3: + resolution: {integrity: sha512-MP8AEUxVnboD2rCC6kDLxnpDBNWN9k3BSVU/0/nNxgm70bPBnfn+yCKcnOsIVPQwdkbKYoFOlKjjWZWJ2XCXUg==} engines: {node: '>=18.0.0'} hasBin: true - tsx@4.16.3: - resolution: {integrity: sha512-MP8AEUxVnboD2rCC6kDLxnpDBNWN9k3BSVU/0/nNxgm70bPBnfn+yCKcnOsIVPQwdkbKYoFOlKjjWZWJ2XCXUg==} + tsx@4.19.1: + resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} engines: {node: '>=18.0.0'} hasBin: true @@ -8157,8 +8022,8 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - undici@6.19.8: - resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==} + undici@6.20.0: + resolution: {integrity: sha512-AITZfPuxubm31Sx0vr8bteSalEbs9wQb/BOBi9FPlD9Qpd6HxZ4Q0+hI742jBhkPb4RT2v5MQzaW5VhRVyj+9A==} engines: {node: '>=18.17'} unicorn-magic@0.1.0: @@ -8289,8 +8154,8 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 - vectordb@0.10.0: - resolution: {integrity: sha512-bTgnJP65zM7Foyhz08a708Cn0PglONQYKJ8c8dGjTHAOqCACvQM5iyNHddOfroQ1mgXA8neyt81cNY3IMCuF2A==} + vectordb@0.11.0: + resolution: {integrity: sha512-fhuZM2+CZB/tmQ5WFizShFP30CcKqgbGzFvdsoy1WssH5NLDrgLTXk3GDwMQCVCSaxvnF1lhYh8QWM9Lbw9yRQ==} cpu: [x64, arm64] os: [darwin, linux, win32] peerDependencies: @@ -8306,8 +8171,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-node@2.1.1: - resolution: {integrity: sha512-N/mGckI1suG/5wQI35XeR9rsMsPqKXzq1CdUndzVstBj/HvyxxGctwnK6WX43NGt5L3Z5tcRf83g4TITKJhPrA==} + vite-node@2.1.2: + resolution: {integrity: sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -8413,15 +8278,15 @@ packages: postcss: optional: true - vitest@2.1.1: - resolution: {integrity: sha512-97We7/VC0e9X5zBVkvt7SGQMGrRtn3KtySFQG5fpaMlS+l62eeXRQO633AYhSTC3z7IMebnPPNjGXVGNRFlxBA==} + vitest@2.1.2: + resolution: {integrity: sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.1 - '@vitest/ui': 2.1.1 + '@vitest/browser': 2.1.2 + '@vitest/ui': 2.1.2 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -8493,8 +8358,8 @@ packages: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} - web-tree-sitter@0.23.0: - resolution: {integrity: sha512-p1T+ju2H30fpVX2q5yr+Wv/NfdMMWMjQp9Q+4eEPrHAJpPFh9DPfI2Yr9L1f5SA5KPE+g1cNUqPbpihxUDzmVw==} + web-tree-sitter@0.24.3: + resolution: {integrity: sha512-uR9YNewr1S2EzPKE+y39nAwaTyobBaZRG/IsfkB/OT4v0lXtNj5WjtHKgn2h7eOYUWIZh5rK9Px7tI6S9CRKdA==} webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -9072,14 +8937,14 @@ snapshots: '@babel/helper-member-expression-to-functions@7.24.8': dependencies: - '@babel/traverse': 7.24.8 + '@babel/traverse': 7.25.3 '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.24.7': dependencies: - '@babel/traverse': 7.24.7 + '@babel/traverse': 7.25.3 '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color @@ -9095,17 +8960,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.24.9(@babel/core@7.25.2)': - dependencies: - '@babel/core': 7.25.2 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -9133,14 +8987,14 @@ snapshots: '@babel/helper-simple-access@7.24.7': dependencies: - '@babel/traverse': 7.24.7 + '@babel/traverse': 7.25.3 '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.24.7': dependencies: - '@babel/traverse': 7.24.8 + '@babel/traverse': 7.25.3 '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color @@ -9205,7 +9059,7 @@ snapshots: '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 - '@babel/helper-module-transforms': 7.24.9(@babel/core@7.25.2) + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-simple-access': 7.24.7 transitivePeerDependencies: @@ -9273,21 +9127,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@7.24.8': - dependencies: - '@babel/code-frame': 7.24.7 - '@babel/generator': 7.25.0 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-function-name': 7.24.7 - '@babel/helper-hoist-variables': 7.24.7 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/parser': 7.25.3 - '@babel/types': 7.25.2 - debug: 4.3.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.25.3': dependencies: '@babel/code-frame': 7.24.7 @@ -9482,9 +9321,6 @@ snapshots: transitivePeerDependencies: - '@algolia/client-search' - '@esbuild/aix-ppc64@0.20.2': - optional: true - '@esbuild/aix-ppc64@0.21.5': optional: true @@ -9494,9 +9330,6 @@ snapshots: '@esbuild/android-arm64@0.18.20': optional: true - '@esbuild/android-arm64@0.20.2': - optional: true - '@esbuild/android-arm64@0.21.5': optional: true @@ -9506,9 +9339,6 @@ snapshots: '@esbuild/android-arm@0.18.20': optional: true - '@esbuild/android-arm@0.20.2': - optional: true - '@esbuild/android-arm@0.21.5': optional: true @@ -9518,9 +9348,6 @@ snapshots: '@esbuild/android-x64@0.18.20': optional: true - '@esbuild/android-x64@0.20.2': - optional: true - '@esbuild/android-x64@0.21.5': optional: true @@ -9530,9 +9357,6 @@ snapshots: '@esbuild/darwin-arm64@0.18.20': optional: true - '@esbuild/darwin-arm64@0.20.2': - optional: true - '@esbuild/darwin-arm64@0.21.5': optional: true @@ -9542,9 +9366,6 @@ snapshots: '@esbuild/darwin-x64@0.18.20': optional: true - '@esbuild/darwin-x64@0.20.2': - optional: true - '@esbuild/darwin-x64@0.21.5': optional: true @@ -9554,9 +9375,6 @@ snapshots: '@esbuild/freebsd-arm64@0.18.20': optional: true - '@esbuild/freebsd-arm64@0.20.2': - optional: true - '@esbuild/freebsd-arm64@0.21.5': optional: true @@ -9566,9 +9384,6 @@ snapshots: '@esbuild/freebsd-x64@0.18.20': optional: true - '@esbuild/freebsd-x64@0.20.2': - optional: true - '@esbuild/freebsd-x64@0.21.5': optional: true @@ -9578,9 +9393,6 @@ snapshots: '@esbuild/linux-arm64@0.18.20': optional: true - '@esbuild/linux-arm64@0.20.2': - optional: true - '@esbuild/linux-arm64@0.21.5': optional: true @@ -9590,9 +9402,6 @@ snapshots: '@esbuild/linux-arm@0.18.20': optional: true - '@esbuild/linux-arm@0.20.2': - optional: true - '@esbuild/linux-arm@0.21.5': optional: true @@ -9602,9 +9411,6 @@ snapshots: '@esbuild/linux-ia32@0.18.20': optional: true - '@esbuild/linux-ia32@0.20.2': - optional: true - '@esbuild/linux-ia32@0.21.5': optional: true @@ -9614,9 +9420,6 @@ snapshots: '@esbuild/linux-loong64@0.18.20': optional: true - '@esbuild/linux-loong64@0.20.2': - optional: true - '@esbuild/linux-loong64@0.21.5': optional: true @@ -9626,9 +9429,6 @@ snapshots: '@esbuild/linux-mips64el@0.18.20': optional: true - '@esbuild/linux-mips64el@0.20.2': - optional: true - '@esbuild/linux-mips64el@0.21.5': optional: true @@ -9638,9 +9438,6 @@ snapshots: '@esbuild/linux-ppc64@0.18.20': optional: true - '@esbuild/linux-ppc64@0.20.2': - optional: true - '@esbuild/linux-ppc64@0.21.5': optional: true @@ -9650,9 +9447,6 @@ snapshots: '@esbuild/linux-riscv64@0.18.20': optional: true - '@esbuild/linux-riscv64@0.20.2': - optional: true - '@esbuild/linux-riscv64@0.21.5': optional: true @@ -9662,9 +9456,6 @@ snapshots: '@esbuild/linux-s390x@0.18.20': optional: true - '@esbuild/linux-s390x@0.20.2': - optional: true - '@esbuild/linux-s390x@0.21.5': optional: true @@ -9674,9 +9465,6 @@ snapshots: '@esbuild/linux-x64@0.18.20': optional: true - '@esbuild/linux-x64@0.20.2': - optional: true - '@esbuild/linux-x64@0.21.5': optional: true @@ -9686,9 +9474,6 @@ snapshots: '@esbuild/netbsd-x64@0.18.20': optional: true - '@esbuild/netbsd-x64@0.20.2': - optional: true - '@esbuild/netbsd-x64@0.21.5': optional: true @@ -9701,9 +9486,6 @@ snapshots: '@esbuild/openbsd-x64@0.18.20': optional: true - '@esbuild/openbsd-x64@0.20.2': - optional: true - '@esbuild/openbsd-x64@0.21.5': optional: true @@ -9713,9 +9495,6 @@ snapshots: '@esbuild/sunos-x64@0.18.20': optional: true - '@esbuild/sunos-x64@0.20.2': - optional: true - '@esbuild/sunos-x64@0.21.5': optional: true @@ -9725,9 +9504,6 @@ snapshots: '@esbuild/win32-arm64@0.18.20': optional: true - '@esbuild/win32-arm64@0.20.2': - optional: true - '@esbuild/win32-arm64@0.21.5': optional: true @@ -9737,9 +9513,6 @@ snapshots: '@esbuild/win32-ia32@0.18.20': optional: true - '@esbuild/win32-ia32@0.20.2': - optional: true - '@esbuild/win32-ia32@0.21.5': optional: true @@ -9749,9 +9522,6 @@ snapshots: '@esbuild/win32-x64@0.18.20': optional: true - '@esbuild/win32-x64@0.20.2': - optional: true - '@esbuild/win32-x64@0.21.5': optional: true @@ -9922,41 +9692,41 @@ snapshots: '@kwsites/promise-deferred@1.1.1': {} - '@lancedb/vectordb-darwin-arm64@0.4.20': + '@lancedb/vectordb-darwin-arm64@0.11.0': optional: true - '@lancedb/vectordb-darwin-x64@0.4.20': + '@lancedb/vectordb-darwin-x64@0.11.0': optional: true - '@lancedb/vectordb-linux-arm64-gnu@0.4.20': + '@lancedb/vectordb-linux-arm64-gnu@0.11.0': optional: true - '@lancedb/vectordb-linux-x64-gnu@0.4.20': + '@lancedb/vectordb-linux-x64-gnu@0.11.0': optional: true - '@lancedb/vectordb-win32-x64-msvc@0.4.20': + '@lancedb/vectordb-win32-x64-msvc@0.11.0': optional: true - '@langchain/anthropic@0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))': + '@langchain/anthropic@0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))': dependencies: '@anthropic-ai/sdk': 0.27.3 - '@langchain/core': 0.3.3(openai@4.58.1(zod@3.23.8)) + '@langchain/core': 0.3.10(openai@4.67.3(zod@3.23.8)) fast-xml-parser: 4.4.1 zod: 3.23.8 zod-to-json-schema: 3.22.5(zod@3.23.8) transitivePeerDependencies: - encoding - '@langchain/community@0.3.3(@langchain/anthropic@0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))))(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))(@xenova/transformers@2.17.2)(axios@1.7.7)(cheerio@1.0.0)(ignore@6.0.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.58.1(zod@3.23.8))(vectordb@0.10.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0))(ws@8.18.0)': + '@langchain/community@0.3.5(@langchain/anthropic@0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))))(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))(@xenova/transformers@2.17.2)(axios@1.7.7)(cheerio@1.0.0)(ignore@6.0.2)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.67.3(zod@3.23.8))(vectordb@0.11.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0))(ws@8.18.0)': dependencies: - '@langchain/core': 0.3.3(openai@4.58.1(zod@3.23.8)) - '@langchain/openai': 0.3.2(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) + '@langchain/core': 0.3.10(openai@4.67.3(zod@3.23.8)) + '@langchain/openai': 0.3.7(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) binary-extensions: 2.2.0 expr-eval: 2.0.2 flat: 5.0.2 js-yaml: 4.1.0 - langchain: 0.3.2(@langchain/anthropic@0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))))(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))(axios@1.7.7)(cheerio@1.0.0)(openai@4.58.1(zod@3.23.8)) - langsmith: 0.1.58(openai@4.58.1(zod@3.23.8)) + langchain: 0.3.2(@langchain/anthropic@0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))))(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))(axios@1.7.7)(cheerio@1.0.0)(openai@4.67.3(zod@3.23.8)) + langsmith: 0.1.58(openai@4.67.3(zod@3.23.8)) uuid: 10.0.0 zod: 3.23.8 zod-to-json-schema: 3.22.5(zod@3.23.8) @@ -9966,7 +9736,7 @@ snapshots: ignore: 6.0.2 jsonwebtoken: 9.0.2 lodash: 4.17.21 - vectordb: 0.10.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0) + vectordb: 0.11.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0) ws: 8.18.0 transitivePeerDependencies: - '@langchain/anthropic' @@ -9983,13 +9753,13 @@ snapshots: - openai - peggy - '@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))': + '@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))': dependencies: ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 - js-tiktoken: 1.0.14 - langsmith: 0.1.58(openai@4.58.1(zod@3.23.8)) + js-tiktoken: 1.0.15 + langsmith: 0.1.65(openai@4.67.3(zod@3.23.8)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -9999,33 +9769,33 @@ snapshots: transitivePeerDependencies: - openai - '@langchain/langgraph-checkpoint@0.0.6(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))': + '@langchain/langgraph-checkpoint@0.0.10(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))': dependencies: - '@langchain/core': 0.3.3(openai@4.58.1(zod@3.23.8)) + '@langchain/core': 0.3.10(openai@4.67.3(zod@3.23.8)) uuid: 10.0.0 - '@langchain/langgraph@0.2.9(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))': + '@langchain/langgraph@0.2.14(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))': dependencies: - '@langchain/core': 0.3.3(openai@4.58.1(zod@3.23.8)) - '@langchain/langgraph-checkpoint': 0.0.6(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) + '@langchain/core': 0.3.10(openai@4.67.3(zod@3.23.8)) + '@langchain/langgraph-checkpoint': 0.0.10(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) double-ended-queue: 2.1.0-0 uuid: 10.0.0 zod: 3.23.8 - '@langchain/openai@0.3.2(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))': + '@langchain/openai@0.3.7(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))': dependencies: - '@langchain/core': 0.3.3(openai@4.58.1(zod@3.23.8)) - js-tiktoken: 1.0.14 - openai: 4.58.1(zod@3.23.8) + '@langchain/core': 0.3.10(openai@4.67.3(zod@3.23.8)) + js-tiktoken: 1.0.15 + openai: 4.67.3(zod@3.23.8) zod: 3.23.8 zod-to-json-schema: 3.22.5(zod@3.23.8) transitivePeerDependencies: - encoding - '@langchain/textsplitters@0.1.0(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))': + '@langchain/textsplitters@0.1.0(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))': dependencies: - '@langchain/core': 0.3.3(openai@4.58.1(zod@3.23.8)) - js-tiktoken: 1.0.14 + '@langchain/core': 0.3.10(openai@4.67.3(zod@3.23.8)) + js-tiktoken: 1.0.15 '@lexical/clipboard@0.18.0': dependencies: @@ -10311,13 +10081,13 @@ snapshots: '@radix-ui/primitive@1.1.0': {} - '@radix-ui/react-accordion@1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-accordion@1.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collapsible': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-collapsible': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-collection': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) @@ -10328,12 +10098,12 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-alert-dialog@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-alert-dialog@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-dialog': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-dialog': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) react: 19.0.0-rc-d6cb4e77-20240911 @@ -10351,12 +10121,12 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-checkbox@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-checkbox@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-previous': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10367,13 +10137,13 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-collapsible@1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-collapsible@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10408,11 +10178,11 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-context-menu@2.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-context-menu@2.2.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-menu': 2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-menu': 2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10435,6 +10205,12 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.1 + '@radix-ui/react-context@1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1)': + dependencies: + react: 19.0.0-rc-d6cb4e77-20240911 + optionalDependencies: + '@types/react': types-react@19.0.0-rc.1 + '@radix-ui/react-dialog@1.0.5(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.24.7 @@ -10458,24 +10234,24 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-dialog@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-dialog@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-focus-guards': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-dismissable-layer': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-focus-guards': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-focus-scope': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-portal': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) aria-hidden: 1.2.4 react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) - react-remove-scroll: 2.5.7(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + react-remove-scroll: 2.6.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 @@ -10500,7 +10276,7 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-dismissable-layer@1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-dismissable-layer@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10513,13 +10289,13 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-dropdown-menu@2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-dropdown-menu@2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-menu': 2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-menu': 2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) react: 19.0.0-rc-d6cb4e77-20240911 @@ -10535,7 +10311,7 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-focus-guards@1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1)': + '@radix-ui/react-focus-guards@1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1)': dependencies: react: 19.0.0-rc-d6cb4e77-20240911 optionalDependencies: @@ -10564,15 +10340,15 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-hover-card@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-hover-card@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-dismissable-layer': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-popper': 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-portal': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) react: 19.0.0-rc-d6cb4e77-20240911 @@ -10609,20 +10385,20 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-menu@2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-menu@2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-collection': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-focus-guards': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-dismissable-layer': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-focus-guards': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-focus-scope': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-popper': 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-portal': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-roving-focus': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10630,20 +10406,20 @@ snapshots: aria-hidden: 1.2.4 react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) - react-remove-scroll: 2.5.7(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + react-remove-scroll: 2.6.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-menubar@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-menubar@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-collection': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-menu': 2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-menu': 2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-roving-focus': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10653,25 +10429,25 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-popover@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-popover@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-focus-guards': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-dismissable-layer': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-focus-guards': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-focus-scope': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-popper': 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-portal': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) aria-hidden: 1.2.4 react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) - react-remove-scroll: 2.5.7(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + react-remove-scroll: 2.6.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 @@ -10704,7 +10480,7 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-portal@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-portal@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10725,7 +10501,7 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-presence@1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-presence@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10764,13 +10540,13 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-radio-group@1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-radio-group@1.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-roving-focus': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10799,14 +10575,14 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-scroll-area@1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-scroll-area@1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10816,20 +10592,20 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-select@2.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-select@2.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.0 '@radix-ui/react-collection': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-focus-guards': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-dismissable-layer': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-focus-guards': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-focus-scope': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-popper': 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-portal': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10840,18 +10616,18 @@ snapshots: aria-hidden: 1.2.4 react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) - react-remove-scroll: 2.5.7(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + react-remove-scroll: 2.6.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-slider@1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-slider@1.2.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.0 '@radix-ui/react-collection': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10879,11 +10655,11 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-switch@1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-switch@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-previous': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10894,13 +10670,13 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-tabs@1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-tabs@1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-roving-focus': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -10910,16 +10686,16 @@ snapshots: '@types/react': types-react@19.0.0-rc.1 '@types/react-dom': types-react-dom@19.0.0-rc.1 - '@radix-ui/react-tooltip@1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': + '@radix-ui/react-tooltip@1.1.3(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) - '@radix-ui/react-dismissable-layer': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.1(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + '@radix-ui/react-dismissable-layer': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-id': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-popper': 1.2.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-portal': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-portal': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) '@radix-ui/react-use-controllable-state': 1.1.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -11017,7 +10793,7 @@ snapshots: '@radix-ui/rect@1.1.0': {} - '@remix-run/router@1.19.2': {} + '@remix-run/router@1.20.0': {} '@rollup/pluginutils@5.1.0(rollup@4.21.1)': dependencies: @@ -11301,16 +11077,16 @@ snapshots: '@swc/counter': 0.1.3 optional: true - '@tanstack/query-core@5.56.2': {} + '@tanstack/query-core@5.59.10': {} - '@tanstack/react-query@5.56.2(react@19.0.0-rc-d6cb4e77-20240911)': + '@tanstack/react-query@5.59.11(react@19.0.0-rc-d6cb4e77-20240911)': dependencies: - '@tanstack/query-core': 5.56.2 + '@tanstack/query-core': 5.59.10 react: 19.0.0-rc-d6cb4e77-20240911 '@tomjs/node@2.2.3': {} - '@tomjs/vite-plugin-vscode@2.6.0(@swc/core@1.7.10)(postcss@8.4.47)(typescript@5.4.5)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0))': + '@tomjs/vite-plugin-vscode@3.0.0(@swc/core@1.7.10)(postcss@8.4.47)(typescript@5.4.5)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0))': dependencies: '@tomjs/node': 2.2.3 dayjs: 1.11.12 @@ -11458,8 +11234,6 @@ snapshots: '@types/prop-types@15.7.12': {} - '@types/qs@6.9.15': {} - '@types/react@18.3.4': dependencies: '@types/prop-types': 15.7.12 @@ -11732,7 +11506,7 @@ snapshots: - rollup - supports-color - '@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@22.5.1)(less@4.2.0))': + '@vitejs/plugin-react@4.3.2(vite@5.4.8(@types/node@22.5.1)(less@4.2.0))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) @@ -11748,43 +11522,43 @@ snapshots: vite: 5.3.5(@types/node@22.5.1)(less@4.2.0) vue: 3.4.36(typescript@5.4.5) - '@vitest/expect@2.1.1': + '@vitest/expect@2.1.2': dependencies: - '@vitest/spy': 2.1.1 - '@vitest/utils': 2.1.1 + '@vitest/spy': 2.1.2 + '@vitest/utils': 2.1.2 chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0))': + '@vitest/mocker@2.1.2(@vitest/spy@2.1.2)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0))': dependencies: - '@vitest/spy': 2.1.1 + '@vitest/spy': 2.1.2 estree-walker: 3.0.3 magic-string: 0.30.11 optionalDependencies: vite: 5.4.8(@types/node@22.5.1)(less@4.2.0) - '@vitest/pretty-format@2.1.1': + '@vitest/pretty-format@2.1.2': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.1.1': + '@vitest/runner@2.1.2': dependencies: - '@vitest/utils': 2.1.1 + '@vitest/utils': 2.1.2 pathe: 1.1.2 - '@vitest/snapshot@2.1.1': + '@vitest/snapshot@2.1.2': dependencies: - '@vitest/pretty-format': 2.1.1 + '@vitest/pretty-format': 2.1.2 magic-string: 0.30.11 pathe: 1.1.2 - '@vitest/spy@2.1.1': + '@vitest/spy@2.1.2': dependencies: tinyspy: 3.0.0 - '@vitest/utils@2.1.1': + '@vitest/utils@2.1.2': dependencies: - '@vitest/pretty-format': 2.1.1 + '@vitest/pretty-format': 2.1.2 loupe: 3.1.1 tinyrainbow: 1.2.0 @@ -11827,7 +11601,7 @@ snapshots: '@vscode/vsce-sign-win32-arm64': 2.0.2 '@vscode/vsce-sign-win32-x64': 2.0.2 - '@vscode/vsce@3.1.0': + '@vscode/vsce@3.1.1': dependencies: '@azure/identity': 4.3.0 '@vscode/vsce-sign': 2.0.4 @@ -12226,7 +12000,7 @@ snapshots: b4a@1.6.6: {} - babel-plugin-react-compiler@0.0.0-experimental-27e0f40-20241002: + babel-plugin-react-compiler@0.0.0-experimental-ad3b12a-20241011: dependencies: '@babel/generator': 7.2.0 '@babel/types': 7.25.2 @@ -12411,7 +12185,7 @@ snapshots: parse5: 7.1.2 parse5-htmlparser2-tree-adapter: 7.0.0 parse5-parser-stream: 7.1.2 - undici: 6.19.8 + undici: 6.20.0 whatwg-mimetype: 4.0.0 chevrotain-allstar@0.3.1(chevrotain@11.0.3): @@ -13288,7 +13062,7 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 - es-toolkit@1.21.0: {} + es-toolkit@1.24.0: {} es6-error@4.1.1: {} @@ -13317,32 +13091,6 @@ snapshots: '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 - esbuild@0.20.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 - esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -13404,29 +13152,29 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0): dependencies: confusing-browser-globals: 1.0.11 eslint: 8.57.0 - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) object.assign: 4.1.5 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb-typescript@18.0.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0): dependencies: '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - eslint-plugin-import - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.35.0(eslint@8.57.0))(eslint@8.57.0): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.0))(eslint-plugin-react@7.35.0(eslint@8.57.0))(eslint@8.57.0): dependencies: eslint: 8.57.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -13437,9 +13185,9 @@ snapshots: dependencies: eslint: 8.57.0 - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0)): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0)): dependencies: - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) eslint-import-resolver-node@0.3.9: dependencies: @@ -13449,47 +13197,47 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.6 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-bun-module: 1.1.0 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -13500,7 +13248,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.30.0)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.31.0)(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -13509,6 +13257,7 @@ snapshots: object.groupby: 1.0.3 object.values: 1.2.0 semver: 6.3.1 + string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.4.5) @@ -13552,7 +13301,7 @@ snapshots: '@types/eslint': 8.56.10 eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-plugin-react-compiler@0.0.0-experimental-1e98da5-20241002(eslint@8.57.0): + eslint-plugin-react-compiler@0.0.0-experimental-45ae4c3-20241011(eslint@8.57.0): dependencies: '@babel/core': 7.25.2 '@babel/parser': 7.25.3 @@ -13653,9 +13402,9 @@ snapshots: transitivePeerDependencies: - supports-color - esno@4.7.0: + esno@4.8.0: dependencies: - tsx: 4.10.5 + tsx: 4.19.1 espree@9.6.1: dependencies: @@ -13890,7 +13639,7 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@11.8.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911): + framer-motion@11.11.8(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911): dependencies: tslib: 2.6.2 optionalDependencies: @@ -14252,13 +14001,13 @@ snapshots: domhandler: 5.0.3 htmlparser2: 9.1.0 - html-react-parser@5.1.16(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1): + html-react-parser@5.1.18(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1): dependencies: domhandler: 5.0.3 html-dom-parser: 5.0.10 react: 19.0.0-rc-d6cb4e77-20240911 react-property: 2.0.2 - style-to-js: 1.1.14 + style-to-js: 1.1.16 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 @@ -14359,6 +14108,8 @@ snapshots: inline-style-parser@0.2.3: {} + inline-style-parser@0.2.4: {} + inline-style-prefixer@7.0.1: dependencies: css-in-js-utils: 3.1.0 @@ -14602,11 +14353,13 @@ snapshots: jiti@2.0.0-beta.2: {} + jiti@2.3.3: {} + joycon@3.1.1: {} js-cookie@2.2.1: {} - js-tiktoken@1.0.14: + js-tiktoken@1.0.15: dependencies: base64-js: 1.5.1 @@ -14710,7 +14463,7 @@ snapshots: khroma@2.1.0: {} - knip@5.30.5(@types/node@22.5.1)(typescript@5.4.5): + knip@5.33.3(@types/node@22.5.1)(typescript@5.4.5): dependencies: '@nodelib/fs.walk': 1.2.8 '@snyk/github-codeowners': 1.1.0 @@ -14718,7 +14471,7 @@ snapshots: easy-table: 1.2.0 enhanced-resolve: 5.17.1 fast-glob: 3.3.2 - jiti: 1.21.6 + jiti: 2.3.3 js-yaml: 4.1.0 minimist: 1.2.8 picocolors: 1.1.0 @@ -14733,15 +14486,15 @@ snapshots: kolorist@1.8.0: {} - langchain@0.3.2(@langchain/anthropic@0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))))(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8)))(axios@1.7.7)(cheerio@1.0.0)(openai@4.58.1(zod@3.23.8)): + langchain@0.3.2(@langchain/anthropic@0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))))(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8)))(axios@1.7.7)(cheerio@1.0.0)(openai@4.67.3(zod@3.23.8)): dependencies: - '@langchain/core': 0.3.3(openai@4.58.1(zod@3.23.8)) - '@langchain/openai': 0.3.2(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) - '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) - js-tiktoken: 1.0.14 + '@langchain/core': 0.3.10(openai@4.67.3(zod@3.23.8)) + '@langchain/openai': 0.3.7(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) + '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) + js-tiktoken: 1.0.15 js-yaml: 4.1.0 jsonpointer: 5.0.1 - langsmith: 0.1.58(openai@4.58.1(zod@3.23.8)) + langsmith: 0.1.58(openai@4.67.3(zod@3.23.8)) openapi-types: 12.1.3 p-retry: 4.6.2 uuid: 10.0.0 @@ -14749,7 +14502,7 @@ snapshots: zod: 3.23.8 zod-to-json-schema: 3.22.5(zod@3.23.8) optionalDependencies: - '@langchain/anthropic': 0.3.3(@langchain/core@0.3.3(openai@4.58.1(zod@3.23.8))) + '@langchain/anthropic': 0.3.3(@langchain/core@0.3.10(openai@4.67.3(zod@3.23.8))) axios: 1.7.7 cheerio: 1.0.0 transitivePeerDependencies: @@ -14764,7 +14517,18 @@ snapshots: vscode-languageserver-textdocument: 1.0.11 vscode-uri: 3.0.8 - langsmith@0.1.58(openai@4.58.1(zod@3.23.8)): + langsmith@0.1.58(openai@4.67.3(zod@3.23.8)): + dependencies: + '@types/uuid': 10.0.0 + commander: 10.0.1 + p-queue: 6.6.2 + p-retry: 4.6.2 + semver: 7.6.3 + uuid: 10.0.0 + optionalDependencies: + openai: 4.67.3(zod@3.23.8) + + langsmith@0.1.65(openai@4.67.3(zod@3.23.8)): dependencies: '@types/uuid': 10.0.0 commander: 10.0.1 @@ -14773,7 +14537,7 @@ snapshots: semver: 7.6.3 uuid: 10.0.0 optionalDependencies: - openai: 4.58.1(zod@3.23.8) + openai: 4.67.3(zod@3.23.8) language-subtag-registry@0.3.23: {} @@ -15168,7 +14932,7 @@ snapshots: merge@2.1.1: {} - mermaid@11.2.1: + mermaid@11.3.0: dependencies: '@braintree/sanitize-url': 7.1.0 '@iconify/utils': 2.1.33 @@ -15646,17 +15410,15 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openai@4.58.1(zod@3.23.8): + openai@4.67.3(zod@3.23.8): dependencies: '@types/node': 18.19.39 '@types/node-fetch': 2.6.11 - '@types/qs': 6.9.15 abort-controller: 3.0.0 agentkeepalive: 4.5.0 form-data-encoder: 1.7.2 formdata-node: 4.4.1 node-fetch: 2.7.0 - qs: 6.11.2 optionalDependencies: zod: 3.23.8 transitivePeerDependencies: @@ -15857,7 +15619,7 @@ snapshots: platform@1.3.6: {} - pnpm@9.11.0: {} + pnpm@9.12.1: {} points-on-curve@0.2.0: {} @@ -15887,13 +15649,13 @@ snapshots: optionalDependencies: postcss: 8.4.47 - postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.47)(tsx@4.16.3)(yaml@2.5.0): + postcss-load-config@6.0.1(jiti@2.3.3)(postcss@8.4.47)(tsx@4.19.1)(yaml@2.5.0): dependencies: lilconfig: 3.1.2 optionalDependencies: - jiti: 1.21.6 + jiti: 2.3.3 postcss: 8.4.47 - tsx: 4.16.3 + tsx: 4.19.1 yaml: 2.5.0 postcss-nested@6.2.0(postcss@8.4.47): @@ -16068,7 +15830,7 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - react-remove-scroll@2.5.7(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1): + react-remove-scroll@2.6.0(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1): dependencies: react: 19.0.0-rc-d6cb4e77-20240911 react-remove-scroll-bar: 2.3.6(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) @@ -16079,27 +15841,27 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - react-resizable-panels@2.1.3(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911): + react-resizable-panels@2.1.4(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911): dependencies: react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) - react-router-dom@6.26.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911): + react-router-dom@6.27.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911): dependencies: - '@remix-run/router': 1.19.2 + '@remix-run/router': 1.20.0 react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) - react-router: 6.26.2(react@19.0.0-rc-d6cb4e77-20240911) + react-router: 6.27.0(react@19.0.0-rc-d6cb4e77-20240911) - react-router@6.26.2(react@19.0.0-rc-d6cb4e77-20240911): + react-router@6.27.0(react@19.0.0-rc-d6cb4e77-20240911): dependencies: - '@remix-run/router': 1.19.2 + '@remix-run/router': 1.20.0 react: 19.0.0-rc-d6cb4e77-20240911 react-shiki@0.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1): dependencies: clsx: 2.1.1 - html-react-parser: 5.1.16(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) + html-react-parser: 5.1.18(react@19.0.0-rc-d6cb4e77-20240911)(types-react@19.0.0-rc.1) react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) shiki: 1.20.0 @@ -16751,17 +16513,17 @@ snapshots: strnum@1.0.5: {} - style-to-js@1.1.14: + style-to-js@1.1.16: dependencies: - style-to-object: 1.0.7 + style-to-object: 1.0.8 style-to-object@1.0.6: dependencies: inline-style-parser: 0.2.3 - style-to-object@1.0.7: + style-to-object@1.0.8: dependencies: - inline-style-parser: 0.2.3 + inline-style-parser: 0.2.4 stylis@4.3.4: {} @@ -16815,7 +16577,7 @@ snapshots: typical: 7.2.0 wordwrapjs: 5.1.0 - tailwind-merge@2.5.2: {} + tailwind-merge@2.5.3: {} tailwindcss-animate@1.0.7(tailwindcss@3.4.13): dependencies: @@ -16998,7 +16760,7 @@ snapshots: - supports-color - ts-node - tsup@8.3.0(@swc/core@1.7.10)(jiti@1.21.6)(postcss@8.4.47)(tsx@4.16.3)(typescript@5.4.5)(yaml@2.5.0): + tsup@8.3.0(@swc/core@1.7.10)(jiti@2.3.3)(postcss@8.4.47)(tsx@4.19.1)(typescript@5.4.5)(yaml@2.5.0): dependencies: bundle-require: 5.0.0(esbuild@0.23.0) cac: 6.7.14 @@ -17009,7 +16771,7 @@ snapshots: execa: 5.1.1 joycon: 3.1.1 picocolors: 1.0.1 - postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.47)(tsx@4.16.3)(yaml@2.5.0) + postcss-load-config: 6.0.1(jiti@2.3.3)(postcss@8.4.47)(tsx@4.19.1)(yaml@2.5.0) resolve-from: 5.0.0 rollup: 4.21.1 source-map: 0.8.0-beta.0 @@ -17026,16 +16788,16 @@ snapshots: - tsx - yaml - tsx@4.10.5: + tsx@4.16.3: dependencies: - esbuild: 0.20.2 + esbuild: 0.21.5 get-tsconfig: 4.7.5 optionalDependencies: fsevents: 2.3.3 - tsx@4.16.3: + tsx@4.19.1: dependencies: - esbuild: 0.21.5 + esbuild: 0.23.0 get-tsconfig: 4.7.5 optionalDependencies: fsevents: 2.3.3 @@ -17139,7 +16901,7 @@ snapshots: undici-types@6.19.8: {} - undici@6.19.8: {} + undici@6.20.0: {} unicorn-magic@0.1.0: {} @@ -17279,25 +17041,25 @@ snapshots: vaul@1.0.0(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1): dependencies: - '@radix-ui/react-dialog': 1.1.1(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) + '@radix-ui/react-dialog': 1.1.2(react-dom@19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911))(react@19.0.0-rc-d6cb4e77-20240911)(types-react-dom@19.0.0-rc.1)(types-react@19.0.0-rc.1) react: 19.0.0-rc-d6cb4e77-20240911 react-dom: 19.0.0-rc-d6cb4e77-20240911(react@19.0.0-rc-d6cb4e77-20240911) transitivePeerDependencies: - '@types/react' - '@types/react-dom' - vectordb@0.10.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0): + vectordb@0.11.0(@apache-arrow/ts@14.0.2)(apache-arrow@17.0.0): dependencies: '@apache-arrow/ts': 14.0.2 '@neon-rs/load': 0.0.74 apache-arrow: 17.0.0 axios: 1.7.7 optionalDependencies: - '@lancedb/vectordb-darwin-arm64': 0.4.20 - '@lancedb/vectordb-darwin-x64': 0.4.20 - '@lancedb/vectordb-linux-arm64-gnu': 0.4.20 - '@lancedb/vectordb-linux-x64-gnu': 0.4.20 - '@lancedb/vectordb-win32-x64-msvc': 0.4.20 + '@lancedb/vectordb-darwin-arm64': 0.11.0 + '@lancedb/vectordb-darwin-x64': 0.11.0 + '@lancedb/vectordb-linux-arm64-gnu': 0.11.0 + '@lancedb/vectordb-linux-x64-gnu': 0.11.0 + '@lancedb/vectordb-win32-x64-msvc': 0.11.0 transitivePeerDependencies: - debug @@ -17316,7 +17078,7 @@ snapshots: '@types/unist': 3.0.2 vfile-message: 4.0.2 - vite-node@2.1.1(@types/node@22.5.1)(less@4.2.0): + vite-node@2.1.2(@types/node@22.5.1)(less@4.2.0): dependencies: cac: 6.7.14 debug: 4.3.6 @@ -17333,7 +17095,7 @@ snapshots: - supports-color - terser - vite-plugin-pages@0.32.3(@vue/compiler-sfc@3.4.36)(react-router@6.26.2(react@19.0.0-rc-d6cb4e77-20240911))(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)): + vite-plugin-pages@0.32.3(@vue/compiler-sfc@3.4.36)(react-router@6.27.0(react@19.0.0-rc-d6cb4e77-20240911))(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)): dependencies: '@types/debug': 4.1.12 debug: 4.3.6 @@ -17347,7 +17109,7 @@ snapshots: yaml: 2.5.0 optionalDependencies: '@vue/compiler-sfc': 3.4.36 - react-router: 6.26.2(react@19.0.0-rc-d6cb4e77-20240911) + react-router: 6.27.0(react@19.0.0-rc-d6cb4e77-20240911) transitivePeerDependencies: - supports-color @@ -17440,15 +17202,15 @@ snapshots: - typescript - universal-cookie - vitest@2.1.1(@types/node@22.5.1)(less@4.2.0): + vitest@2.1.2(@types/node@22.5.1)(less@4.2.0): dependencies: - '@vitest/expect': 2.1.1 - '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) - '@vitest/pretty-format': 2.1.1 - '@vitest/runner': 2.1.1 - '@vitest/snapshot': 2.1.1 - '@vitest/spy': 2.1.1 - '@vitest/utils': 2.1.1 + '@vitest/expect': 2.1.2 + '@vitest/mocker': 2.1.2(@vitest/spy@2.1.2)(vite@5.4.8(@types/node@22.5.1)(less@4.2.0)) + '@vitest/pretty-format': 2.1.2 + '@vitest/runner': 2.1.2 + '@vitest/snapshot': 2.1.2 + '@vitest/spy': 2.1.2 + '@vitest/utils': 2.1.2 chai: 5.1.1 debug: 4.3.6 magic-string: 0.30.11 @@ -17459,7 +17221,7 @@ snapshots: tinypool: 1.0.0 tinyrainbow: 1.2.0 vite: 5.4.8(@types/node@22.5.1)(less@4.2.0) - vite-node: 2.1.1(@types/node@22.5.1)(less@4.2.0) + vite-node: 2.1.2(@types/node@22.5.1)(less@4.2.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.5.1 @@ -17523,7 +17285,7 @@ snapshots: web-streams-polyfill@4.0.0-beta.3: {} - web-tree-sitter@0.23.0: {} + web-tree-sitter@0.24.3: {} webidl-conversions@3.0.1: {} diff --git a/src/extension/ai/embeddings/embedding-manager.ts b/src/extension/ai/embeddings/embedding-manager.ts index 9bcd45d..107ebe7 100644 --- a/src/extension/ai/embeddings/embedding-manager.ts +++ b/src/extension/ai/embeddings/embedding-manager.ts @@ -25,8 +25,6 @@ export const embeddingModels = [ } ] as const satisfies BaseEmbeddingModelInfo[] -export type EmbeddingModelType = (typeof embeddingModels)[number]['type'] - export class EmbeddingManager { private static instance: EmbeddingManager diff --git a/src/extension/constants.ts b/src/extension/constants.ts index dff4604..77b06fb 100644 --- a/src/extension/constants.ts +++ b/src/extension/constants.ts @@ -1,5 +1,7 @@ export const AbortError = new Error('AbortError') +export const AI_SUPPORT_IMG_EXT = ['jpg', 'jpeg', 'png'] + export const DEFAULT_IGNORE_FILETYPES = [ '**/*.DS_Store', '**/*-lock.json', @@ -70,6 +72,10 @@ export const DEFAULT_IGNORE_FILETYPES = [ // "**/*.prompt", // can be incredibly confusing for the LLM to have another set of instructions injected into the prompt ] +export const IGNORE_FILETYPES_WITHOUT_IMG = DEFAULT_IGNORE_FILETYPES.filter( + filetype => !AI_SUPPORT_IMG_EXT.some(ext => filetype.endsWith(ext)) +) + export const PRE_INDEX_DOCS = [ { title: 'Jinja', diff --git a/src/extension/file-utils/ignore-patterns.ts b/src/extension/file-utils/ignore-patterns.ts index ec989dc..56bf10c 100644 --- a/src/extension/file-utils/ignore-patterns.ts +++ b/src/extension/file-utils/ignore-patterns.ts @@ -61,6 +61,8 @@ export const createShouldIgnore = async ( const relativePath = path.relative(workspacePath, fullFilePath) const unixRelativePath = relativePath.replace(/\\/g, '/') + if (!unixRelativePath) return true + if (ig && ig.ignores(unixRelativePath)) { return true } diff --git a/src/extension/registers/index.ts b/src/extension/registers/index.ts index 7499046..bd8da7d 100644 --- a/src/extension/registers/index.ts +++ b/src/extension/registers/index.ts @@ -4,6 +4,7 @@ import { BaseRegister } from './base-register' import { CodebaseWatcherRegister } from './codebase-watcher-register' import { ModelRegister } from './model-register' import { RegisterManager } from './register-manager' +import { ServerPluginRegister } from './server-plugin-register' import { SystemSetupRegister } from './system-setup-register' import { TmpFileActionRegister } from './tmp-file-action-register' import { WebviewRegister } from './webview-register' @@ -14,9 +15,10 @@ export const setupRegisters = async (registerManager: RegisterManager) => { TmpFileActionRegister, AideKeyUsageStatusBarRegister, AutoOpenCorrespondingFilesRegister, - WebviewRegister, ModelRegister, - CodebaseWatcherRegister + CodebaseWatcherRegister, + ServerPluginRegister, + WebviewRegister ] satisfies (typeof BaseRegister)[] for await (const Register of Registers) { diff --git a/src/extension/registers/server-plugin-register.ts b/src/extension/registers/server-plugin-register.ts new file mode 100644 index 0000000..ace1441 --- /dev/null +++ b/src/extension/registers/server-plugin-register.ts @@ -0,0 +1,34 @@ +import type { CommandManager } from '@extension/commands/command-manager' +import { createServerPlugins } from '@shared/plugins/base/server/create-server-plugins' +import { ServerPluginRegistry } from '@shared/plugins/base/server/server-plugin-registry' +import * as vscode from 'vscode' + +import { BaseRegister } from './base-register' +import type { RegisterManager } from './register-manager' + +export class ServerPluginRegister extends BaseRegister { + serverPluginRegistry!: ServerPluginRegistry + + constructor( + protected context: vscode.ExtensionContext, + protected registerManager: RegisterManager, + protected commandManager: CommandManager + ) { + super(context, registerManager, commandManager) + } + + async register(): Promise { + const serverPluginRegistry = new ServerPluginRegistry() + const plugins = createServerPlugins() + + await Promise.allSettled( + plugins.map(plugin => serverPluginRegistry.loadPlugin(plugin)) + ) + + this.serverPluginRegistry = serverPluginRegistry + } + + async dispose(): Promise { + await this.serverPluginRegistry.unloadAllPlugins() + } +} diff --git a/src/extension/webview-api/chat-context-processor/index.ts b/src/extension/webview-api/chat-context-processor/index.ts index 709a36f..3f5b5b7 100644 --- a/src/extension/webview-api/chat-context-processor/index.ts +++ b/src/extension/webview-api/chat-context-processor/index.ts @@ -1,16 +1,19 @@ import type { CommandManager } from '@extension/commands/command-manager' import type { RegisterManager } from '@extension/registers/register-manager' +import { + ChatContextType, + type ChatContext, + type Conversation +} from '@shared/types/chat-context' import { AutoTaskStrategy } from './strategies/auto-task-strategy' -import type { BaseStrategy } from './strategies/base-strategy' +import type { + BaseStrategy, + BaseStrategyOptions +} from './strategies/base-strategy' import { ChatStrategy } from './strategies/chat-strategy' import { ComposerStrategy } from './strategies/composer-strategy' import { V0Strategy } from './strategies/v0-strategy' -import { - ChatContextType, - type ChatContext, - type Conversation -} from './types/chat-context' export class ChatContextProcessor { private strategyMap: Map @@ -26,17 +29,16 @@ export class ChatContextProcessor { this.registerManager = registerManager this.commandManager = commandManager + const baseStrategyOptions: BaseStrategyOptions = { + registerManager, + commandManager + } + this.strategyMap = new Map([ - [ChatContextType.Chat, new ChatStrategy(registerManager, commandManager)], - [ - ChatContextType.Composer, - new ComposerStrategy(registerManager, commandManager) - ], - [ChatContextType.V0, new V0Strategy(registerManager, commandManager)], - [ - ChatContextType.AutoTask, - new AutoTaskStrategy(registerManager, commandManager) - ] + [ChatContextType.Chat, new ChatStrategy(baseStrategyOptions)], + [ChatContextType.Composer, new ComposerStrategy(baseStrategyOptions)], + [ChatContextType.V0, new V0Strategy(baseStrategyOptions)], + [ChatContextType.AutoTask, new AutoTaskStrategy(baseStrategyOptions)] ]) } diff --git a/src/extension/webview-api/chat-context-processor/strategies/base-strategy.ts b/src/extension/webview-api/chat-context-processor/strategies/base-strategy.ts index 12ef524..13bd170 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/base-strategy.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/base-strategy.ts @@ -1,19 +1,20 @@ import type { CommandManager } from '@extension/commands/command-manager' import type { RegisterManager } from '@extension/registers/register-manager' +import type { ChatContext, Conversation } from '@shared/types/chat-context' -import type { ChatContext, Conversation } from '../types/chat-context' +export interface BaseStrategyOptions { + registerManager: RegisterManager + commandManager: CommandManager +} export abstract class BaseStrategy { protected registerManager: RegisterManager protected commandManager: CommandManager - constructor( - registerManager: RegisterManager, - commandManager: CommandManager - ) { - this.registerManager = registerManager - this.commandManager = commandManager + constructor(options: BaseStrategyOptions) { + this.registerManager = options.registerManager + this.commandManager = options.commandManager } abstract getAnswers( diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/chat-workflow.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/chat-workflow.ts index ed0fe27..e269d8e 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/chat-workflow.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/chat-workflow.ts @@ -1,43 +1,44 @@ +import { ServerPluginRegister } from '@extension/registers/server-plugin-register' import { END, START, StateGraph } from '@langchain/langgraph' import { combineNode } from '../../utils/combine-node' -import { agentNode } from './nodes/agent-node' -import { codebaseSearchNode } from './nodes/codebase-search-node' -import { docRetrieverNode } from './nodes/doc-retriever-node' -import { generateNode } from './nodes/generate-node' +import type { BaseStrategyOptions } from '../base-strategy' +import { createAgentNode } from './nodes/agent-node' +import { createGenerateNode } from './nodes/generate-node' import { ChatGraphNodeName, chatGraphState, type ChatGraphState } from './nodes/state' -import { webSearchNode } from './nodes/web-search-node' -import { webVisitNode } from './nodes/web-visit-node' const createSmartRoute = (nextNodeName: ChatGraphNodeName) => (state: ChatGraphState) => state.shouldContinue ? nextNodeName : END -const chatWorkflow = new StateGraph(chatGraphState) - .addNode(ChatGraphNodeName.Agent, agentNode) - .addNode( - ChatGraphNodeName.Tools, - combineNode( - [codebaseSearchNode, docRetrieverNode, webSearchNode, webVisitNode], - chatGraphState - ) - ) - .addNode(ChatGraphNodeName.Generate, generateNode) +export const createChatWorkflow = async (options: BaseStrategyOptions) => { + const chatStrategyProvider = options.registerManager + .getRegister(ServerPluginRegister) + ?.serverPluginRegistry?.providerManagers.chatStrategy.mergeAll() + + const toolNodes = + (await chatStrategyProvider?.buildLanggraphToolNodes?.(options)) || [] + + const chatWorkflow = new StateGraph(chatGraphState) + .addNode(ChatGraphNodeName.Agent, createAgentNode(options)) + .addNode(ChatGraphNodeName.Tools, combineNode(toolNodes, chatGraphState)) + .addNode(ChatGraphNodeName.Generate, createGenerateNode(options)) -chatWorkflow - .addConditionalEdges(START, createSmartRoute(ChatGraphNodeName.Agent)) - .addConditionalEdges( - ChatGraphNodeName.Agent, - createSmartRoute(ChatGraphNodeName.Tools) - ) - .addConditionalEdges( - ChatGraphNodeName.Tools, - createSmartRoute(ChatGraphNodeName.Generate) - ) - .addEdge(ChatGraphNodeName.Generate, END) + chatWorkflow + .addConditionalEdges(START, createSmartRoute(ChatGraphNodeName.Agent)) + .addConditionalEdges( + ChatGraphNodeName.Agent, + createSmartRoute(ChatGraphNodeName.Tools) + ) + .addConditionalEdges( + ChatGraphNodeName.Tools, + createSmartRoute(ChatGraphNodeName.Generate) + ) + .addEdge(ChatGraphNodeName.Generate, END) -export { chatWorkflow } + return chatWorkflow +} diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/index.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/index.ts index 4458892..a4b3c85 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/index.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/index.ts @@ -1,15 +1,29 @@ -import type { - ChatContext, - Conversation -} from '@extension/webview-api/chat-context-processor/types/chat-context' +import type { ChatContext, Conversation } from '@shared/types/chat-context' +import { UnPromise } from '@shared/types/common' import { BaseStrategy } from '../base-strategy' -import { chatWorkflow } from './chat-workflow' +import { createChatWorkflow } from './chat-workflow' export class ChatStrategy extends BaseStrategy { + private _chatWorkflow: UnPromise< + ReturnType + > | null = null + + private getChatWorkflow = async () => { + if (!this._chatWorkflow) { + this._chatWorkflow = await createChatWorkflow({ + registerManager: this.registerManager, + commandManager: this.commandManager + }) + } + + return this._chatWorkflow + } + async *getAnswers( chatContext: ChatContext ): AsyncGenerator { + const chatWorkflow = await this.getChatWorkflow() const graph = chatWorkflow.compile() const stream = await graph.stream({ diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/chat-messages-constructor.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/chat-messages-constructor.ts index b9dd63a..fea153d 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/chat-messages-constructor.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/chat-messages-constructor.ts @@ -1,51 +1,54 @@ -import type { ChatContext } from '@extension/webview-api/chat-context-processor/types/chat-context' -import type { LangchainMessage } from '@extension/webview-api/chat-context-processor/types/langchain-message' +import type { CommandManager } from '@extension/commands/command-manager' +import type { RegisterManager } from '@extension/registers/register-manager' +import { ServerPluginRegister } from '@extension/registers/server-plugin-register' import { HumanMessage, SystemMessage } from '@langchain/core/messages' +import type { ChatContext } from '@shared/types/chat-context' +import type { LangchainMessage } from '@shared/types/chat-context/langchain-message' import { settledPromiseResults } from '@shared/utils/common' -import { CHAT_WITH_FILE_SYSTEM_PROMPT, COMMON_SYSTEM_PROMPT } from './constants' +import type { BaseStrategyOptions } from '../../base-strategy' import { ConversationMessageConstructor } from './conversation-message-constructor' +interface ChatMessagesConstructorOptions extends BaseStrategyOptions { + chatContext: ChatContext +} + export class ChatMessagesConstructor { private chatContext: ChatContext - constructor(chatContext: ChatContext) { - this.chatContext = chatContext + private registerManager: RegisterManager + + private commandManager: CommandManager + + private getChatStrategyProvider() { + return this.registerManager + .getRegister(ServerPluginRegister) + ?.serverPluginRegistry?.providerManagers.chatStrategy.mergeAll() + } + + constructor(options: ChatMessagesConstructorOptions) { + this.chatContext = options.chatContext + this.registerManager = options.registerManager + this.commandManager = options.commandManager } async constructMessages(): Promise { - const hasAttachedFiles = this.checkForAttachedFiles() - const systemMessage = this.createSystemMessage(hasAttachedFiles) + const systemMessage = await this.createSystemMessage() const instructionMessage = this.createCustomInstructionMessage() - const conversationMessages = - await this.buildConversationMessages(hasAttachedFiles) + const conversationMessages = await this.buildConversationMessages() return [systemMessage, instructionMessage, ...conversationMessages].filter( Boolean ) as LangchainMessage[] } - private checkForAttachedFiles(): boolean { - return this.chatContext.conversations.some(conversation => { - const { selectedFiles = [], selectedFolders = [] } = - conversation.attachments?.fileContext || {} - const { relevantCodeSnippets = [] } = - conversation.attachments?.codebaseContext || {} - - return ( - selectedFiles.length > 0 || - selectedFolders.length > 0 || - relevantCodeSnippets.length > 0 - ) - }) - } - - private createSystemMessage(hasAttachedFiles: boolean): SystemMessage { - const content = hasAttachedFiles - ? CHAT_WITH_FILE_SYSTEM_PROMPT - : COMMON_SYSTEM_PROMPT + private async createSystemMessage(): Promise { + const chatStrategyProvider = this.getChatStrategyProvider() + const content = await chatStrategyProvider?.buildSystemMessagePrompt?.( + this.chatContext + ) - return new SystemMessage({ content }) + return content ? new SystemMessage({ content }) : null } private createCustomInstructionMessage(): HumanMessage | null { @@ -62,14 +65,18 @@ ${explicitContext} }) } - private async buildConversationMessages( - hasAttachedFiles: boolean - ): Promise { + private async buildConversationMessages(): Promise { + const chatStrategyProvider = this.getChatStrategyProvider() + + if (!chatStrategyProvider) + throw new Error('Chat strategy provider not found') + const messagePromises = this.chatContext.conversations.map(conversation => - new ConversationMessageConstructor( + new ConversationMessageConstructor({ + chatContext: this.chatContext, conversation, - hasAttachedFiles - ).buildMessages() + chatStrategyProvider + }).buildMessages() ) const messageArrays = await settledPromiseResults(messagePromises) return messageArrays.flat() diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/constants.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/constants.ts deleted file mode 100644 index f945002..0000000 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/constants.ts +++ /dev/null @@ -1,89 +0,0 @@ -export const COMMON_SYSTEM_PROMPT = ` -You are an intelligent programmer, powered by GPT-4. You are happy to help answer any questions that the user has (usually they will be about coding). You will be given the context of the code in their file(s) and potentially relevant blocks of code. - -1. Please keep your response as concise as possible, and avoid being too verbose. - -2. Do not lie or make up facts. - -3. If a user messages you in a foreign language, please respond in that language. - -4. Format your response in markdown. - -5. When referencing code blocks in your answer, keep the following guidelines in mind: - - a. Never include line numbers in the output code. - - b. When outputting new code blocks, please specify the language ID after the initial backticks: -\`\`\`python -{{ code }} -\`\`\` - - c. When outputting code blocks for an existing file, include the file path after the initial backticks: -\`\`\`python:src/backend/main.py -{{ code }} -\`\`\` - - d. When referencing a code block the user gives you, only reference the start and end line numbers of the relevant code: -\`\`\`typescript:app/components/Todo.tsx -startLine: 2 -endLine: 30 -\`\`\` -` - -export const CHAT_WITH_FILE_SYSTEM_PROMPT = ` -You are an intelligent programmer, powered by GPT-4o. You are happy to help answer any questions that the user has (usually they will be about coding). - -1. Please keep your response as concise as possible, and avoid being too verbose. - -2. When the user is asking for edits to their code, please output a simplified version of the code block that highlights the changes necessary and adds comments to indicate where unchanged code has been skipped. For example: -\`\`\`file_path -// ... existing code ... -{{ edit_1 }} -// ... existing code ... -{{ edit_2 }} -// ... existing code ... -\`\`\` -The user can see the entire file, so they prefer to only read the updates to the code. Often this will mean that the start/end of the file will be skipped, but that's okay! Rewrite the entire file only if specifically requested. Always provide a brief explanation of the updates, unless the user specifically requests only the code. - -3. Do not lie or make up facts. - -4. If a user messages you in a foreign language, please respond in that language. - -5. Format your response in markdown. - -6. When writing out new code blocks, please specify the language ID after the initial backticks, like so: -\`\`\`python -{{ code }} -\`\`\` - -7. When writing out code blocks for an existing file, please also specify the file path after the initial backticks and restate the method / class your codeblock belongs to, like so: -\`\`\`typescript:app/components/Ref.tsx -function AIChatHistory() { - ... - {{ code }} - ... -} -\`\`\` -` - -export const FILE_CONTEXT_PROMPT = ` -If you need to reference any of the code blocks I gave you, only output the start and end line numbers. For example: -\`\`\`typescript:app/components/Todo.tsx -startLine: 200 -endLine: 310 -\`\`\` - -If you are writing code, do not include the "line_number|" before each line of code. -` - -export const CONTENT_SEPARATOR = ` - - -------- - - - -------- - - -` diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/conversation-message-constructor.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/conversation-message-constructor.ts index 40e9162..44c662c 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/conversation-message-constructor.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/conversation-message-constructor.ts @@ -1,48 +1,30 @@ -import { - traverseFileOrFolders, - type FileInfo -} from '@extension/file-utils/traverse-fs' -import { logger } from '@extension/logger' -import { getWorkspaceFolder } from '@extension/utils' -import type { - Conversation, - GitDiff -} from '@extension/webview-api/chat-context-processor/types/chat-context' +import { MessageBuilder } from '@extension/webview-api/chat-context-processor/utils/message-builder' +import { HumanMessage } from '@langchain/core/messages' +import type { ChatStrategyProvider } from '@shared/plugins/base/server/create-provider-manager' +import type { ChatContext } from '@shared/types/chat-context' +import type { Conversation } from '@shared/types/chat-context/conversation' import type { LangchainMessage, LangchainMessageContents -} from '@extension/webview-api/chat-context-processor/types/langchain-message' -import { formatCodeSnippet } from '@extension/webview-api/chat-context-processor/utils/code-snippet-formatter' -import { getFileContent } from '@extension/webview-api/chat-context-processor/utils/get-file-content' -import { mergeCodeSnippets } from '@extension/webview-api/chat-context-processor/utils/merge-code-snippets' -import { MessageBuilder } from '@extension/webview-api/chat-context-processor/utils/message-builder' -import { HumanMessage } from '@langchain/core/messages' +} from '@shared/types/chat-context/langchain-message' -import { CONTENT_SEPARATOR, FILE_CONTEXT_PROMPT } from './constants' - -interface BuildFilePromptsResult { - selectedFilesPrompt: string - currentFilesPrompt: string +interface ConversationMessageConstructorOptions { + chatContext: ChatContext + conversation: Conversation + chatStrategyProvider: ChatStrategyProvider } export class ConversationMessageConstructor { - private conversation: Conversation - - private hasAttachedFiles: boolean - - private _buildFilePromptsResult!: BuildFilePromptsResult + private chatContext: ChatContext - private async getBuildFilePromptsResult(): Promise { - if (!this._buildFilePromptsResult) { - this._buildFilePromptsResult = await this.buildFilePrompts() - } + private conversation: Conversation - return this._buildFilePromptsResult - } + private chatStrategyProvider: ChatStrategyProvider - constructor(conversation: Conversation, hasAttachedFiles: boolean) { - this.conversation = conversation - this.hasAttachedFiles = hasAttachedFiles + constructor(options: ConversationMessageConstructorOptions) { + this.chatContext = options.chatContext + this.conversation = options.conversation + this.chatStrategyProvider = options.chatStrategyProvider } async buildMessages(): Promise { @@ -56,55 +38,52 @@ export class ConversationMessageConstructor { } const contextMessage = await this.buildContextMessage() - const userMessage = await this.buildUserMessage() + const humanMessage = await this.buildHumanMessage() - return [contextMessage, userMessage].filter(Boolean) as LangchainMessage[] + return [contextMessage, humanMessage].filter(Boolean) as LangchainMessage[] } private async buildContextMessage(): Promise { - const codeSnippetsPrompt = await this.buildCodeSnippetsPrompt() - - logger.dev.verbose('codeSnippetsPrompt', codeSnippetsPrompt) - - const { currentFilesPrompt } = await this.getBuildFilePromptsResult() - const relevantDocsPrompt = this.buildRelevantDocsPrompt() - const gitCommitsPrompt = this.buildGitCommitPrompt() + const prompt = + (await this.chatStrategyProvider.buildContextMessagePrompt?.( + this.conversation, + this.chatContext + )) || '' - const _gitDiffsPrompt = this.buildGitDiffsPrompt() - const gitDiffsPrompt = _gitDiffsPrompt - ? `# Git Diffs\n\n${_gitDiffsPrompt}` - : '' - - const prompts = [ - codeSnippetsPrompt, - currentFilesPrompt, - relevantDocsPrompt, - gitCommitsPrompt, - gitDiffsPrompt - ].filter(Boolean) - - if (!prompts.length) { - return null - } + if (!prompt.trim()) return null return new HumanMessage({ content: ` # Inputs -${prompts.join('\n\n')} +${prompt} ` }) } - private async buildUserMessage(): Promise { - const { selectedFilesPrompt } = await this.getBuildFilePromptsResult() - const codeChunksPrompt = this.buildCodeChunksPrompt() - const fileContextPrompt = this.hasAttachedFiles ? FILE_CONTEXT_PROMPT : '' + private async buildHumanMessage(): Promise { + const prompt = + (await this.chatStrategyProvider.buildHumanMessagePrompt?.( + this.conversation, + this.chatContext + )) || '' + + const endPrompt = + (await this.chatStrategyProvider.buildHumanMessageEndPrompt?.( + this.conversation, + this.chatContext + )) || '' + + const imageUrls = + (await this.chatStrategyProvider.buildHumanMessageImageUrls?.( + this.conversation, + this.chatContext + )) || [] const imageContents: LangchainMessageContents = - this.conversation.attachments?.fileContext.selectedImages.map(image => ({ + imageUrls.map(url => ({ type: 'image_url', - image_url: image.url + image_url: url })) || [] let isEnhanced = false @@ -116,10 +95,9 @@ ${prompts.join('\n\n')} return { ...content, text: ` -${selectedFilesPrompt} -${codeChunksPrompt} +${prompt} ${content.text} -${fileContextPrompt} +${endPrompt} ` } } @@ -129,171 +107,4 @@ ${fileContextPrompt} return new HumanMessage({ content: enhancedContents }) } - - private async buildCodeSnippetsPrompt(): Promise { - const codeSnippets = - this.conversation.attachments?.codebaseContext.relevantCodeSnippets - - if (!codeSnippets || codeSnippets.length === 0) return '' - - const mergedSnippets = await mergeCodeSnippets(codeSnippets) - - const snippetsContent = mergedSnippets - .map(snippet => - formatCodeSnippet({ - relativePath: snippet.relativePath, - code: snippet.code, - startLine: snippet.startLine, - endLine: snippet.endLine, - showLine: true - }) - ) - .join('') - - return snippetsContent - ? ` -## Potentially Relevant Code Snippets from the current Codebase - -${snippetsContent} -${CONTENT_SEPARATOR} -` - : '' - } - - private async buildFilePrompts(): Promise { - const fileContext = this.conversation.attachments?.fileContext - const result = { selectedFilesPrompt: '', currentFilesPrompt: '' } - - if (!fileContext) return result - - const workspacePath = getWorkspaceFolder().uri.fsPath - const currentFilePaths = new Set( - fileContext.currentFiles.map(file => file.fullPath) - ) - const processedFiles = new Set() - - await traverseFileOrFolders({ - type: 'file', - filesOrFolders: [ - ...fileContext.selectedFolders.map(folder => folder.fullPath), - ...fileContext.selectedFiles.map(file => file.fullPath) - ], - workspacePath, - itemCallback: async (fileInfo: FileInfo) => { - if (processedFiles.has(fileInfo.fullPath)) return - - const fileContent = await getFileContent(fileInfo) - const formattedSnippet = formatCodeSnippet({ - relativePath: fileInfo.relativePath, - code: fileContent, - showLine: false - }) - - if (currentFilePaths.has(fileInfo.fullPath)) { - result.currentFilesPrompt += formattedSnippet - } else { - result.selectedFilesPrompt += formattedSnippet - } - - processedFiles.add(fileInfo.fullPath) - } - }) - - if (result.currentFilesPrompt) { - result.currentFilesPrompt = ` -## Current Files -Here is the file I'm looking at. It might be truncated from above and below and, if so, is centered around my cursor. - -${result.currentFilesPrompt} -` - } - - return result - } - - private buildCodeChunksPrompt(): string { - const codeChunks = this.conversation.attachments?.codeContext.codeChunks - if (!codeChunks || codeChunks.length === 0) return '' - - const chunksContent = codeChunks - .map(chunk => - formatCodeSnippet({ - relativePath: chunk.relativePath, - code: chunk.code, - language: chunk.language, - startLine: chunk.startLine, - endLine: chunk.endLine, - showLine: Boolean(chunk.startLine && chunk.endLine) - }) - ) - .join('') - - return chunksContent - } - - private buildRelevantDocsPrompt(): string { - const relevantDocs = this.conversation.attachments?.docContext.relevantDocs - if (!relevantDocs || relevantDocs.length === 0) return '' - - let docsContent = '' - - relevantDocs.forEach(doc => { - docsContent += ` -Source Path: ${doc.path} -Content: ${doc.content} -` - }) - - return docsContent - ? ` -## Potentially Relevant Docs - -${docsContent} -${CONTENT_SEPARATOR} -` - : '' - } - - private buildGitDiffsPrompt( - gitDiffs: GitDiff[] | undefined = this.conversation.attachments?.gitContext - .gitDiffs - ): string { - if (!gitDiffs?.length) return '' - - let gitDiffContent = '' - - gitDiffs.forEach(diff => { - gitDiffContent += ` -File: ${diff.from} → ${diff.to} -Changes: -${diff.chunks - .map(chunk => chunk.content + chunk.lines.map(line => line).join('\n')) - .join('\n')} -` - }) - - return gitDiffContent - } - - private buildGitCommitPrompt(): string { - const gitCommits = this.conversation.attachments?.gitContext.gitCommits - if (!gitCommits?.length) return '' - - let gitCommitContent = ` -## Git Commits - ` - - gitCommits.forEach(commit => { - gitCommitContent += ` -Commit: ${commit.sha} -Message: ${commit.message} -Author: ${commit.author} -Date: ${commit.date} -Diffs: -${this.buildGitDiffsPrompt(commit.diff)} -` - }) - - return gitCommitContent - } } diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/agent-node.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/agent-node.ts index fe8cc93..658f304 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/agent-node.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/agent-node.ts @@ -1,33 +1,30 @@ import { createModelProvider } from '@extension/ai/helpers' -import type { LangchainTool } from '@extension/webview-api/chat-context-processor/types/langchain-message' +import { ServerPluginRegister } from '@extension/registers/server-plugin-register' import { convertLangchainMessageToConversation } from '@extension/webview-api/chat-context-processor/utils/convert-langchain-message-to-conversation' import { getToolCallsFromMessage } from '@extension/webview-api/chat-context-processor/utils/get-tool-calls-from-message' +import type { LangchainTool } from '@shared/types/chat-context/langchain-message' import { produce } from 'immer' import { ChatMessagesConstructor } from '../messages-constructors/chat-messages-constructor' -import { createCodebaseSearchTool } from './codebase-search-node' -import { createDocRetrieverTool } from './doc-retriever-node' -import type { ChatGraphNode } from './state' -import { createWebSearchTool } from './web-search-node' -import { createWebVisitTool } from './web-visit-node' +import type { CreateChatGraphNode } from './state' -export const agentNode: ChatGraphNode = async state => { +export const createAgentNode: CreateChatGraphNode = options => async state => { const modelProvider = await createModelProvider() const aiModelAbortController = new AbortController() const aiModel = await modelProvider.getModel() + const chatStrategyProvider = options.registerManager + .getRegister(ServerPluginRegister) + ?.serverPluginRegistry?.providerManagers.chatStrategy.mergeAll() const tools = [ - // code base search - await createCodebaseSearchTool(state), - // doc - await createDocRetrieverTool(state), - // web search - await createWebSearchTool(state), - // web visit - await createWebVisitTool(state) + ...((await chatStrategyProvider?.buildAgentTools?.(options, state)) || []) ].filter(Boolean) as LangchainTool[] - const chatMessagesConstructor = new ChatMessagesConstructor(state.chatContext) + const chatMessagesConstructor = new ChatMessagesConstructor({ + ...options, + chatContext: state.chatContext + }) + const messagesFromChatContext = await chatMessagesConstructor.constructMessages() diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/generate-node.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/generate-node.ts index e85b310..db5f597 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/generate-node.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/generate-node.ts @@ -3,28 +3,33 @@ import { convertLangchainMessageToConversation } from '@extension/webview-api/ch import { produce } from 'immer' import { ChatMessagesConstructor } from '../messages-constructors/chat-messages-constructor' -import type { ChatGraphNode } from './state' +import type { CreateChatGraphNode } from './state' -export const generateNode: ChatGraphNode = async state => { - const { chatContext } = state - const modelProvider = await createModelProvider() - const aiModelAbortController = new AbortController() - const aiModel = await modelProvider.getModel() +export const createGenerateNode: CreateChatGraphNode = + options => async state => { + const { chatContext } = state + const modelProvider = await createModelProvider() + const aiModelAbortController = new AbortController() + const aiModel = await modelProvider.getModel() - const chatMessagesConstructor = new ChatMessagesConstructor(state.chatContext) - const messagesFromChatContext = - await chatMessagesConstructor.constructMessages() + const chatMessagesConstructor = new ChatMessagesConstructor({ + ...options, + chatContext: state.chatContext + }) - const response = await aiModel - .bind({ signal: aiModelAbortController.signal }) - .invoke(messagesFromChatContext) + const messagesFromChatContext = + await chatMessagesConstructor.constructMessages() - const finalChatContext = produce(chatContext, draft => { - draft.conversations.push(convertLangchainMessageToConversation(response)) - }) + const response = await aiModel + .bind({ signal: aiModelAbortController.signal }) + .invoke(messagesFromChatContext) - return { - messages: [response], - chatContext: finalChatContext + const finalChatContext = produce(chatContext, draft => { + draft.conversations.push(convertLangchainMessageToConversation(response)) + }) + + return { + messages: [response], + chatContext: finalChatContext + } } -} diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state.ts index b906680..cbe487f 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state.ts +++ b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state.ts @@ -1,15 +1,9 @@ import type { BaseMessage } from '@langchain/core/messages' import { Annotation } from '@langchain/langgraph' -import type { ChatContext } from '@webview/types/chat' +import type { ChatContext } from '@shared/types/chat-context' import { baseState } from '../../base-state' - -export enum ChatGraphToolName { - DocRetriever = 'docRetriever', - WebSearch = 'webSearch', - CodebaseSearch = 'codebaseSearch', - WebVisit = 'webVisit' -} +import type { BaseStrategyOptions } from '../../base-strategy' export enum ChatGraphNodeName { Agent = 'agent', @@ -33,6 +27,11 @@ export const chatGraphState = Annotation.Root({ }) export type ChatGraphState = typeof chatGraphState.State + export type ChatGraphNode = ( state: ChatGraphState ) => Promise> + +export type CreateChatGraphNode = ( + options: BaseStrategyOptions +) => ChatGraphNode diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/web-visit-node.ts b/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/web-visit-node.ts deleted file mode 100644 index 9ebd223..0000000 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/web-visit-node.ts +++ /dev/null @@ -1,94 +0,0 @@ -import type { LangchainTool } from '@extension/webview-api/chat-context-processor/types/langchain-message' -import { DocCrawler } from '@extension/webview-api/chat-context-processor/utils/doc-crawler' -import { findCurrentToolsCallParams } from '@extension/webview-api/chat-context-processor/utils/find-current-tools-call-params' -import type { ToolMessage } from '@langchain/core/messages' -import { DynamicStructuredTool } from '@langchain/core/tools' -import { settledPromiseResults } from '@shared/utils/common' -import { ContextInfoSource } from '@webview/types/chat' -import { z } from 'zod' - -import { - ChatGraphToolName, - type ChatGraphNode, - type ChatGraphState -} from './state' - -interface WebVisitToolResult { - contents: { url: string; content: string }[] -} - -// eslint-disable-next-line unused-imports/no-unused-vars -export const createWebVisitTool = async (state: ChatGraphState) => { - const getPageContents = async ( - urls: string[] - ): Promise<{ url: string; content: string }[]> => { - const docCrawler = new DocCrawler(urls[0]!) - const contents = await settledPromiseResults( - urls.map(async url => ({ - url, - content: - (await docCrawler.getPageContent(url)) || 'Failed to retrieve content' - })) - ) - return contents - } - - return new DynamicStructuredTool({ - name: ChatGraphToolName.WebVisit, - description: - 'Visit specific web pages and retrieve their content. Use this tool when you need to access and analyze the content of one or more web pages.', - func: async ({ urls }): Promise => { - const contents = await getPageContents(urls) - return { contents } - }, - schema: z.object({ - urls: z - .array(z.string().url()) - .describe( - 'An array of URLs to visit and retrieve content from. Each URL should be a valid web address.' - ) - }) - }) -} - -export const webVisitNode: ChatGraphNode = async state => { - const { messages, chatContext } = state - const { conversations } = chatContext - const lastConversation = conversations.at(-1) - const docContext = lastConversation?.attachments?.docContext - - if (!docContext) return {} - - const webVisitTool = await createWebVisitTool(state) - - if (!webVisitTool) return {} - - const tools: LangchainTool[] = [webVisitTool] - const lastMessage = messages.at(-1) - const toolCalls = findCurrentToolsCallParams(lastMessage, tools) - - if (!toolCalls.length) return {} - - const toolCallsPromises = toolCalls.map(async toolCall => { - const toolMessage = (await webVisitTool.invoke(toolCall)) as ToolMessage - - const result = JSON.parse( - toolMessage?.lc_kwargs.content - ) as WebVisitToolResult - - lastConversation.attachments!.docContext.relevantDocs = [ - ...lastConversation.attachments!.docContext.relevantDocs, - ...result.contents.map(item => ({ - path: item.url, - content: item.content, - source: ContextInfoSource.ToolNode - })) - ] - }) - - await settledPromiseResults(toolCallsPromises) - - return { - chatContext - } -} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/base-context.ts b/src/extension/webview-api/chat-context-processor/types/chat-context/base-context.ts deleted file mode 100644 index d830e0d..0000000 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/base-context.ts +++ /dev/null @@ -1,13 +0,0 @@ -export interface BaseToolContext { - enableTool: boolean -} - -export enum ContextInfoSource { - FileSelector = 'file-selector', - Editor = 'editor', - ToolNode = 'tool-node' -} - -export interface BaseContextInfo { - source: ContextInfoSource -} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/code-context.ts b/src/extension/webview-api/chat-context-processor/types/chat-context/code-context.ts deleted file mode 100644 index f32bee9..0000000 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/code-context.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { BaseContextInfo } from './base-context' - -export interface CodeChunk extends BaseContextInfo { - code: string - language: string - - relativePath?: string - fullPath?: string - startLine?: number - endLine?: number -} - -export interface CodeContext { - codeChunks: CodeChunk[] -} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/codebase-context.ts b/src/extension/webview-api/chat-context-processor/types/chat-context/codebase-context.ts deleted file mode 100644 index 5149dc2..0000000 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/codebase-context.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { BaseContextInfo, BaseToolContext } from './base-context' - -export interface CodeSnippet extends BaseContextInfo { - fileHash: string - relativePath: string - fullPath: string - startLine: number - startCharacter: number - endLine: number - endCharacter: number - - code: string -} - -export interface CodebaseContext extends BaseToolContext { - relevantCodeSnippets: CodeSnippet[] -} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/conversation.ts b/src/extension/webview-api/chat-context-processor/types/chat-context/conversation.ts deleted file mode 100644 index 6ceafaa..0000000 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/conversation.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { MessageType } from '@langchain/core/messages' - -import type { LangchainMessageContents } from '../langchain-message' -import type { CodeContext } from './code-context' -import type { CodebaseContext } from './codebase-context' -import type { DocContext } from './doc-context' -import type { FileContext } from './file-context' -import type { GitContext } from './git-context' -import type { WebContext } from './web-context' - -export interface Attachments { - codebaseContext: CodebaseContext - fileContext: FileContext - codeContext: CodeContext - webContext: WebContext - docContext: DocContext - gitContext: GitContext -} - -export interface Conversation { - id: string - createdAt: number - role: MessageType - contents: LangchainMessageContents - richText?: string // JSON stringified - attachments?: Attachments -} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/doc-context.ts b/src/extension/webview-api/chat-context-processor/types/chat-context/doc-context.ts deleted file mode 100644 index 1c4060a..0000000 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/doc-context.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { BaseContextInfo } from './base-context' - -export interface DocInfo extends BaseContextInfo { - content: string - path: string // file path or url -} - -export interface DocSiteName extends BaseContextInfo { - name: string -} - -export interface DocContext { - allowSearchDocSiteNames: DocSiteName[] - relevantDocs: DocInfo[] -} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/file-context.ts b/src/extension/webview-api/chat-context-processor/types/chat-context/file-context.ts deleted file mode 100644 index 8b8f9ab..0000000 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/file-context.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { - FileInfo as IFileInfo, - FolderInfo as IFolderInfo -} from '@extension/file-utils/traverse-fs' - -import type { BaseContextInfo } from './base-context' - -export interface FileInfo extends BaseContextInfo, IFileInfo {} -export interface FolderInfo extends BaseContextInfo, IFolderInfo {} -export interface ImageInfo extends BaseContextInfo { - url: string -} - -export interface FileContext { - selectedFiles: FileInfo[] - selectedFolders: FolderInfo[] - selectedImages: ImageInfo[] - currentFiles: FileInfo[] // only for record the current files when create conversation, not ensure for chat context -} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/web-context.ts b/src/extension/webview-api/chat-context-processor/types/chat-context/web-context.ts deleted file mode 100644 index 8f99723..0000000 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/web-context.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { BaseContextInfo, BaseToolContext } from './base-context' - -export interface WebSearchResult extends BaseContextInfo { - url: string - title: string - content: string -} - -export interface WebContext extends BaseToolContext { - webSearchResults: WebSearchResult[] -} diff --git a/src/extension/webview-api/chat-context-processor/utils/content-manager.ts b/src/extension/webview-api/chat-context-processor/utils/content-manager.ts deleted file mode 100644 index e462539..0000000 --- a/src/extension/webview-api/chat-context-processor/utils/content-manager.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { - MessageContentComplex, - MessageContentImageUrl, - MessageContentText -} from '@langchain/core/messages' - -export class LangchainContentsManager { - private messageContents: MessageContentComplex[] - - constructor( - messageContents: string | MessageContentComplex | MessageContentComplex[] - ) { - this.messageContents = [{ type: 'text', text: '' }] - - if (messageContents) { - this.mergeMessageContents(messageContents) - } - } - - appendText(text: string): void { - const textContent = this.messageContents.find( - content => content.type === 'text' - ) as MessageContentText - - textContent.text += text - } - - appendImage(url: string): void { - this.messageContents.push({ - type: 'image_url', - image_url: url - } as MessageContentImageUrl) - } - - mergeMessageContents( - contents: string | MessageContentComplex | MessageContentComplex[] - ): void { - if (typeof contents === 'string') { - this.appendText(`\n${contents}`) - } else if (Array.isArray(contents)) { - contents.forEach(param => this.mergeMessageContents(param)) - } else if (contents.type === 'text') { - this.appendText(`\n${contents.text}`) - } else if (contents.type === 'image_url') { - this.appendImage(contents.image_url) - } - } - - getContents(): MessageContentComplex[] { - return this.messageContents - } -} diff --git a/src/extension/webview-api/chat-context-processor/utils/convert-langchain-message-to-conversation.ts b/src/extension/webview-api/chat-context-processor/utils/convert-langchain-message-to-conversation.ts index 1f288aa..27b4e70 100644 --- a/src/extension/webview-api/chat-context-processor/utils/convert-langchain-message-to-conversation.ts +++ b/src/extension/webview-api/chat-context-processor/utils/convert-langchain-message-to-conversation.ts @@ -1,9 +1,9 @@ -import type { Conversation } from '@extension/webview-api/chat-context-processor/types/chat-context' +import type { MessageType } from '@langchain/core/messages' +import type { Conversation } from '@shared/types/chat-context' import type { LangchainMessage, LangchainMessageContents -} from '@extension/webview-api/chat-context-processor/types/langchain-message' -import type { MessageType } from '@langchain/core/messages' +} from '@shared/types/chat-context/langchain-message' import { convertToLangchainMessageContents } from '@shared/utils/convert-to-langchain-message-contents' import { getDefaultConversation } from '@shared/utils/get-default-conversation' diff --git a/src/extension/webview-api/chat-context-processor/utils/find-current-tools-call-params.ts b/src/extension/webview-api/chat-context-processor/utils/find-current-tools-call-params.ts index 61d86b7..02b2a1f 100644 --- a/src/extension/webview-api/chat-context-processor/utils/find-current-tools-call-params.ts +++ b/src/extension/webview-api/chat-context-processor/utils/find-current-tools-call-params.ts @@ -1,7 +1,7 @@ import type { AIMessage, BaseMessage } from '@langchain/core/messages' import type { ToolCall } from '@langchain/core/messages/tool' -import type { LangchainTool } from '../types/langchain-message' +import type { LangchainTool } from '../../../../shared/types/chat-context/langchain-message' import { getToolCallsFromMessage } from './get-tool-calls-from-message' export const findCurrentToolsCallParams = ( diff --git a/src/extension/webview-api/chat-context-processor/utils/message-builder.ts b/src/extension/webview-api/chat-context-processor/utils/message-builder.ts index 75175a9..83e31e2 100644 --- a/src/extension/webview-api/chat-context-processor/utils/message-builder.ts +++ b/src/extension/webview-api/chat-context-processor/utils/message-builder.ts @@ -8,7 +8,7 @@ import { import type { LangchainMessage, LangchainMessageContents -} from '../types/langchain-message' +} from '../../../../shared/types/chat-context/langchain-message' export class MessageBuilder { static createMessage( diff --git a/src/extension/webview-api/chat-context-processor/utils/searxng-search.ts b/src/extension/webview-api/chat-context-processor/utils/searxng-search.ts index 7bb6b33..a8fcf9d 100644 --- a/src/extension/webview-api/chat-context-processor/utils/searxng-search.ts +++ b/src/extension/webview-api/chat-context-processor/utils/searxng-search.ts @@ -1,8 +1,13 @@ import * as cheerio from 'cheerio' -import { ContextInfoSource, type WebSearchResult } from '../types/chat-context' import { getRandomHeaders } from './fake-request-headers' +interface WebSearchResult { + url: string + title: string + content: string +} + interface SearxngSearchOptions { apiBase: string params?: SearxngSearchParams @@ -42,8 +47,7 @@ const parseHtml = (htmlContent: string): SearxngResults => { .map((_, element) => ({ title: $(element).find('h3').text().trim(), url: $(element).find('a').attr('href') || '', - content: $(element).find('.content').text().trim(), - source: ContextInfoSource.ToolNode + content: $(element).find('.content').text().trim() })) .get() diff --git a/src/extension/webview-api/chat-context-processor/vectordb/base-indexer.ts b/src/extension/webview-api/chat-context-processor/vectordb/base-indexer.ts index 6ac714a..6aac1d9 100644 --- a/src/extension/webview-api/chat-context-processor/vectordb/base-indexer.ts +++ b/src/extension/webview-api/chat-context-processor/vectordb/base-indexer.ts @@ -27,6 +27,19 @@ export interface IndexRow { embedding: number[] } +export const createBaseTableSchemaFields = (dimensions: number) => [ + new Field('fullPath', new Utf8()), + new Field('fileHash', new Utf8()), + new Field('startLine', new Int32()), + new Field('startCharacter', new Int32()), + new Field('endLine', new Int32()), + new Field('endCharacter', new Int32()), + new Field( + 'embedding', + new FixedSizeList(dimensions, new Field('emb', new Float32())) + ) +] + export abstract class BaseIndexer { protected lanceDb!: Connection @@ -58,6 +71,8 @@ export abstract class BaseIndexer { abstract getTableName(): Promise + abstract getTableSchema(dimensions: number): Schema + async getOrCreateTable(): Promise> { const tableName = await this.getTableName() const { dimensions } = EmbeddingManager.getInstance().getActiveModelInfo() @@ -68,18 +83,7 @@ export abstract class BaseIndexer { if (tables.includes(tableName)) return await this.lanceDb.openTable(tableName) - const schema = new Schema([ - new Field('fullPath', new Utf8()), - new Field('fileHash', new Utf8()), - new Field('startLine', new Int32()), - new Field('startCharacter', new Int32()), - new Field('endLine', new Int32()), - new Field('endCharacter', new Int32()), - new Field( - 'embedding', - new FixedSizeList(dimensions, new Field('emb', new Float32())) - ) - ]) + const schema = this.getTableSchema(dimensions) return await this.lanceDb.createTable({ name: tableName, diff --git a/src/extension/webview-api/chat-context-processor/vectordb/codebase-indexer.ts b/src/extension/webview-api/chat-context-processor/vectordb/codebase-indexer.ts index e735a90..6810202 100644 --- a/src/extension/webview-api/chat-context-processor/vectordb/codebase-indexer.ts +++ b/src/extension/webview-api/chat-context-processor/vectordb/codebase-indexer.ts @@ -6,11 +6,16 @@ import { VsCodeFS } from '@extension/file-utils/vscode-fs' import { logger } from '@extension/logger' import { settledPromiseResults } from '@shared/utils/common' import { languageIdExts } from '@shared/utils/vscode-lang' +import { Field, Schema, Utf8 } from 'apache-arrow' import * as vscode from 'vscode' import { CodeChunkerManager, type TextChunk } from '../tree-sitter/code-chunker' import { treeSitterExtLanguageMap } from '../tree-sitter/constants' -import { BaseIndexer, IndexRow } from './base-indexer' +import { + BaseIndexer, + createBaseTableSchemaFields, + IndexRow +} from './base-indexer' export interface CodeChunkRow extends IndexRow { relativePath: string @@ -30,6 +35,13 @@ export class CodebaseIndexer extends BaseIndexer { return `code_chunks_embeddings_${semanticModelName}` } + getTableSchema(dimensions: number): Schema { + return new Schema([ + ...createBaseTableSchemaFields(dimensions), + new Field('relativePath', new Utf8()) + ]) + } + async indexFile(filePath: string): Promise { try { const rows = await this.createCodeChunkRows(filePath) diff --git a/src/extension/webview-api/chat-context-processor/vectordb/doc-indexer.ts b/src/extension/webview-api/chat-context-processor/vectordb/doc-indexer.ts index 884ff07..a31387d 100644 --- a/src/extension/webview-api/chat-context-processor/vectordb/doc-indexer.ts +++ b/src/extension/webview-api/chat-context-processor/vectordb/doc-indexer.ts @@ -5,10 +5,15 @@ import { traverseFileOrFolders } from '@extension/file-utils/traverse-fs' import { VsCodeFS } from '@extension/file-utils/vscode-fs' import { logger } from '@extension/logger' import { settledPromiseResults } from '@shared/utils/common' +import { Schema } from 'apache-arrow' import { CodeChunkerManager, type TextChunk } from '../tree-sitter/code-chunker' import { ProgressReporter } from '../utils/process-reporter' -import { BaseIndexer, IndexRow } from './base-indexer' +import { + BaseIndexer, + createBaseTableSchemaFields, + IndexRow +} from './base-indexer' export interface DocChunkRow extends IndexRow {} @@ -32,6 +37,10 @@ export class DocIndexer extends BaseIndexer { return `doc_chunks_embeddings_${semanticModelName}_${docPathName}` } + getTableSchema(dimensions: number): Schema { + return new Schema([...createBaseTableSchemaFields(dimensions)]) + } + async indexFile(filePath: string): Promise { try { const rows = await this.createDocChunkRows(filePath) diff --git a/src/extension/webview-api/controllers/chat.controller.ts b/src/extension/webview-api/controllers/chat.controller.ts index 263149b..c4ab0a9 100644 --- a/src/extension/webview-api/controllers/chat.controller.ts +++ b/src/extension/webview-api/controllers/chat.controller.ts @@ -1,8 +1,6 @@ +import type { ChatContext, Conversation } from '@shared/types/chat-context' + import { ChatContextProcessor } from '../chat-context-processor' -import type { - ChatContext, - Conversation -} from '../chat-context-processor/types/chat-context' import { Controller } from '../types' export class ChatController extends Controller { diff --git a/src/extension/webview-api/controllers/git.controller.ts b/src/extension/webview-api/controllers/git.controller.ts index 0da1b6d..656a87c 100644 --- a/src/extension/webview-api/controllers/git.controller.ts +++ b/src/extension/webview-api/controllers/git.controller.ts @@ -1,14 +1,10 @@ import type { CommandManager } from '@extension/commands/command-manager' import type { RegisterManager } from '@extension/registers/register-manager' import { getWorkspaceFolder } from '@extension/utils' +import type { GitCommit, GitDiff } from '@shared/plugins/git-plugin/types' import { settledPromiseResults } from '@shared/utils/common' import simpleGit, { SimpleGit } from 'simple-git' -import { - ContextInfoSource, - type GitCommit, - type GitDiff -} from '../chat-context-processor/types/chat-context' import { Controller } from '../types' export class GitController extends Controller { @@ -37,8 +33,7 @@ export class GitController extends Controller { message: commit.message, diff: this.parseDiff(diff), author: commit.author_name, - date: commit.date, - source: ContextInfoSource.Editor + date: commit.date } }) ) @@ -97,8 +92,7 @@ export class GitController extends Controller { content: `@@ ${content}`, lines: lines.filter(line => line.trim() !== '') } - }), - source: ContextInfoSource.Editor + }) }) }) diff --git a/src/shared/plugins/base/client/client-plugin-context.ts b/src/shared/plugins/base/client/client-plugin-context.ts new file mode 100644 index 0000000..0d21f42 --- /dev/null +++ b/src/shared/plugins/base/client/client-plugin-context.ts @@ -0,0 +1,68 @@ +import type { PluginId, PluginState, ValidRecipeReturnType } from '../types' +import type { ClientPluginRegistry } from './client-plugin-registry' + +export interface ClientPlugin { + id: PluginId + version: string + dependencies?: PluginId[] + getInitState(): State + activate(context: ClientPluginContext): Promise + deactivate?(): void + migrate?(oldState: any): State // TODO +} + +interface ClientPluginContextOptions { + pluginId: PluginId + registry: ClientPluginRegistry +} + +export class ClientPluginContext { + private pluginId: PluginId + + private registry: ClientPluginRegistry + + constructor(options: ClientPluginContextOptions) { + const { pluginId, registry } = options + this.pluginId = pluginId + this.registry = registry + } + + get state(): Readonly { + return this.registry.getState(this.pluginId) + } + + setState( + updater: State | ((draft: State) => ValidRecipeReturnType) + ): void { + this.registry.setState(this.pluginId, updater) + } + + resetState(): void { + const plugin = this.registry.getPlugin(this.pluginId) + + if (!plugin) return + + this.registry.setState(this.pluginId, plugin.getInitState()) + } + + getQueryClient() { + return this.registry.queryClient + } + + registerCommand(command: string, callback: (...args: any[]) => void): void { + this.registry.registerCommand(command, callback) + } + + executeCommand(command: string, ...args: any[]): void { + this.registry.executeCommand(command, ...args) + } + + registerProvider( + key: K, + provider: Parameters< + ClientPluginRegistry['providerManagers'][K]['register'] + >[1] + ): void { + this.registry.providerManagers[key].register(this.pluginId, provider as any) + } +} diff --git a/src/shared/plugins/base/client/client-plugin-registry.ts b/src/shared/plugins/base/client/client-plugin-registry.ts new file mode 100644 index 0000000..6f5dd8a --- /dev/null +++ b/src/shared/plugins/base/client/client-plugin-registry.ts @@ -0,0 +1,133 @@ +import type { QueryClient } from '@tanstack/react-query' +import { logger } from '@webview/utils/logger' +import { produce } from 'immer' + +import type { PluginId, PluginState, ValidRecipeReturnType } from '../types' +import { ClientPluginContext, type ClientPlugin } from './client-plugin-context' +import { createProviderManagers } from './create-provider-manager' + +interface ClientPluginRegistryOptions { + queryClient: QueryClient + getState: (pluginId: PluginId) => any + setState: (pluginId: PluginId, newState: any) => void +} + +export class ClientPluginRegistry { + private plugins: Map = new Map() + + private pluginContexts: Map = new Map() + + private commands: Map void> = new Map() + + queryClient: QueryClient + + providerManagers = createProviderManagers() + + getState: (pluginId: PluginId) => any + + setState: ( + pluginId: PluginId, + updater: State | ((draft: State) => ValidRecipeReturnType) + ) => void + + constructor(options: ClientPluginRegistryOptions) { + this.queryClient = options.queryClient + this.getState = options.getState + this.setState = this.createStateSetter(options) + } + + private createStateSetter(options: ClientPluginRegistryOptions) { + return ( + pluginId: PluginId, + updater: + | PluginState + | ((draft: PluginState) => ValidRecipeReturnType) + ) => { + const currentState = options.getState(pluginId) + const newState = + typeof updater === 'function' ? produce(currentState, updater) : updater + options.setState(pluginId, newState) + } + } + + private checkDependencies(plugin: ClientPlugin): boolean { + return ( + !plugin.dependencies || + plugin.dependencies.every(depId => this.plugins.has(depId)) + ) + } + + async loadPlugin( + _plugin: ClientPlugin + ): Promise { + let currentPluginId: PluginId | null = null + + try { + const plugin = _plugin as ClientPlugin + currentPluginId = plugin.id + + if (!this.checkDependencies(plugin)) + throw new Error(`Dependencies not met for plugin ${currentPluginId}`) + + this.plugins.set(currentPluginId, plugin) + const context = new ClientPluginContext({ + registry: this, + pluginId: currentPluginId + }) + this.pluginContexts.set(currentPluginId, context) + await plugin.activate(context) + } catch (error: any) { + this.handleError(error, currentPluginId) + } finally { + currentPluginId = null + } + } + + private handleError(error: Error, pluginId: PluginId | null): void { + logger.error(`Error in plugin ${pluginId}:`, error) + } + + usePluginState(pluginId: PluginId) { + const state = this.getState(pluginId) as State + const setState = ( + updater: State | ((draft: State) => ValidRecipeReturnType) + ) => this.setState(pluginId, updater) + + const resetState = () => { + const plugin = this.plugins.get(pluginId) + if (plugin) this.setState(pluginId, plugin.getInitState()) + } + + return [state, setState, resetState] as const + } + + registerCommand(command: string, callback: (...args: any[]) => void): void { + this.commands.set(command, callback) + } + + executeCommand(command: string, ...args: any[]): void { + const callback = this.commands.get(command) + if (callback) callback(...args) + } + + getPlugin(pluginId: PluginId): T | undefined { + return this.plugins.get(pluginId) as T + } + + async unloadPlugin(pluginId: PluginId): Promise { + const plugin = this.plugins.get(pluginId) + if (plugin?.deactivate) { + await plugin.deactivate() + } + this.plugins.delete(pluginId) + Object.values(this.providerManagers).forEach(manager => + manager.unregister(pluginId) + ) + } + + async unloadAllPlugins(): Promise { + for (const pluginId of this.plugins.keys()) { + await this.unloadPlugin(pluginId) + } + } +} diff --git a/src/shared/plugins/base/client/create-client-plugins.ts b/src/shared/plugins/base/client/create-client-plugins.ts new file mode 100644 index 0000000..1b6e96d --- /dev/null +++ b/src/shared/plugins/base/client/create-client-plugins.ts @@ -0,0 +1,17 @@ +import { DocClientPlugin } from '@shared/plugins/doc-plugin/client/doc-client-plugin' +import { FsClientPlugin } from '@shared/plugins/fs-plugin/client/fs-client-plugin' +import { GitClientPlugin } from '@shared/plugins/git-plugin/client/git-client-plugin' +import { WebClientPlugin } from '@shared/plugins/web-plugin/client/web-client-plugin' + +import type { ClientPlugin } from './client-plugin-context' + +export const createClientPlugins = (): ClientPlugin[] => { + const plugins: ClientPlugin[] = [ + new FsClientPlugin(), + new DocClientPlugin(), + new WebClientPlugin(), + new GitClientPlugin() + ] + + return plugins +} diff --git a/src/shared/plugins/base/client/create-provider-manager.ts b/src/shared/plugins/base/client/create-provider-manager.ts new file mode 100644 index 0000000..0b81a7f --- /dev/null +++ b/src/shared/plugins/base/client/create-provider-manager.ts @@ -0,0 +1,22 @@ +import type { ImageInfo } from '@shared/plugins/fs-plugin/types' +import type { FileInfo, MentionOption } from '@webview/types/chat' + +import { ProviderManager } from '../provider-manager' +import type { PluginState } from '../types' + +export const createProviderManagers = () => + ({ + state: new ProviderManager(), + editor: new ProviderManager<{ + getMentionOptions: () => Promise + }>(), + filesSelector: new ProviderManager<{ + getSelectedFiles: () => FileInfo[] + setSelectedFiles: (files: FileInfo[]) => void + }>(), + imagesSelector: new ProviderManager<{ + getSelectedImages: () => ImageInfo[] + addSelectedImage: (image: ImageInfo) => void + removeSelectedImage: (image: ImageInfo) => void + }>() + }) as const satisfies Record> diff --git a/src/shared/plugins/base/deep-merge-providers.ts b/src/shared/plugins/base/deep-merge-providers.ts new file mode 100644 index 0000000..34a1bfc --- /dev/null +++ b/src/shared/plugins/base/deep-merge-providers.ts @@ -0,0 +1,109 @@ +/* eslint-disable func-names */ +const isPlainObject = (item: any): item is object => + item !== null && + typeof item === 'object' && + Object.prototype.toString.call(item) === '[object Object]' && + typeof item.constructor === 'function' + +const isAsyncFunction = (func: Function): boolean => + func.constructor.name === 'AsyncFunction' + +const mergeFunctions = (func1: Function, func2: Function): Function => { + const isAsync1 = isAsyncFunction(func1) + const isAsync2 = isAsyncFunction(func2) + + if (isAsync1 || isAsync2) { + return async function (this: any, ...args: any[]) { + const result1 = isAsync1 + ? await func1.apply(this, args) + : func1.apply(this, args) + const result2 = isAsync2 + ? await func2.apply(this, args) + : func2.apply(this, args) + return deepMergeProviders([result1, result2]) + } + } + return function (this: any, ...args: any[]) { + const result1 = func1.apply(this, args) + const result2 = func2.apply(this, args) + return deepMergeProviders([result1, result2]) + } +} + +const getAllProperties = (obj: any): string[] => { + if (isPlainObject(obj) && obj.constructor.name !== 'Object') { + const props = new Set() + + const addProps = (currentObj: any) => { + if (currentObj === null || currentObj === Object.prototype) { + return + } + Object.getOwnPropertyNames(currentObj).forEach(prop => { + if (prop !== 'constructor') { + props.add(prop) + } + }) + addProps(Object.getPrototypeOf(currentObj)) + } + + addProps(obj) + return Array.from(props) + } + return Object.keys(obj) +} + +export const deepMergeProviders = (objects: T[]): T => { + if (objects.length === 0) { + return {} as T + } + + if (objects.length === 1) { + return objects[0] as T + } + + return objects.reduce((result, obj) => { + if (isPlainObject(result) && isPlainObject(obj)) { + getAllProperties(obj).forEach(key => { + const value = (obj as any)[key] + if (typeof value === 'function') { + if (key in result && typeof (result as any)[key] === 'function') { + ;(result as any)[key] = mergeFunctions((result as any)[key], value) + } else { + ;(result as any)[key] = value + } + } else if (isPlainObject(value)) { + if (key in result) { + ;(result as any)[key] = deepMergeProviders([ + (result as any)[key], + value + ]) + } else { + ;(result as any)[key] = value + } + } else if (Array.isArray(value)) { + if (key in result) { + ;(result as any)[key] = [...(result as any)[key], ...value] + } else { + ;(result as any)[key] = value + } + } else if (typeof value === 'string') { + if (key in result) { + ;(result as any)[key] += value + } else { + ;(result as any)[key] = value + } + } else { + ;(result as any)[key] = value + } + }) + return result + } + if (Array.isArray(result) && Array.isArray(obj)) { + return [...result, ...obj] as unknown as T + } + if (typeof result === 'string' && typeof obj === 'string') { + return (result + obj) as unknown as T + } + return obj + }, {} as T) +} diff --git a/src/shared/plugins/base/provider-manager.ts b/src/shared/plugins/base/provider-manager.ts new file mode 100644 index 0000000..d891dfd --- /dev/null +++ b/src/shared/plugins/base/provider-manager.ts @@ -0,0 +1,28 @@ +import { deepMergeProviders } from './deep-merge-providers' +import type { PluginId } from './types' + +export class ProviderManager { + protected providers: Map T> = new Map() + + register(pluginId: PluginId, provider: () => T): void { + this.providers.set(pluginId, provider) + } + + unregister(pluginId: PluginId): void { + this.providers.delete(pluginId) + } + + getAll(): Record> { + const entries = Array.from(this.providers.entries()) + const results = entries.map(([pluginId, provider]) => { + const value = provider() + return [pluginId, value] as [PluginId, T] + }) + return Object.fromEntries(results) as Record + } + + mergeAll(): Partial { + const allValues = this.getAll() + return deepMergeProviders(Object.values(allValues)) + } +} diff --git a/src/shared/plugins/base/server/create-provider-manager.ts b/src/shared/plugins/base/server/create-provider-manager.ts new file mode 100644 index 0000000..eca2139 --- /dev/null +++ b/src/shared/plugins/base/server/create-provider-manager.ts @@ -0,0 +1,42 @@ +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import type { + ChatGraphNode, + ChatGraphState +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' +import type { StructuredTool } from '@langchain/core/tools' +import type { ChatContext } from '@shared/types/chat-context' +import type { Conversation } from '@shared/types/chat-context/conversation' + +import { ProviderManager } from '../provider-manager' + +export interface ChatStrategyProvider { + buildSystemMessagePrompt?: (chatContext: ChatContext) => Promise + buildContextMessagePrompt?: ( + conversation: Conversation, + chatContext: ChatContext + ) => Promise + buildHumanMessagePrompt?: ( + conversation: Conversation, + chatContext: ChatContext + ) => Promise + buildHumanMessageEndPrompt?: ( + conversation: Conversation, + chatContext: ChatContext + ) => Promise + buildHumanMessageImageUrls?: ( + conversation: Conversation, + chatContext: ChatContext + ) => Promise + buildAgentTools?: ( + options: BaseStrategyOptions, + graphState: ChatGraphState + ) => Promise + buildLanggraphToolNodes?: ( + options: BaseStrategyOptions + ) => Promise +} + +export const createProviderManagers = () => + ({ + chatStrategy: new ProviderManager() + }) as const satisfies Record> diff --git a/src/shared/plugins/base/server/create-server-plugins.ts b/src/shared/plugins/base/server/create-server-plugins.ts new file mode 100644 index 0000000..6057acf --- /dev/null +++ b/src/shared/plugins/base/server/create-server-plugins.ts @@ -0,0 +1,17 @@ +import { DocServerPlugin } from '@shared/plugins/doc-plugin/server/doc-server-plugin' +import { FsServerPlugin } from '@shared/plugins/fs-plugin/server/fs-server-plugin' +import { GitServerPlugin } from '@shared/plugins/git-plugin/server/git-server-plugin' +import { WebServerPlugin } from '@shared/plugins/web-plugin/server/web-server-plugin' + +import type { ServerPlugin } from './server-plugin-context' + +export const createServerPlugins = (): ServerPlugin[] => { + const plugins: ServerPlugin[] = [ + new FsServerPlugin(), + new DocServerPlugin(), + new WebServerPlugin(), + new GitServerPlugin() + ] + + return plugins +} diff --git a/src/shared/plugins/base/server/server-plugin-context.ts b/src/shared/plugins/base/server/server-plugin-context.ts new file mode 100644 index 0000000..f17f931 --- /dev/null +++ b/src/shared/plugins/base/server/server-plugin-context.ts @@ -0,0 +1,46 @@ +import type { PluginId, PluginState } from '../types' +import type { createProviderManagers } from './create-provider-manager' +import type { ServerPluginRegistry } from './server-plugin-registry' + +export interface ServerPlugin { + id: PluginId + version: string + dependencies?: PluginId[] + activate(context: ServerPluginContext): Promise + deactivate?(): void +} + +interface ServerPluginContextOptions { + pluginId: PluginId + registry: ServerPluginRegistry +} + +// eslint-disable-next-line unused-imports/no-unused-vars +export class ServerPluginContext { + private pluginId: PluginId + + private registry: ServerPluginRegistry + + constructor(options: ServerPluginContextOptions) { + const { pluginId, registry } = options + this.pluginId = pluginId + this.registry = registry + } + + registerCommand(command: string, callback: (...args: any[]) => void): void { + this.registry.registerCommand(command, callback) + } + + executeCommand(command: string, ...args: any[]): void { + this.registry.executeCommand(command, ...args) + } + + registerProvider( + key: K, + provider: Parameters< + ReturnType[K]['register'] + >[1] + ): void { + this.registry.providerManagers[key].register(this.pluginId, provider as any) + } +} diff --git a/src/shared/plugins/base/server/server-plugin-registry.ts b/src/shared/plugins/base/server/server-plugin-registry.ts new file mode 100644 index 0000000..c7b0e6d --- /dev/null +++ b/src/shared/plugins/base/server/server-plugin-registry.ts @@ -0,0 +1,80 @@ +import { logger } from '@extension/logger' + +import type { PluginId } from '../types' +import { createProviderManagers } from './create-provider-manager' +import { ServerPluginContext, type ServerPlugin } from './server-plugin-context' + +export class ServerPluginRegistry { + private plugins: Map = new Map() + + private pluginContexts: Map = new Map() + + private commands: Map void> = new Map() + + providerManagers = createProviderManagers() + + private checkDependencies(plugin: ServerPlugin): boolean { + return ( + !plugin.dependencies || + plugin.dependencies.every(depId => this.plugins.has(depId)) + ) + } + + async loadPlugin(_plugin: ServerPlugin): Promise { + let currentPluginId: PluginId | null = null + + try { + const plugin = _plugin as ServerPlugin + currentPluginId = plugin.id + + if (!this.checkDependencies(plugin)) + throw new Error(`Dependencies not met for plugin ${currentPluginId}`) + + this.plugins.set(currentPluginId, plugin) + const context = new ServerPluginContext({ + registry: this, + pluginId: currentPluginId + }) + this.pluginContexts.set(currentPluginId, context) + await plugin.activate(context) + } catch (error: any) { + this.handleError(error, currentPluginId) + } finally { + currentPluginId = null + } + } + + private handleError(error: Error, pluginId: PluginId | null): void { + logger.error(`Error in plugin ${pluginId}:`, error) + } + + registerCommand(command: string, callback: (...args: any[]) => void): void { + this.commands.set(command, callback) + } + + executeCommand(command: string, ...args: any[]): void { + const callback = this.commands.get(command) + if (callback) callback(...args) + } + + getPlugin(pluginId: PluginId): T | undefined { + return this.plugins.get(pluginId) as T + } + + async unloadPlugin(pluginId: PluginId): Promise { + const plugin = this.plugins.get(pluginId) + if (plugin?.deactivate) { + await plugin.deactivate() + } + this.plugins.delete(pluginId) + Object.values(this.providerManagers).forEach(manager => + manager.unregister(pluginId) + ) + } + + async unloadAllPlugins(): Promise { + for (const pluginId of this.plugins.keys()) { + await this.unloadPlugin(pluginId) + } + } +} diff --git a/src/shared/plugins/base/types.ts b/src/shared/plugins/base/types.ts new file mode 100644 index 0000000..b7f904d --- /dev/null +++ b/src/shared/plugins/base/types.ts @@ -0,0 +1,14 @@ +export enum PluginId { + Fs = 'fsPlugin', + Web = 'webPlugin', + Doc = 'docPlugin', + Git = 'gitPlugin' +} + +export type PluginState = Record + +export type ValidRecipeReturnType = + | State + | void + | undefined + | (State extends undefined ? any : never) diff --git a/src/shared/plugins/doc-plugin/client/doc-client-plugin.tsx b/src/shared/plugins/doc-plugin/client/doc-client-plugin.tsx new file mode 100644 index 0000000..faea371 --- /dev/null +++ b/src/shared/plugins/doc-plugin/client/doc-client-plugin.tsx @@ -0,0 +1,99 @@ +import { IdCardIcon } from '@radix-ui/react-icons' +import type { + ClientPlugin, + ClientPluginContext +} from '@shared/plugins/base/client/client-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' +import { api } from '@webview/services/api-client' +import { type MentionOption } from '@webview/types/chat' + +import type { DocPluginState } from '../types' + +export class DocClientPlugin implements ClientPlugin { + id = PluginId.Doc + + version: string = pkg.version + + private context: ClientPluginContext | null = null + + getInitState() { + return { + allowSearchDocSiteNamesFromEditor: [], + relevantDocsFromAgent: [] + } + } + + async activate(context: ClientPluginContext): Promise { + this.context = context + + this.context.registerProvider('state', () => this.context!.state) + this.context.registerProvider('editor', () => ({ + getMentionOptions: this.getMentionOptions.bind(this) + })) + } + + deactivate(): void { + this.context?.resetState() + this.context = null + } + + private async getMentionOptions(): Promise { + if (!this.context) return [] + + const docSites = await this.context.getQueryClient().fetchQuery({ + queryKey: ['realtime', 'docSites'], + queryFn: () => api.doc.getDocSites({}) + }) + + const docSiteNamesMentionOptions: MentionOption[] = docSites.map( + site => + ({ + id: `${PluginId.Doc}#doc#${site.id}`, + type: `${PluginId.Doc}#doc`, + label: site.name, + data: site.name, + onAddOne: data => { + this.context?.setState(draft => { + draft.allowSearchDocSiteNamesFromEditor.push(data) + }) + }, + onRemoveOne: data => { + this.context?.setState(draft => { + draft.allowSearchDocSiteNamesFromEditor = + draft.allowSearchDocSiteNamesFromEditor.filter( + name => name !== data + ) + }) + }, + onReplaceAll: dataArr => { + this.context?.setState(draft => { + draft.allowSearchDocSiteNamesFromEditor = dataArr + }) + }, + + searchKeywords: [site.name, site.url], + itemLayoutProps: { + icon: , + label: site.name, + details: site.url + } + }) satisfies MentionOption + ) + + return [ + { + id: `${PluginId.Doc}#docs`, + type: `${PluginId.Doc}#docs`, + label: 'Docs', + topLevelSort: 4, + searchKeywords: ['docs'], + itemLayoutProps: { + icon: , + label: 'Docs' + }, + children: docSiteNamesMentionOptions + } + ] + } +} diff --git a/src/shared/plugins/doc-plugin/server/chat-strategy/doc-chat-strategy-provider.ts b/src/shared/plugins/doc-plugin/server/chat-strategy/doc-chat-strategy-provider.ts new file mode 100644 index 0000000..7bf81c2 --- /dev/null +++ b/src/shared/plugins/doc-plugin/server/chat-strategy/doc-chat-strategy-provider.ts @@ -0,0 +1,81 @@ +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import type { + ChatGraphNode, + ChatGraphState +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' +import type { StructuredTool } from '@langchain/core/tools' +import type { ChatStrategyProvider } from '@shared/plugins/base/server/create-provider-manager' +import { PluginId } from '@shared/plugins/base/types' +import type { Conversation } from '@shared/types/chat-context/conversation' + +import type { DocPluginState } from '../../types' +import { + createDocRetrieverNode, + createDocRetrieverTool +} from './doc-retriever-node' + +export class DocChatStrategyProvider implements ChatStrategyProvider { + async buildContextMessagePrompt(conversation: Conversation): Promise { + const state = conversation.pluginStates?.[PluginId.Doc] as + | Partial + | undefined + + if (!state) return '' + + const relevantDocsPrompt = this.buildRelevantDocsPrompt(state) + + const prompts = [relevantDocsPrompt].filter(Boolean) + + return prompts.join('\n\n') + } + + async buildAgentTools( + options: BaseStrategyOptions, + state: ChatGraphState + ): Promise { + const tools = await Promise.all([createDocRetrieverTool(options, state)]) + return tools.filter(Boolean) as StructuredTool[] + } + + async buildLanggraphToolNodes( + options: BaseStrategyOptions + ): Promise { + return [createDocRetrieverNode(options)] + } + + private buildRelevantDocsPrompt(state: Partial): string { + const { relevantDocsFromAgent: relevantDocsFromDocAgent } = state + + if (!relevantDocsFromDocAgent?.length) return '' + + let docsContent = '' + + relevantDocsFromDocAgent.forEach(doc => { + docsContent += ` +Source Path: ${doc.path} +Content: ${doc.content} +` + }) + + return docsContent + ? ` +## Potentially Relevant Docs + +${docsContent} +${CONTENT_SEPARATOR} +` + : '' + } +} + +const CONTENT_SEPARATOR = ` + + +------- + + + +------- + + +` diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/doc-retriever-node.ts b/src/shared/plugins/doc-plugin/server/chat-strategy/doc-retriever-node.ts similarity index 55% rename from src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/doc-retriever-node.ts rename to src/shared/plugins/doc-plugin/server/chat-strategy/doc-retriever-node.ts index a562c6d..2384fa7 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/doc-retriever-node.ts +++ b/src/shared/plugins/doc-plugin/server/chat-strategy/doc-retriever-node.ts @@ -1,38 +1,44 @@ import { aidePaths } from '@extension/file-utils/paths' -import { DocInfo } from '@extension/webview-api/chat-context-processor/types/chat-context/doc-context' -import type { LangchainTool } from '@extension/webview-api/chat-context-processor/types/langchain-message' +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import { + type ChatGraphState, + type CreateChatGraphNode +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' import { DocCrawler } from '@extension/webview-api/chat-context-processor/utils/doc-crawler' import { findCurrentToolsCallParams } from '@extension/webview-api/chat-context-processor/utils/find-current-tools-call-params' import { DocIndexer } from '@extension/webview-api/chat-context-processor/vectordb/doc-indexer' import { docSitesDB } from '@extension/webview-api/lowdb/doc-sites-db' import type { ToolMessage } from '@langchain/core/messages' import { DynamicStructuredTool } from '@langchain/core/tools' +import { PluginId } from '@shared/plugins/base/types' +import type { LangchainTool } from '@shared/types/chat-context/langchain-message' import { removeDuplicates, settledPromiseResults } from '@shared/utils/common' -import { ContextInfoSource } from '@webview/types/chat' +import { produce } from 'immer' import { z } from 'zod' -import { - ChatGraphToolName, - type ChatGraphNode, - type ChatGraphState -} from './state' +import type { DocInfo, DocPluginState } from '../../types' interface DocRetrieverToolResult { relevantDocs: DocInfo[] } -export const createDocRetrieverTool = async (state: ChatGraphState) => { +export const createDocRetrieverTool = async ( + options: BaseStrategyOptions, + state: ChatGraphState +) => { const { chatContext } = state const { conversations } = chatContext const lastConversation = conversations.at(-1) - const docContext = lastConversation?.attachments?.docContext - if (!docContext) return null + const docPluginState = lastConversation?.pluginStates?.[PluginId.Doc] as + | Partial + | undefined - const { allowSearchDocSiteNames } = docContext + if (!docPluginState?.allowSearchDocSiteNamesFromEditor?.length) return null - if (!allowSearchDocSiteNames.length) return null - const siteNames = allowSearchDocSiteNames.map(item => item.name) + const siteNames = removeDuplicates( + docPluginState.allowSearchDocSiteNamesFromEditor + ) const getRelevantDocs = async ( queryParts: { siteName: string; keywords: string[] }[] @@ -65,8 +71,7 @@ export const createDocRetrieverTool = async (state: ChatGraphState) => { const docInfoResults = await settledPromiseResults( searchRows.map(async row => ({ content: await docIndexer.getRowFileContent(row), - path: docSite.url, - source: ContextInfoSource.ToolNode + path: docSite.url })) ) @@ -78,7 +83,7 @@ export const createDocRetrieverTool = async (state: ChatGraphState) => { } return new DynamicStructuredTool({ - name: ChatGraphToolName.DocRetriever, + name: 'docRetriever', description: 'Search for relevant information in specified documentation sites. This tool can search across multiple doc sites, with multiple keywords for each site. Use this tool to find documentation on specific topics or understand how certain features are described in the documentation.', func: async ({ queryParts }): Promise => ({ @@ -89,7 +94,7 @@ export const createDocRetrieverTool = async (state: ChatGraphState) => { .array( z.object({ siteName: z - .enum(allowSearchDocSiteNames as unknown as [string, ...string[]]) + .enum(siteNames as unknown as [string, ...string[]]) .describe('The name of the documentation site to search'), keywords: z .array(z.string()) @@ -105,40 +110,54 @@ export const createDocRetrieverTool = async (state: ChatGraphState) => { }) } -export const docRetrieverNode: ChatGraphNode = async state => { - const { messages, chatContext } = state - const { conversations } = chatContext - const lastConversation = conversations.at(-1) - const docContext = lastConversation?.attachments?.docContext +export const createDocRetrieverNode: CreateChatGraphNode = + options => async state => { + const { messages, chatContext } = state + const { conversations } = chatContext + const lastConversation = conversations.at(-1) - if (!docContext) return {} + const docPluginState = lastConversation?.pluginStates?.[PluginId.Doc] as + | Partial + | undefined - const docRetrieverTool = await createDocRetrieverTool(state) + if (!docPluginState?.allowSearchDocSiteNamesFromEditor?.length) return {} - if (!docRetrieverTool) return {} + const docRetrieverTool = await createDocRetrieverTool(options, state) - const tools: LangchainTool[] = [docRetrieverTool] - const lastMessage = messages.at(-1) - const toolCalls = findCurrentToolsCallParams(lastMessage, tools) + if (!docRetrieverTool) return {} - if (!toolCalls.length) return {} + const tools: LangchainTool[] = [docRetrieverTool] + const lastMessage = messages.at(-1) + const toolCalls = findCurrentToolsCallParams(lastMessage, tools) - const toolCallsPromises = toolCalls.map(async toolCall => { - const toolMessage = (await docRetrieverTool.invoke(toolCall)) as ToolMessage + if (!toolCalls.length) return {} - const result = JSON.parse( - toolMessage?.lc_kwargs.content - ) as DocRetrieverToolResult + const toolCallsPromises = toolCalls.map(async toolCall => { + const toolMessage = (await docRetrieverTool.invoke( + toolCall + )) as ToolMessage - lastConversation.attachments!.docContext.relevantDocs = [ - ...lastConversation.attachments!.docContext.relevantDocs, - ...result.relevantDocs - ] - }) + const result = JSON.parse( + toolMessage?.lc_kwargs.content + ) as DocRetrieverToolResult - await settledPromiseResults(toolCallsPromises) + lastConversation!.pluginStates![PluginId.Doc] = produce( + lastConversation!.pluginStates![ + PluginId.Doc + ] as Partial, + (draft: Partial) => { + if (!draft.relevantDocsFromAgent) { + draft.relevantDocsFromAgent = [] + } - return { - chatContext + draft.relevantDocsFromAgent.push(...result.relevantDocs) + } + ) + }) + + await settledPromiseResults(toolCallsPromises) + + return { + chatContext + } } -} diff --git a/src/shared/plugins/doc-plugin/server/doc-server-plugin.ts b/src/shared/plugins/doc-plugin/server/doc-server-plugin.ts new file mode 100644 index 0000000..7eac628 --- /dev/null +++ b/src/shared/plugins/doc-plugin/server/doc-server-plugin.ts @@ -0,0 +1,30 @@ +import type { + ServerPlugin, + ServerPluginContext +} from '@shared/plugins/base/server/server-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' + +import type { DocPluginState } from '../types' +import { DocChatStrategyProvider } from './chat-strategy/doc-chat-strategy-provider' + +export class DocServerPlugin implements ServerPlugin { + id = PluginId.Doc + + version: string = pkg.version + + private context: ServerPluginContext | null = null + + async activate(context: ServerPluginContext): Promise { + this.context = context + + this.context.registerProvider( + 'chatStrategy', + () => new DocChatStrategyProvider() + ) + } + + deactivate(): void { + this.context = null + } +} diff --git a/src/shared/plugins/doc-plugin/types.ts b/src/shared/plugins/doc-plugin/types.ts new file mode 100644 index 0000000..693d69d --- /dev/null +++ b/src/shared/plugins/doc-plugin/types.ts @@ -0,0 +1,9 @@ +export interface DocInfo { + content: string + path: string // file path or url +} + +export interface DocPluginState { + allowSearchDocSiteNamesFromEditor: string[] + relevantDocsFromAgent: DocInfo[] +} diff --git a/src/shared/plugins/fs-plugin/client/fs-client-plugin.tsx b/src/shared/plugins/fs-plugin/client/fs-client-plugin.tsx new file mode 100644 index 0000000..95f8d12 --- /dev/null +++ b/src/shared/plugins/fs-plugin/client/fs-client-plugin.tsx @@ -0,0 +1,267 @@ +import { + CardStackIcon, + ChevronRightIcon, + CodeIcon, + CubeIcon, + FileIcon +} from '@radix-ui/react-icons' +import type { + ClientPlugin, + ClientPluginContext +} from '@shared/plugins/base/client/client-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' +import { FileIcon as FileIcon2 } from '@webview/components/file-icon' +import { api } from '@webview/services/api-client' +import { + SearchSortStrategy, + type FileInfo, + type FolderInfo, + type MentionOption +} from '@webview/types/chat' +import { getFileNameFromPath } from '@webview/utils/path' + +import type { FsPluginState, ImageInfo } from '../types' +import { MentionFilePreview } from './mention-file-preview' +import { MentionFolderPreview } from './mention-folder-preview' + +export class FsClientPlugin implements ClientPlugin { + id = PluginId.Fs + + version: string = pkg.version + + private context: ClientPluginContext | null = null + + getInitState() { + return { + selectedFilesFromFileSelector: [], + selectedFilesFromEditor: [], + currentFilesFromVSCode: [], + selectedFoldersFromEditor: [], + selectedImagesFromOutsideUrl: [], + codeChunksFromEditor: [], + codeSnippetFromAgent: [], + enableCodebaseAgent: false + } + } + + async activate(context: ClientPluginContext): Promise { + this.context = context + + this.context.registerProvider('state', () => this.context!.state) + this.context.registerProvider('editor', () => ({ + getMentionOptions: this.getMentionOptions.bind(this) + })) + this.context.registerProvider('filesSelector', () => ({ + getSelectedFiles: this.getSelectedFiles.bind(this), + setSelectedFiles: this.setSelectedFiles.bind(this) + })) + this.context.registerProvider('imagesSelector', () => ({ + getSelectedImages: this.getSelectedImages.bind(this), + addSelectedImage: this.addSelectedImage.bind(this), + removeSelectedImage: this.removeSelectedImage.bind(this) + })) + } + + deactivate(): void { + this.context?.resetState() + this.context = null + } + + private getSelectedFiles(): FileInfo[] { + if (!this.context) return [] + + return this.context.state.selectedFilesFromFileSelector + } + + private setSelectedFiles(files: FileInfo[]): void { + if (!this.context) return + + this.context.setState(draft => { + draft.selectedFilesFromFileSelector = files + }) + } + + private getSelectedImages(): ImageInfo[] { + if (!this.context) return [] + + return this.context.state.selectedImagesFromOutsideUrl + } + + private addSelectedImage(image: ImageInfo): void { + if (!this.context) return + + this.context.setState(draft => { + draft.selectedImagesFromOutsideUrl.push(image) + }) + } + + private removeSelectedImage(image: ImageInfo): void { + if (!this.context) return + + this.context.setState(draft => { + draft.selectedImagesFromOutsideUrl = + draft.selectedImagesFromOutsideUrl.filter(i => i.url !== image.url) + }) + } + + private async getMentionOptions(): Promise { + if (!this.context) return [] + + const files = await this.context.getQueryClient().fetchQuery({ + queryKey: ['realtime', 'files'], + queryFn: () => api.file.traverseWorkspaceFiles({ filesOrFolders: ['./'] }) + }) + + const folders = await this.context.getQueryClient().fetchQuery({ + queryKey: ['realtime', 'folders'], + queryFn: () => api.file.traverseWorkspaceFolders({ folders: ['./'] }) + }) + + const filesMentionOptions: MentionOption[] = files.map( + file => + ({ + id: `${PluginId.Fs}#file#${file.fullPath}`, + type: `${PluginId.Fs}#file`, + label: getFileNameFromPath(file.fullPath), + data: file, + onAddOne: data => { + this.context?.setState(draft => { + draft.selectedFilesFromEditor.push(data) + }) + }, + onRemoveOne: data => { + this.context?.setState(draft => { + draft.selectedFilesFromEditor = + draft.selectedFilesFromEditor.filter( + f => f.fullPath !== data.fullPath + ) + }) + }, + onReplaceAll: dataArr => { + this.context?.setState(draft => { + draft.selectedFilesFromEditor = dataArr + }) + }, + + searchKeywords: [file.relativePath], + searchSortStrategy: SearchSortStrategy.EndMatch, + itemLayoutProps: { + icon: ( + + ), + label: getFileNameFromPath(file.fullPath), + details: file.relativePath + }, + customRenderPreview: MentionFilePreview + }) satisfies MentionOption + ) + + const foldersMentionOptions: MentionOption[] = folders.map( + folder => + ({ + id: `${PluginId.Fs}#folder#${folder.fullPath}`, + type: `${PluginId.Fs}#folder`, + label: getFileNameFromPath(folder.fullPath), + data: folder, + onAddOne: data => { + this.context?.setState(draft => { + draft.selectedFoldersFromEditor.push(data) + }) + }, + onRemoveOne: data => { + this.context?.setState(draft => { + draft.selectedFoldersFromEditor = + draft.selectedFoldersFromEditor.filter( + f => f.fullPath !== data.fullPath + ) + }) + }, + onReplaceAll: dataArr => { + this.context?.setState(draft => { + draft.selectedFoldersFromEditor = dataArr + }) + }, + + searchKeywords: [folder.relativePath], + searchSortStrategy: SearchSortStrategy.EndMatch, + itemLayoutProps: { + icon: ( + <> + + + + ), + label: getFileNameFromPath(folder.fullPath), + details: folder.relativePath + }, + customRenderPreview: MentionFolderPreview + }) satisfies MentionOption + ) + + return [ + { + id: `${PluginId.Fs}#files`, + type: `${PluginId.Fs}#files`, + label: 'Files', + topLevelSort: 0, + searchKeywords: ['files'], + children: filesMentionOptions, + itemLayoutProps: { + icon: , + label: 'Files' + } + }, + { + id: `${PluginId.Fs}#folders`, + type: `${PluginId.Fs}#folders`, + label: 'Folders', + topLevelSort: 1, + searchKeywords: ['folders'], + children: foldersMentionOptions, + itemLayoutProps: { + icon: , + label: 'Folders' + } + }, + { + id: `${PluginId.Fs}#code`, + type: `${PluginId.Fs}#code`, + label: 'Code', + topLevelSort: 2, + searchKeywords: ['code'], + itemLayoutProps: { + icon: , + label: 'Code' + } + }, + { + id: `${PluginId.Fs}#codebase`, + type: `${PluginId.Fs}#codebase`, + label: 'Codebase', + data: true, + onAddOne: () => { + this.context?.setState(draft => { + draft.enableCodebaseAgent = true + }) + }, + onReplaceAll: (dataArr: true[]) => { + this.context?.setState(draft => { + draft.enableCodebaseAgent = dataArr.length > 0 + }) + }, + topLevelSort: 6, + searchKeywords: ['codebase'], + itemLayoutProps: { + icon: , + label: 'Codebase' + } + } + ] + } +} diff --git a/src/webview/components/chat/selectors/mention-selector/files/mention-file-preview.tsx b/src/shared/plugins/fs-plugin/client/mention-file-preview.tsx similarity index 100% rename from src/webview/components/chat/selectors/mention-selector/files/mention-file-preview.tsx rename to src/shared/plugins/fs-plugin/client/mention-file-preview.tsx diff --git a/src/webview/components/chat/selectors/mention-selector/folders/mention-folder-preview.tsx b/src/shared/plugins/fs-plugin/client/mention-folder-preview.tsx similarity index 100% rename from src/webview/components/chat/selectors/mention-selector/folders/mention-folder-preview.tsx rename to src/shared/plugins/fs-plugin/client/mention-folder-preview.tsx diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/codebase-search-node.ts b/src/shared/plugins/fs-plugin/server/chat-strategy/codebase-search-node.ts similarity index 51% rename from src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/codebase-search-node.ts rename to src/shared/plugins/fs-plugin/server/chat-strategy/codebase-search-node.ts index 4c9e54c..9f6cafb 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/codebase-search-node.ts +++ b/src/shared/plugins/fs-plugin/server/chat-strategy/codebase-search-node.ts @@ -1,31 +1,37 @@ import { CodebaseWatcherRegister } from '@extension/registers/codebase-watcher-register' -import { CodeSnippet } from '@extension/webview-api/chat-context-processor/types/chat-context/codebase-context' -import type { LangchainTool } from '@extension/webview-api/chat-context-processor/types/langchain-message' +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import { + type ChatGraphState, + type CreateChatGraphNode +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' import { findCurrentToolsCallParams } from '@extension/webview-api/chat-context-processor/utils/find-current-tools-call-params' -import { mergeCodeSnippets } from '@extension/webview-api/chat-context-processor/utils/merge-code-snippets' import type { ToolMessage } from '@langchain/core/messages' import { DynamicStructuredTool } from '@langchain/core/tools' +import { PluginId } from '@shared/plugins/base/types' +import { mergeCodeSnippets } from '@shared/plugins/fs-plugin/server/merge-code-snippets' +import type { LangchainTool } from '@shared/types/chat-context/langchain-message' import { settledPromiseResults } from '@shared/utils/common' -import { ContextInfoSource } from '@webview/types/chat' +import { produce } from 'immer' import { z } from 'zod' -import { - ChatGraphToolName, - type ChatGraphNode, - type ChatGraphState -} from './state' +import type { CodeSnippet, FsPluginState } from '../../types' interface CodebaseSearchToolResult { codeSnippets: CodeSnippet[] } -export const createCodebaseSearchTool = async (state: ChatGraphState) => { +export const createCodebaseSearchTool = async ( + options: BaseStrategyOptions, + state: ChatGraphState +) => { const { chatContext } = state const { conversations } = chatContext const lastConversation = conversations.at(-1) - const codebaseContext = lastConversation?.attachments?.codebaseContext + const fsPluginState = lastConversation?.pluginStates?.[PluginId.Fs] as + | Partial + | undefined - if (!codebaseContext || !codebaseContext.enableTool) return null + if (!fsPluginState?.enableCodebaseAgent) return null const getSearchResults = async ( state: ChatGraphState, @@ -50,7 +56,7 @@ export const createCodebaseSearchTool = async (state: ChatGraphState) => { .map(row => { // eslint-disable-next-line unused-imports/no-unused-vars const { embedding, ...others } = row - return { ...others, code: '', source: ContextInfoSource.ToolNode } + return { ...others, code: '' } }) const mergedCodeSnippets = await mergeCodeSnippets(searchCodeSnippets, { @@ -64,7 +70,7 @@ export const createCodebaseSearchTool = async (state: ChatGraphState) => { } return new DynamicStructuredTool({ - name: ChatGraphToolName.CodebaseSearch, + name: 'codebaseSearch', description: 'Search the codebase using vector embeddings. This tool breaks down the query into parts and finds relevant code snippets for each part. Use this when you need to find specific code implementations or understand how certain features are coded in the project.', func: async ({ queryParts }): Promise => @@ -85,42 +91,51 @@ export const createCodebaseSearchTool = async (state: ChatGraphState) => { }) } -export const codebaseSearchNode: ChatGraphNode = async state => { - const { messages, chatContext } = state - const { conversations } = chatContext - const lastConversation = conversations.at(-1) - const codebaseContext = lastConversation?.attachments?.codebaseContext +export const createCodebaseSearchNode: CreateChatGraphNode = + options => async state => { + const { messages, chatContext } = state + const { conversations } = chatContext + const lastConversation = conversations.at(-1) + const fsPluginState = lastConversation?.pluginStates?.[PluginId.Fs] as + | Partial + | undefined - if (!codebaseContext || !codebaseContext.enableTool) return {} + if (!fsPluginState?.enableCodebaseAgent) return {} - const codebaseSearchTool = await createCodebaseSearchTool(state) + const codebaseSearchTool = await createCodebaseSearchTool(options, state) - if (!codebaseSearchTool) return {} + if (!codebaseSearchTool) return {} - const tools: LangchainTool[] = [codebaseSearchTool] - const lastMessage = messages.at(-1) - const toolCalls = findCurrentToolsCallParams(lastMessage, tools) + const tools: LangchainTool[] = [codebaseSearchTool] + const lastMessage = messages.at(-1) + const toolCalls = findCurrentToolsCallParams(lastMessage, tools) - if (!toolCalls.length) return {} + if (!toolCalls.length) return {} - const toolCallsPromises = toolCalls.map(async toolCall => { - const toolMessage = (await codebaseSearchTool.invoke( - toolCall - )) as ToolMessage + const toolCallsPromises = toolCalls.map(async toolCall => { + const toolMessage = (await codebaseSearchTool.invoke( + toolCall + )) as ToolMessage - const result = JSON.parse( - toolMessage?.lc_kwargs.content - ) as CodebaseSearchToolResult + const result = JSON.parse( + toolMessage?.lc_kwargs.content + ) as CodebaseSearchToolResult - lastConversation.attachments!.codebaseContext.relevantCodeSnippets = [ - ...lastConversation.attachments!.codebaseContext.relevantCodeSnippets, - ...result.codeSnippets - ] - }) + lastConversation!.pluginStates![PluginId.Fs] = produce( + lastConversation!.pluginStates![PluginId.Fs] as Partial, + (draft: Partial) => { + if (!draft.codeSnippetFromAgent) { + draft.codeSnippetFromAgent = [] + } - await settledPromiseResults(toolCallsPromises) + draft.codeSnippetFromAgent.push(...result.codeSnippets) + } + ) + }) + + await settledPromiseResults(toolCallsPromises) - return { - chatContext + return { + chatContext + } } -} diff --git a/src/shared/plugins/fs-plugin/server/chat-strategy/fs-chat-strategy-provider.ts b/src/shared/plugins/fs-plugin/server/chat-strategy/fs-chat-strategy-provider.ts new file mode 100644 index 0000000..741edf5 --- /dev/null +++ b/src/shared/plugins/fs-plugin/server/chat-strategy/fs-chat-strategy-provider.ts @@ -0,0 +1,361 @@ +import { + AI_SUPPORT_IMG_EXT, + IGNORE_FILETYPES_WITHOUT_IMG +} from '@extension/constants' +import { createShouldIgnore } from '@extension/file-utils/ignore-patterns' +import { traverseFileOrFolders } from '@extension/file-utils/traverse-fs' +import { VsCodeFS } from '@extension/file-utils/vscode-fs' +import { logger } from '@extension/logger' +import { getWorkspaceFolder } from '@extension/utils' +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import type { + ChatGraphNode, + ChatGraphState +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' +import { formatCodeSnippet } from '@extension/webview-api/chat-context-processor/utils/code-snippet-formatter' +import { getFileContent } from '@extension/webview-api/chat-context-processor/utils/get-file-content' +import type { StructuredTool } from '@langchain/core/tools' +import type { ChatStrategyProvider } from '@shared/plugins/base/server/create-provider-manager' +import { PluginId } from '@shared/plugins/base/types' +import { mergeCodeSnippets } from '@shared/plugins/fs-plugin/server/merge-code-snippets' +import type { Conversation } from '@shared/types/chat-context/conversation' +import { removeDuplicates } from '@shared/utils/common' +import type { ChatContext, FileInfo } from '@webview/types/chat' + +import type { FsPluginState } from '../../types' +import { + createCodebaseSearchNode, + createCodebaseSearchTool +} from './codebase-search-node' + +interface BuildFilePromptsResult { + selectedFilesPrompt: string + currentFilesPrompt: string + imageBase64Urls: string[] +} + +export class FsChatStrategyProvider implements ChatStrategyProvider { + async buildSystemMessagePrompt(chatContext: ChatContext): Promise { + const hasAttachedFiles = this.checkForAttachedFiles(chatContext) + + return hasAttachedFiles + ? CHAT_WITH_FILE_SYSTEM_PROMPT + : COMMON_SYSTEM_PROMPT + } + + async buildContextMessagePrompt(conversation: Conversation): Promise { + const state = conversation.pluginStates?.[PluginId.Fs] as + | Partial + | undefined + + if (!state) return '' + + const codeSnippetsPrompt = await this.buildCodeSnippetsPrompt(state) + codeSnippetsPrompt && + logger.dev.verbose('codeSnippetsPrompt', codeSnippetsPrompt) + + const { currentFilesPrompt } = await this.buildFilePrompts(state) + const prompts = [codeSnippetsPrompt, currentFilesPrompt].filter(Boolean) + + return prompts.join('\n\n') + } + + async buildHumanMessagePrompt(conversation: Conversation): Promise { + const state = conversation.pluginStates?.[PluginId.Fs] as + | Partial + | undefined + + if (!state) return '' + + const { selectedFilesPrompt } = await this.buildFilePrompts(state) + const codeChunksPrompt = this.buildCodeChunksPrompt(state) + + return ` +${selectedFilesPrompt} +${codeChunksPrompt}` + } + + async buildHumanMessageEndPrompt( + conversation: Conversation, + chatContext: ChatContext + ): Promise { + const hasAttachedFiles = this.checkForAttachedFiles(chatContext) + const fileContextPrompt = hasAttachedFiles ? FILE_CONTEXT_PROMPT : '' + + return fileContextPrompt + } + + async buildHumanMessageImageUrls( + conversation: Conversation + ): Promise { + const state = conversation.pluginStates?.[PluginId.Fs] as + | Partial + | undefined + + if (!state) return [] + + const { selectedImagesFromOutsideUrl } = state + const { imageBase64Urls } = await this.buildFilePrompts(state) + return removeDuplicates([ + ...(selectedImagesFromOutsideUrl?.map(image => image.url) || []), + ...imageBase64Urls + ]) + } + + async buildAgentTools( + options: BaseStrategyOptions, + state: ChatGraphState + ): Promise { + const tools = await Promise.all([createCodebaseSearchTool(options, state)]) + return tools.filter(Boolean) as StructuredTool[] + } + + async buildLanggraphToolNodes( + options: BaseStrategyOptions + ): Promise { + return [createCodebaseSearchNode(options)] + } + + private checkForAttachedFiles(chatContext: ChatContext): boolean { + return chatContext.conversations.some(conversation => { + const { + selectedFilesFromEditor = [], + selectedFoldersFromEditor = [], + codeSnippetFromAgent = [] + } = (conversation.pluginStates?.[PluginId.Fs] as + | Partial + | undefined) || {} + + return ( + selectedFilesFromEditor.length > 0 || + selectedFoldersFromEditor.length > 0 || + codeSnippetFromAgent.length > 0 + ) + }) + } + + private async buildFilePrompts( + state: Partial + ): Promise { + const result: BuildFilePromptsResult = { + selectedFilesPrompt: '', + currentFilesPrompt: '', + imageBase64Urls: [] + } + + const workspacePath = getWorkspaceFolder().uri.fsPath + const currentFilePaths = new Set( + state.currentFilesFromVSCode?.map(file => file.fullPath) + ) + const processedFiles = new Set() + + const filesOrFolders = removeDuplicates( + [ + ...(state.selectedFilesFromEditor || []), + ...(state.selectedFilesFromFileSelector || []), + ...(state.selectedFoldersFromEditor || []) + ], + ['fullPath'] + ).map(file => file.fullPath) + + const shouldIgnore = await createShouldIgnore( + workspacePath, + IGNORE_FILETYPES_WITHOUT_IMG + ) + + await traverseFileOrFolders({ + type: 'file', + filesOrFolders, + workspacePath, + customShouldIgnore: shouldIgnore, + itemCallback: async (fileInfo: FileInfo) => { + if (processedFiles.has(fileInfo.fullPath)) return + + if ( + AI_SUPPORT_IMG_EXT.some(ext => + fileInfo.fullPath.toLowerCase().endsWith(`.${ext}`) + ) + ) { + const fileContent = await VsCodeFS.readFile( + fileInfo.fullPath, + 'base64' + ) + result.imageBase64Urls.push(fileContent) + } else { + const fileContent = await getFileContent(fileInfo) + const formattedSnippet = formatCodeSnippet({ + relativePath: fileInfo.relativePath, + code: fileContent, + showLine: false + }) + if (currentFilePaths.has(fileInfo.fullPath)) { + result.currentFilesPrompt += formattedSnippet + } else { + result.selectedFilesPrompt += formattedSnippet + } + } + + processedFiles.add(fileInfo.fullPath) + } + }) + + if (result.currentFilesPrompt) { + result.currentFilesPrompt = ` +## Current Files +Here is the file I'm looking at. It might be truncated from above and below and, if so, is centered around my cursor. + +${result.currentFilesPrompt} +` + } + + return result + } + + private async buildCodeSnippetsPrompt( + state: Partial + ): Promise { + const { + enableCodebaseAgent, + codeSnippetFromAgent: codeSnippetFromCodebaseAgent + } = state + + if (!enableCodebaseAgent || !codeSnippetFromCodebaseAgent?.length) return '' + + const mergedSnippets = await mergeCodeSnippets(codeSnippetFromCodebaseAgent) + + const snippetsContent = mergedSnippets + .map(snippet => + formatCodeSnippet({ + relativePath: snippet.relativePath, + code: snippet.code, + startLine: snippet.startLine, + endLine: snippet.endLine, + showLine: true + }) + ) + .join('') + + return snippetsContent + ? ` +## Potentially Relevant Code Snippets from the current Codebase + +${snippetsContent} +${CONTENT_SEPARATOR} +` + : '' + } + + private buildCodeChunksPrompt(state: Partial): string { + const { codeChunksFromEditor } = state + + if (!codeChunksFromEditor?.length) return '' + + const chunksContent = removeDuplicates(codeChunksFromEditor, [ + 'relativePath', + 'code' + ]) + .map(chunk => + formatCodeSnippet({ + relativePath: chunk.relativePath, + code: chunk.code, + language: chunk.language, + startLine: chunk.startLine, + endLine: chunk.endLine, + showLine: Boolean(chunk.startLine && chunk.endLine) + }) + ) + .join('') + + return chunksContent + } +} + +const COMMON_SYSTEM_PROMPT = ` +You are an intelligent programmer, powered by GPT-4. You are happy to help answer any questions that the user has (usually they will be about coding). You will be given the context of the code in their file(s) and potentially relevant blocks of code. + +1. Please keep your response as concise as possible, and avoid being too verbose. + +2. Do not lie or make up facts. + +3. If a user messages you in a foreign language, please respond in that language. + +4. Format your response in markdown. + +5. When referencing code blocks in your answer, keep the following guidelines in mind: + + a. Never include line numbers in the output code. + + b. When outputting new code blocks, please specify the language ID after the initial backticks: +\`\`\`python +{{ code }} +\`\`\` + + c. When outputting code blocks for an existing file, include the file path after the initial backticks: +\`\`\`python:src/backend/main.py +{{ code }} +\`\`\` + + d. When referencing a code block the user gives you, only reference the start and end line numbers of the relevant code: +\`\`\`typescript:app/components/Todo.tsx +startLine: 2 +endLine: 30 +\`\`\` +` + +const CHAT_WITH_FILE_SYSTEM_PROMPT = ` +You are an intelligent programmer, powered by GPT-4o. You are happy to help answer any questions that the user has (usually they will be about coding). + +1. Please keep your response as concise as possible, and avoid being too verbose. + +2. When the user is asking for edits to their code, please output a simplified version of the code block that highlights the changes necessary and adds comments to indicate where unchanged code has been skipped. For example: +\`\`\`file_path +// ... existing code ... +{{ edit_1 }} +// ... existing code ... +{{ edit_2 }} +// ... existing code ... +\`\`\` +The user can see the entire file, so they prefer to only read the updates to the code. Often this will mean that the start/end of the file will be skipped, but that's okay! Rewrite the entire file only if specifically requested. Always provide a brief explanation of the updates, unless the user specifically requests only the code. + +3. Do not lie or make up facts. + +4. If a user messages you in a foreign language, please respond in that language. + +5. Format your response in markdown. + +6. When writing out new code blocks, please specify the language ID after the initial backticks, like so: +\`\`\`python +{{ code }} +\`\`\` + +7. When writing out code blocks for an existing file, please also specify the file path after the initial backticks and restate the method / class your codeblock belongs to, like so: +\`\`\`typescript:app/components/Ref.tsx +function AIChatHistory() { + ... + {{ code }} + ... +} +\`\`\` +` + +const FILE_CONTEXT_PROMPT = ` +If you need to reference any of the code blocks I gave you, only output the start and end line numbers. For example: +\`\`\`typescript:app/components/Todo.tsx +startLine: 200 +endLine: 310 +\`\`\` + +If you are writing code, do not include the "line_number|" before each line of code. +` + +const CONTENT_SEPARATOR = ` + + +------- + + + +------- + + +` diff --git a/src/shared/plugins/fs-plugin/server/fs-server-plugin.ts b/src/shared/plugins/fs-plugin/server/fs-server-plugin.ts new file mode 100644 index 0000000..7a280aa --- /dev/null +++ b/src/shared/plugins/fs-plugin/server/fs-server-plugin.ts @@ -0,0 +1,30 @@ +import type { + ServerPlugin, + ServerPluginContext +} from '@shared/plugins/base/server/server-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' + +import type { FsPluginState } from '../types' +import { FsChatStrategyProvider } from './chat-strategy/fs-chat-strategy-provider' + +export class FsServerPlugin implements ServerPlugin { + id = PluginId.Fs + + version: string = pkg.version + + private context: ServerPluginContext | null = null + + async activate(context: ServerPluginContext): Promise { + this.context = context + + this.context.registerProvider( + 'chatStrategy', + () => new FsChatStrategyProvider() + ) + } + + deactivate(): void { + this.context = null + } +} diff --git a/src/extension/webview-api/chat-context-processor/utils/merge-code-snippets.ts b/src/shared/plugins/fs-plugin/server/merge-code-snippets.ts similarity index 97% rename from src/extension/webview-api/chat-context-processor/utils/merge-code-snippets.ts rename to src/shared/plugins/fs-plugin/server/merge-code-snippets.ts index 86818f7..09045e0 100644 --- a/src/extension/webview-api/chat-context-processor/utils/merge-code-snippets.ts +++ b/src/shared/plugins/fs-plugin/server/merge-code-snippets.ts @@ -1,6 +1,5 @@ import { VsCodeFS } from '@extension/file-utils/vscode-fs' - -import type { CodeSnippet } from '../types/chat-context' +import type { CodeSnippet } from '@shared/plugins/fs-plugin/types' export type MergeCodeSnippetsMode = 'default' | 'expanded' diff --git a/src/shared/plugins/fs-plugin/types.ts b/src/shared/plugins/fs-plugin/types.ts new file mode 100644 index 0000000..68feb38 --- /dev/null +++ b/src/shared/plugins/fs-plugin/types.ts @@ -0,0 +1,36 @@ +import type { FileInfo, FolderInfo } from '@extension/file-utils/traverse-fs' + +export interface CodeSnippet { + fileHash: string + relativePath: string + fullPath: string + startLine: number + startCharacter: number + endLine: number + endCharacter: number + code: string +} + +export interface CodeChunk { + code: string + language: string + relativePath?: string + fullPath?: string + startLine?: number + endLine?: number +} + +export interface ImageInfo { + url: string +} + +export interface FsPluginState { + selectedFilesFromFileSelector: FileInfo[] + selectedFilesFromEditor: FileInfo[] + currentFilesFromVSCode: FileInfo[] + selectedFoldersFromEditor: FolderInfo[] + selectedImagesFromOutsideUrl: ImageInfo[] + codeChunksFromEditor: CodeChunk[] + codeSnippetFromAgent: CodeSnippet[] + enableCodebaseAgent: boolean +} diff --git a/src/shared/plugins/git-plugin/client/git-client-plugin.tsx b/src/shared/plugins/git-plugin/client/git-client-plugin.tsx new file mode 100644 index 0000000..20946a2 --- /dev/null +++ b/src/shared/plugins/git-plugin/client/git-client-plugin.tsx @@ -0,0 +1,146 @@ +import { CommitIcon, MaskOffIcon, TransformIcon } from '@radix-ui/react-icons' +import type { + ClientPlugin, + ClientPluginContext +} from '@shared/plugins/base/client/client-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' +import { api } from '@webview/services/api-client' +import { type MentionOption } from '@webview/types/chat' + +import type { GitCommit, GitPluginState } from '../types' + +export class GitClientPlugin implements ClientPlugin { + id = PluginId.Git + + version: string = pkg.version + + private context: ClientPluginContext | null = null + + getInitState() { + return { + gitCommitsFromEditor: [], + gitDiffWithMainBranchFromEditor: null, + gitDiffOfWorkingStateFromEditor: null + } + } + + async activate(context: ClientPluginContext): Promise { + this.context = context + + this.context.registerProvider('state', () => this.context!.state) + this.context.registerProvider('editor', () => ({ + getMentionOptions: this.getMentionOptions.bind(this) + })) + } + + deactivate(): void { + this.context?.resetState() + this.context = null + } + + private async getMentionOptions(): Promise { + if (!this.context) return [] + + const gitCommits = await this.context.getQueryClient().fetchQuery({ + queryKey: ['realtime', 'git-commits'], + queryFn: () => + api.git.getHistoryCommits({ + maxCount: 50 + }) + }) + + const gitCommitsMentionOptions: MentionOption[] = gitCommits.map( + commit => + ({ + id: `${PluginId.Git}#git-commit#${commit.sha}`, + type: `${PluginId.Git}#git-commit`, + label: commit.message, + data: commit, + onAddOne: data => { + this.context?.setState(draft => { + draft.gitCommitsFromEditor.push(data) + }) + }, + onRemoveOne: data => { + this.context?.setState(draft => { + draft.gitCommitsFromEditor = draft.gitCommitsFromEditor.filter( + item => item.sha !== data.sha + ) + }) + }, + onReplaceAll: dataArr => { + this.context?.setState(draft => { + draft.gitCommitsFromEditor = dataArr + }) + }, + + searchKeywords: [commit.sha, commit.message], + itemLayoutProps: { + icon: , + label: commit.message, + details: commit.sha + } + }) satisfies MentionOption + ) + + return [ + { + id: `${PluginId.Git}#git`, + type: `${PluginId.Git}#git`, + label: 'Git', + topLevelSort: 5, + searchKeywords: ['git'], + itemLayoutProps: { + icon: , + label: 'Git' + }, + children: [ + { + id: `${PluginId.Git}#git-diff`, + type: `${PluginId.Git}#git-diff`, + label: 'Diff (Diff of Working State)', + // TODO: add data + onAddOne: data => { + this.context?.setState(draft => { + draft.gitDiffOfWorkingStateFromEditor = data + }) + }, + onReplaceAll: dataArr => { + this.context?.setState(draft => { + draft.gitDiffOfWorkingStateFromEditor = dataArr.at(-1) + }) + }, + searchKeywords: ['diff'], + itemLayoutProps: { + icon: , + label: 'Diff (Diff of Working State)' + } + }, + { + id: `${PluginId.Git}#git-pr`, + type: `${PluginId.Git}#git-pr`, + label: 'PR (Diff with Main Branch)', + // TODO: add data + onAddOne: data => { + this.context?.setState(draft => { + draft.gitDiffWithMainBranchFromEditor = data + }) + }, + onReplaceAll: dataArr => { + this.context?.setState(draft => { + draft.gitDiffWithMainBranchFromEditor = dataArr.at(-1) + }) + }, + searchKeywords: ['pull request', 'pr', 'diff'], + itemLayoutProps: { + icon: , + label: 'PR (Diff with Main Branch)' + } + }, + ...gitCommitsMentionOptions + ] + } + ] + } +} diff --git a/src/shared/plugins/git-plugin/server/chat-strategy/git-chat-strategy-provider.ts b/src/shared/plugins/git-plugin/server/chat-strategy/git-chat-strategy-provider.ts new file mode 100644 index 0000000..57a03b0 --- /dev/null +++ b/src/shared/plugins/git-plugin/server/chat-strategy/git-chat-strategy-provider.ts @@ -0,0 +1,97 @@ +import type { ChatStrategyProvider } from '@shared/plugins/base/server/create-provider-manager' +import { PluginId } from '@shared/plugins/base/types' +import type { Conversation } from '@shared/types/chat-context/conversation' +import { removeDuplicates } from '@shared/utils/common' + +import type { GitDiff, GitPluginState } from '../../types' + +export class GitChatStrategyProvider implements ChatStrategyProvider { + async buildContextMessagePrompt(conversation: Conversation): Promise { + const state = conversation.pluginStates?.[PluginId.Git] as + | Partial + | undefined + + if (!state) return '' + + const diffWithMainBranchPrompt = + this.buildGitDiffWithMainBranchPrompt(state) + const diffOfWorkingStatePrompt = + this.buildGitDiffOfWorkingStatePrompt(state) + const commitPrompt = this.buildGitCommitPrompt(state) + + const prompts = [ + diffWithMainBranchPrompt, + diffOfWorkingStatePrompt, + commitPrompt + ].filter(Boolean) + + return prompts.join('\n\n') + } + + private buildGitCommitPrompt(state: Partial): string { + const { gitCommitsFromEditor = [] } = state + + if (!gitCommitsFromEditor.length) return '' + + let gitCommitContent = ` +## Git Commits + ` + + removeDuplicates(gitCommitsFromEditor, ['sha']).forEach(commit => { + gitCommitContent += ` +Commit: ${commit.sha} +Message: ${commit.message} +Author: ${commit.author} +Date: ${commit.date} +Diffs: +${this.buildGitDiffsPrompt(commit.diff)} +` + }) + + return gitCommitContent + } + + private buildGitDiffWithMainBranchPrompt( + state: Partial + ): string { + const { gitDiffWithMainBranchFromEditor } = state + + if (!gitDiffWithMainBranchFromEditor) return '' + + return ` +## Git Diff with Main Branch +${this.buildGitDiffsPrompt([gitDiffWithMainBranchFromEditor])} +` + } + + private buildGitDiffOfWorkingStatePrompt( + state: Partial + ): string { + const { gitDiffOfWorkingStateFromEditor } = state + + if (!gitDiffOfWorkingStateFromEditor) return '' + + return ` +## Git Diff of Working State +${this.buildGitDiffsPrompt([gitDiffOfWorkingStateFromEditor])} +` + } + + private buildGitDiffsPrompt(gitDiffs: GitDiff[] | undefined): string { + if (!gitDiffs?.length) return '' + + let gitDiffContent = '' + + gitDiffs.forEach(diff => { + gitDiffContent += ` +File: ${diff.from} → ${diff.to} +Changes: +${diff.chunks + .map(chunk => chunk.content + chunk.lines.map(line => line).join('\n')) + .join('\n')} +` + }) + + return gitDiffContent + } +} diff --git a/src/shared/plugins/git-plugin/server/git-server-plugin.ts b/src/shared/plugins/git-plugin/server/git-server-plugin.ts new file mode 100644 index 0000000..b311054 --- /dev/null +++ b/src/shared/plugins/git-plugin/server/git-server-plugin.ts @@ -0,0 +1,30 @@ +import type { + ServerPlugin, + ServerPluginContext +} from '@shared/plugins/base/server/server-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' + +import type { GitPluginState } from '../types' +import { GitChatStrategyProvider } from './chat-strategy/git-chat-strategy-provider' + +export class GitServerPlugin implements ServerPlugin { + id = PluginId.Git + + version: string = pkg.version + + private context: ServerPluginContext | null = null + + async activate(context: ServerPluginContext): Promise { + this.context = context + + this.context.registerProvider( + 'chatStrategy', + () => new GitChatStrategyProvider() + ) + } + + deactivate(): void { + this.context = null + } +} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/git-context.ts b/src/shared/plugins/git-plugin/types.ts similarity index 73% rename from src/extension/webview-api/chat-context-processor/types/chat-context/git-context.ts rename to src/shared/plugins/git-plugin/types.ts index 02899e3..262a8b9 100644 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/git-context.ts +++ b/src/shared/plugins/git-plugin/types.ts @@ -1,6 +1,4 @@ -import type { BaseContextInfo } from './base-context' - -export interface GitDiff extends BaseContextInfo { +export interface GitDiff { /** * @example '.github/workflows/ci.yml' */ @@ -31,7 +29,7 @@ export interface GitDiff extends BaseContextInfo { }[] } -export interface GitCommit extends BaseContextInfo { +export interface GitCommit { /** * @example '0bc7f06aa2930c2755c751615cfb2331de41ddb1' */ @@ -47,7 +45,8 @@ export interface GitCommit extends BaseContextInfo { date: string } -export interface GitContext { - gitCommits: GitCommit[] - gitDiffs: GitDiff[] +export interface GitPluginState { + gitCommitsFromEditor: GitCommit[] + gitDiffWithMainBranchFromEditor: GitDiff | null + gitDiffOfWorkingStateFromEditor: GitDiff | null } diff --git a/src/shared/plugins/web-plugin/client/web-client-plugin.tsx b/src/shared/plugins/web-plugin/client/web-client-plugin.tsx new file mode 100644 index 0000000..9f943ad --- /dev/null +++ b/src/shared/plugins/web-plugin/client/web-client-plugin.tsx @@ -0,0 +1,73 @@ +import { GlobeIcon } from '@radix-ui/react-icons' +import type { + ClientPlugin, + ClientPluginContext +} from '@shared/plugins/base/client/client-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' +import { type MentionOption } from '@webview/types/chat' + +import type { WebPluginState } from '../types' + +export class WebClientPlugin implements ClientPlugin { + id = PluginId.Web + + version: string = pkg.version + + private context: ClientPluginContext | null = null + + getInitState() { + return { + enableWebSearchAgent: false, + webSearchResultsFromAgent: [], + webSearchAsDocFromAgent: [], + enableWebVisitAgent: false, + webVisitResultsFromAgent: [] + } + } + + async activate(context: ClientPluginContext): Promise { + this.context = context + + this.context.registerProvider('state', () => this.context!.state) + this.context.registerProvider('editor', () => ({ + getMentionOptions: this.getMentionOptions.bind(this) + })) + } + + deactivate(): void { + this.context?.resetState() + this.context = null + } + + private async getMentionOptions(): Promise { + if (!this.context) return [] + + return [ + { + id: `${PluginId.Web}#web`, + type: `${PluginId.Web}#web`, + label: 'Web', + data: true, + onAddOne: () => { + this.context?.setState(draft => { + draft.enableWebVisitAgent = true + draft.enableWebSearchAgent = true + }) + }, + onReplaceAll: (dataArr: true[]) => { + this.context?.setState(draft => { + draft.enableWebVisitAgent = dataArr.length > 0 + draft.enableWebSearchAgent = dataArr.length > 0 + }) + }, + topLevelSort: 3, + searchKeywords: ['web'], + itemLayoutProps: { + icon: , + label: 'Web' + } + } + ] + } +} diff --git a/src/shared/plugins/web-plugin/server/chat-strategy/web-chat-strategy-provider.ts b/src/shared/plugins/web-plugin/server/chat-strategy/web-chat-strategy-provider.ts new file mode 100644 index 0000000..30ad9da --- /dev/null +++ b/src/shared/plugins/web-plugin/server/chat-strategy/web-chat-strategy-provider.ts @@ -0,0 +1,89 @@ +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import type { + ChatGraphNode, + ChatGraphState +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' +import type { StructuredTool } from '@langchain/core/tools' +import type { ChatStrategyProvider } from '@shared/plugins/base/server/create-provider-manager' +import { PluginId } from '@shared/plugins/base/types' +import type { Conversation } from '@shared/types/chat-context/conversation' +import { removeDuplicates } from '@shared/utils/common' + +import type { WebPluginState } from '../../types' +import { createWebSearchNode, createWebSearchTool } from './web-search-node' +import { createWebVisitNode, createWebVisitTool } from './web-visit-node' + +export class WebChatStrategyProvider implements ChatStrategyProvider { + async buildContextMessagePrompt(conversation: Conversation): Promise { + const state = conversation.pluginStates?.[PluginId.Web] as + | Partial + | undefined + + if (!state) return '' + + const relevantWebsPrompt = this.buildRelevantWebsPrompt(state) + + const prompts = [relevantWebsPrompt].filter(Boolean) + + return prompts.join('\n\n') + } + + async buildAgentTools( + options: BaseStrategyOptions, + state: ChatGraphState + ): Promise { + const tools = await Promise.all([ + createWebSearchTool(options, state), + createWebVisitTool(options, state) + ]) + return tools.filter(Boolean) as StructuredTool[] + } + + async buildLanggraphToolNodes( + options: BaseStrategyOptions + ): Promise { + return [createWebSearchNode(options), createWebVisitNode(options)] + } + + private buildRelevantWebsPrompt(state: Partial): string { + const { webSearchAsDocFromAgent = [], webVisitResultsFromAgent = [] } = + state + + const webDocs = [ + ...webSearchAsDocFromAgent, + ...removeDuplicates(webVisitResultsFromAgent, ['url']) + ] + + if (!webDocs.length) return '' + + let webContent = '' + + webDocs.forEach(webDoc => { + webContent += ` +Source Url: ${webDoc.url} +Content: ${webDoc.content} +` + }) + + return webContent + ? ` +## Potentially Relevant Webs + +${webContent} +${CONTENT_SEPARATOR} +` + : '' + } +} + +const CONTENT_SEPARATOR = ` + + +------- + + + +------- + + +` diff --git a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/web-search-node.ts b/src/shared/plugins/web-plugin/server/chat-strategy/web-search-node.ts similarity index 54% rename from src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/web-search-node.ts rename to src/shared/plugins/web-plugin/server/chat-strategy/web-search-node.ts index 0c0143d..46c1f80 100644 --- a/src/extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/web-search-node.ts +++ b/src/shared/plugins/web-plugin/server/chat-strategy/web-search-node.ts @@ -1,39 +1,44 @@ import { createModelProvider } from '@extension/ai/helpers' +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import { ChatMessagesConstructor } from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/messages-constructors/chat-messages-constructor' import { - ContextInfoSource, - type WebSearchResult -} from '@extension/webview-api/chat-context-processor/types/chat-context' -import type { LangchainTool } from '@extension/webview-api/chat-context-processor/types/langchain-message' + type ChatGraphState, + type CreateChatGraphNode +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' import { findCurrentToolsCallParams } from '@extension/webview-api/chat-context-processor/utils/find-current-tools-call-params' import { searxngSearch } from '@extension/webview-api/chat-context-processor/utils/searxng-search' import { CheerioWebBaseLoader } from '@langchain/community/document_loaders/web/cheerio' import type { Document } from '@langchain/core/documents' import { HumanMessage, type ToolMessage } from '@langchain/core/messages' import { DynamicStructuredTool } from '@langchain/core/tools' +import { PluginId } from '@shared/plugins/base/types' +import type { LangchainTool } from '@shared/types/chat-context/langchain-message' import { settledPromiseResults } from '@shared/utils/common' +import { produce } from 'immer' import { z } from 'zod' -import { ChatMessagesConstructor } from '../messages-constructors/chat-messages-constructor' -import { - ChatGraphToolName, - type ChatGraphNode, - type ChatGraphState -} from './state' +import type { WebDocInfo, WebPluginState } from '../../types' interface WebSearchToolResult { relevantContent: string - webSearchResults: WebSearchResult[] + webSearchResults: WebDocInfo[] } const MAX_CONTENT_LENGTH = 16 * 1000 -export const createWebSearchTool = async (state: ChatGraphState) => { +export const createWebSearchTool = async ( + options: BaseStrategyOptions, + state: ChatGraphState +) => { const { chatContext } = state const { conversations } = chatContext const lastConversation = conversations.at(-1) - const webContext = lastConversation?.attachments?.webContext - if (!webContext || !webContext.enableTool) return null + const webPluginState = lastConversation?.pluginStates?.[PluginId.Web] as + | Partial + | undefined + + if (!webPluginState?.enableWebSearchAgent) return null const getRelevantContentAndSearchResults = async ( state: ChatGraphState, @@ -53,9 +58,10 @@ export const createWebSearchTool = async (state: ChatGraphState) => { .join('\n') .slice(0, MAX_CONTENT_LENGTH) - const chatMessagesConstructor = new ChatMessagesConstructor( - state.chatContext - ) + const chatMessagesConstructor = new ChatMessagesConstructor({ + ...options, + chatContext: state.chatContext + }) const messagesFromChatContext = await chatMessagesConstructor.constructMessages() @@ -98,7 +104,7 @@ Please provide a relevant and focused summary based on this content and the user } return new DynamicStructuredTool({ - name: ChatGraphToolName.WebSearch, + name: 'webSearch', description: 'search web', func: async ({ keywords }): Promise => { const { relevantContent, webSearchResults } = @@ -115,49 +121,62 @@ Please provide a relevant and focused summary based on this content and the user }) } -export const webSearchNode: ChatGraphNode = async state => { - const { messages, chatContext } = state - const { conversations } = chatContext - const lastConversation = conversations.at(-1) - const webContext = lastConversation?.attachments?.webContext - - if (!webContext || !webContext.enableTool) return {} - - const webRetrieverTool = await createWebSearchTool(state) - - if (!webRetrieverTool) return {} - - const tools: LangchainTool[] = [webRetrieverTool] - const lastMessage = messages.at(-1) - const toolCalls = findCurrentToolsCallParams(lastMessage, tools) - - if (!toolCalls.length) return {} - - const toolCallsPromises = toolCalls.map(async toolCall => { - const toolMessage = (await webRetrieverTool.invoke(toolCall)) as ToolMessage - - const result = JSON.parse( - toolMessage?.lc_kwargs.content - ) as WebSearchToolResult - - lastConversation.attachments!.docContext.relevantDocs = [ - ...lastConversation.attachments!.docContext.relevantDocs, - { - path: '', - content: result.relevantContent, - source: ContextInfoSource.ToolNode - } - ] - - lastConversation.attachments!.webContext.webSearchResults = [ - ...lastConversation.attachments!.webContext.webSearchResults, - ...result.webSearchResults - ] - }) +export const createWebSearchNode: CreateChatGraphNode = + options => async state => { + const { messages, chatContext } = state + const { conversations } = chatContext + const lastConversation = conversations.at(-1) + const webPluginState = lastConversation?.pluginStates?.[PluginId.Web] as + | Partial + | undefined + + if (!webPluginState?.enableWebSearchAgent) return {} + + const webRetrieverTool = await createWebSearchTool(options, state) + + if (!webRetrieverTool) return {} + + const tools: LangchainTool[] = [webRetrieverTool] + const lastMessage = messages.at(-1) + const toolCalls = findCurrentToolsCallParams(lastMessage, tools) + + if (!toolCalls.length) return {} + + const toolCallsPromises = toolCalls.map(async toolCall => { + const toolMessage = (await webRetrieverTool.invoke( + toolCall + )) as ToolMessage + + const result = JSON.parse( + toolMessage?.lc_kwargs.content + ) as WebSearchToolResult + + lastConversation!.pluginStates![PluginId.Web] = produce( + lastConversation!.pluginStates![ + PluginId.Web + ] as Partial, + (draft: Partial) => { + if (!draft.webSearchAsDocFromAgent) { + draft.webSearchAsDocFromAgent = [] + } + + if (!draft.webSearchResultsFromAgent) { + draft.webSearchResultsFromAgent = [] + } + + draft.webSearchAsDocFromAgent.push({ + url: '', + content: result.relevantContent + }) + + draft.webSearchResultsFromAgent.push(...result.webSearchResults) + } + ) + }) - await settledPromiseResults(toolCallsPromises) + await settledPromiseResults(toolCallsPromises) - return { - chatContext + return { + chatContext + } } -} diff --git a/src/shared/plugins/web-plugin/server/chat-strategy/web-visit-node.ts b/src/shared/plugins/web-plugin/server/chat-strategy/web-visit-node.ts new file mode 100644 index 0000000..5988591 --- /dev/null +++ b/src/shared/plugins/web-plugin/server/chat-strategy/web-visit-node.ts @@ -0,0 +1,104 @@ +/* eslint-disable unused-imports/no-unused-vars */ +import type { BaseStrategyOptions } from '@extension/webview-api/chat-context-processor/strategies/base-strategy' +import { + type ChatGraphState, + type CreateChatGraphNode +} from '@extension/webview-api/chat-context-processor/strategies/chat-strategy/nodes/state' +import { DocCrawler } from '@extension/webview-api/chat-context-processor/utils/doc-crawler' +import { findCurrentToolsCallParams } from '@extension/webview-api/chat-context-processor/utils/find-current-tools-call-params' +import type { ToolMessage } from '@langchain/core/messages' +import { DynamicStructuredTool } from '@langchain/core/tools' +import { PluginId } from '@shared/plugins/base/types' +import type { LangchainTool } from '@shared/types/chat-context/langchain-message' +import { settledPromiseResults } from '@shared/utils/common' +import { produce } from 'immer' +import { z } from 'zod' + +import type { WebDocInfo, WebPluginState } from '../../types' + +interface WebVisitToolResult { + contents: WebDocInfo[] +} + +export const createWebVisitTool = async ( + options: BaseStrategyOptions, + state: ChatGraphState +) => { + const getPageContents = async (urls: string[]): Promise => { + const docCrawler = new DocCrawler(urls[0]!) + const contents = await settledPromiseResults( + urls.map(async url => ({ + url, + content: + (await docCrawler.getPageContent(url)) || 'Failed to retrieve content' + })) + ) + return contents + } + + return new DynamicStructuredTool({ + name: 'webVisit', + description: + 'Visit specific web pages and retrieve their content. Use this tool when you need to access and analyze the content of one or more web pages.', + func: async ({ urls }): Promise => { + const contents = await getPageContents(urls) + return { contents } + }, + schema: z.object({ + urls: z + .array(z.string().url()) + .describe( + 'An array of URLs to visit and retrieve content from. Each URL should be a valid web address.' + ) + }) + }) +} + +export const createWebVisitNode: CreateChatGraphNode = + options => async state => { + const { messages, chatContext } = state + const { conversations } = chatContext + const lastConversation = conversations.at(-1) + const webPluginState = lastConversation?.pluginStates?.[PluginId.Web] as + | Partial + | undefined + + if (!webPluginState?.enableWebVisitAgent) return {} + + const webVisitTool = await createWebVisitTool(options, state) + + if (!webVisitTool) return {} + + const tools: LangchainTool[] = [webVisitTool] + const lastMessage = messages.at(-1) + const toolCalls = findCurrentToolsCallParams(lastMessage, tools) + + if (!toolCalls.length) return {} + + const toolCallsPromises = toolCalls.map(async toolCall => { + const toolMessage = (await webVisitTool.invoke(toolCall)) as ToolMessage + + const result = JSON.parse( + toolMessage?.lc_kwargs.content + ) as WebVisitToolResult + + lastConversation!.pluginStates![PluginId.Web] = produce( + lastConversation!.pluginStates![ + PluginId.Web + ] as Partial, + (draft: Partial) => { + if (!draft.webVisitResultsFromAgent) { + draft.webVisitResultsFromAgent = [] + } + + draft.webVisitResultsFromAgent.push(...result.contents) + } + ) + }) + + await settledPromiseResults(toolCallsPromises) + + return { + chatContext + } + } diff --git a/src/shared/plugins/web-plugin/server/web-server-plugin.ts b/src/shared/plugins/web-plugin/server/web-server-plugin.ts new file mode 100644 index 0000000..3e55453 --- /dev/null +++ b/src/shared/plugins/web-plugin/server/web-server-plugin.ts @@ -0,0 +1,30 @@ +import type { + ServerPlugin, + ServerPluginContext +} from '@shared/plugins/base/server/server-plugin-context' +import { PluginId } from '@shared/plugins/base/types' +import { pkg } from '@shared/utils/pkg' + +import type { WebPluginState } from '../types' +import { WebChatStrategyProvider } from './chat-strategy/web-chat-strategy-provider' + +export class WebServerPlugin implements ServerPlugin { + id = PluginId.Web + + version: string = pkg.version + + private context: ServerPluginContext | null = null + + async activate(context: ServerPluginContext): Promise { + this.context = context + + this.context.registerProvider( + 'chatStrategy', + () => new WebChatStrategyProvider() + ) + } + + deactivate(): void { + this.context = null + } +} diff --git a/src/shared/plugins/web-plugin/types.ts b/src/shared/plugins/web-plugin/types.ts new file mode 100644 index 0000000..d3a1517 --- /dev/null +++ b/src/shared/plugins/web-plugin/types.ts @@ -0,0 +1,12 @@ +export interface WebDocInfo { + content: string + url: string +} + +export interface WebPluginState { + enableWebSearchAgent: boolean + webSearchResultsFromAgent: WebDocInfo[] + webSearchAsDocFromAgent: WebDocInfo[] + enableWebVisitAgent: boolean + webVisitResultsFromAgent: WebDocInfo[] +} diff --git a/src/shared/types/chat-context/conversation.ts b/src/shared/types/chat-context/conversation.ts new file mode 100644 index 0000000..3569fcc --- /dev/null +++ b/src/shared/types/chat-context/conversation.ts @@ -0,0 +1,12 @@ +import type { MessageType } from '@langchain/core/messages' +import type { PluginState } from '@shared/plugins/base/types' +import type { LangchainMessageContents } from '@shared/types/chat-context/langchain-message' + +export interface Conversation { + id: string + createdAt: number + role: MessageType + contents: LangchainMessageContents + richText?: string // JSON stringified + pluginStates: Record +} diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/index.ts b/src/shared/types/chat-context/index.ts similarity index 58% rename from src/extension/webview-api/chat-context-processor/types/chat-context/index.ts rename to src/shared/types/chat-context/index.ts index 3f64a8a..8fc1643 100644 --- a/src/extension/webview-api/chat-context-processor/types/chat-context/index.ts +++ b/src/shared/types/chat-context/index.ts @@ -1,6 +1,12 @@ import type { Conversation } from './conversation' import type { SettingsContext } from './settings-context' +export type { Conversation, SettingsContext } +export type { + LangchainMessage, + LangchainMessageContents +} from './langchain-message' + export enum ChatContextType { Chat = 'chat', Composer = 'composer', @@ -16,13 +22,3 @@ export interface ChatContext { conversations: Conversation[] settings: SettingsContext } - -export * from './base-context' -export * from './code-context' -export * from './codebase-context' -export * from './conversation' -export * from './doc-context' -export * from './file-context' -export * from './git-context' -export * from './settings-context' -export * from './web-context' diff --git a/src/extension/webview-api/chat-context-processor/types/langchain-message.ts b/src/shared/types/chat-context/langchain-message.ts similarity index 88% rename from src/extension/webview-api/chat-context-processor/types/langchain-message.ts rename to src/shared/types/chat-context/langchain-message.ts index cc513db..fa8d780 100644 --- a/src/extension/webview-api/chat-context-processor/types/langchain-message.ts +++ b/src/shared/types/chat-context/langchain-message.ts @@ -1,10 +1,10 @@ -import { +import type { AIMessage, + ChatMessage, + FunctionMessage, HumanMessage, SystemMessage, - type ChatMessage, - type FunctionMessage, - type ToolMessage + ToolMessage } from '@langchain/core/messages' import type { RunnableToolLike } from '@langchain/core/runnables' import type { StructuredToolInterface } from '@langchain/core/tools' diff --git a/src/extension/webview-api/chat-context-processor/types/chat-context/settings-context.ts b/src/shared/types/chat-context/settings-context.ts similarity index 100% rename from src/extension/webview-api/chat-context-processor/types/chat-context/settings-context.ts rename to src/shared/types/chat-context/settings-context.ts diff --git a/src/shared/utils/common.ts b/src/shared/utils/common.ts index 5117990..db9d187 100644 --- a/src/shared/utils/common.ts +++ b/src/shared/utils/common.ts @@ -47,13 +47,22 @@ export const tryStringifyJSON = (obj: any) => { } } -export async function settledPromiseResults( - promises: Promise[] -): Promise { +export const settledPromiseResults = async ( + promises: Promise[], + onError?: (error: any) => void +): Promise => { + // eslint-disable-next-line no-console + onError ||= err => console.debug('settledPromiseResults error:', err) const results = await Promise.allSettled(promises) + return results .map((result, index) => ({ result, index })) - .filter(item => item.result.status === 'fulfilled') + .filter(item => { + if (item.result.status === 'rejected' && onError) { + onError((item.result as PromiseRejectedResult).reason) + } + return item.result.status === 'fulfilled' + }) .sort((a, b) => a.index - b.index) .map(item => (item.result as PromiseFulfilledResult).value) } diff --git a/src/shared/utils/convert-to-langchain-message-contents.ts b/src/shared/utils/convert-to-langchain-message-contents.ts index 20a56f9..8656792 100644 --- a/src/shared/utils/convert-to-langchain-message-contents.ts +++ b/src/shared/utils/convert-to-langchain-message-contents.ts @@ -1,5 +1,5 @@ -import type { LangchainMessageContents } from '@extension/webview-api/chat-context-processor/types/langchain-message' import type { MessageContentComplex } from '@langchain/core/messages' +import type { LangchainMessageContents } from '@shared/types/chat-context/langchain-message' export const convertToLangchainMessageContents = ( content: diff --git a/src/shared/utils/get-all-text-from-langchain-message-contents.ts b/src/shared/utils/get-all-text-from-langchain-message-contents.ts index 9dd7110..4357843 100644 --- a/src/shared/utils/get-all-text-from-langchain-message-contents.ts +++ b/src/shared/utils/get-all-text-from-langchain-message-contents.ts @@ -1,4 +1,4 @@ -import type { LangchainMessageContents } from '@extension/webview-api/chat-context-processor/types/langchain-message' +import type { LangchainMessageContents } from '@shared/types/chat-context/langchain-message' export const getAllTextFromLangchainMessageContents = ( contents: LangchainMessageContents diff --git a/src/shared/utils/get-default-conversation-attachments.ts b/src/shared/utils/get-default-conversation-attachments.ts deleted file mode 100644 index 1239822..0000000 --- a/src/shared/utils/get-default-conversation-attachments.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { Attachments } from '@extension/webview-api/chat-context-processor/types/chat-context' - -export const getDefaultConversationAttachments = (): Attachments => ({ - codeContext: { - codeChunks: [] - }, - codebaseContext: { - enableTool: false, - relevantCodeSnippets: [] - }, - docContext: { - allowSearchDocSiteNames: [], - relevantDocs: [] - }, - fileContext: { - selectedFiles: [], - selectedFolders: [], - selectedImages: [], - currentFiles: [] - }, - gitContext: { - gitCommits: [], - gitDiffs: [] - }, - webContext: { - enableTool: false, - webSearchResults: [] - } -}) diff --git a/src/shared/utils/get-default-conversation.ts b/src/shared/utils/get-default-conversation.ts index 4e1dfbd..9254f13 100644 --- a/src/shared/utils/get-default-conversation.ts +++ b/src/shared/utils/get-default-conversation.ts @@ -1,8 +1,6 @@ -import type { Conversation } from '@extension/webview-api/chat-context-processor/types/chat-context' +import type { Conversation } from '@shared/types/chat-context' import { v4 as uuidv4 } from 'uuid' -import { getDefaultConversationAttachments } from './get-default-conversation-attachments' - export const getDefaultConversation = ( role: Conversation['role'] ): Conversation => ({ @@ -10,5 +8,5 @@ export const getDefaultConversation = ( createdAt: Date.now(), role, contents: [], - attachments: getDefaultConversationAttachments() + pluginStates: {} }) diff --git a/src/shared/utils/merge-langchain-message-contents.ts b/src/shared/utils/merge-langchain-message-contents.ts index 3d3ec2c..303cc59 100644 --- a/src/shared/utils/merge-langchain-message-contents.ts +++ b/src/shared/utils/merge-langchain-message-contents.ts @@ -1,4 +1,4 @@ -import type { LangchainMessageContents } from '@extension/webview-api/chat-context-processor/types/langchain-message' +import type { LangchainMessageContents } from '@shared/types/chat-context/langchain-message' export const mergeLangchainMessageContents = ( contents: LangchainMessageContents diff --git a/src/shared/utils/pkg.ts b/src/shared/utils/pkg.ts new file mode 100644 index 0000000..af7b203 --- /dev/null +++ b/src/shared/utils/pkg.ts @@ -0,0 +1,3 @@ +import pkg from '../../../package.json' + +export { pkg } diff --git a/src/webview/components/chat/editor/chat-input.tsx b/src/webview/components/chat/editor/chat-input.tsx index d9a2290..abf7f0c 100644 --- a/src/webview/components/chat/editor/chat-input.tsx +++ b/src/webview/components/chat/editor/chat-input.tsx @@ -1,22 +1,24 @@ import { useEffect, useRef, type FC } from 'react' +import type { PluginId } from '@shared/plugins/base/types' import { tryParseJSON, tryStringifyJSON } from '@shared/utils/common' import { convertToLangchainMessageContents } from '@shared/utils/convert-to-langchain-message-contents' import { getAllTextFromLangchainMessageContents } from '@shared/utils/get-all-text-from-langchain-message-contents' import { mergeLangchainMessageContents } from '@shared/utils/merge-langchain-message-contents' import { Button } from '@webview/components/ui/button' +import { + usePluginRegistry, + WithPluginRegistryProvider +} from '@webview/contexts/plugin-registry-context' +import { useMentionOptions } from '@webview/hooks/chat/use-mention-options' +import { usePluginFilesSelectorProviders } from '@webview/hooks/chat/use-plugin-providers' import { useCloneState } from '@webview/hooks/use-clone-state' import { - AttachmentType, - ContextInfoSource, type ChatContext, type Conversation, type FileInfo } from '@webview/types/chat' -import { - getAttachmentsFromEditorState, - overrideAttachmentItemsBySource -} from '@webview/utils/attachments' import { cn } from '@webview/utils/common' +import { updatePluginStatesFromEditorState } from '@webview/utils/plugin-states' import { $createParagraphNode, $createTextNode, @@ -52,7 +54,7 @@ export interface ChatInputProps { export interface ChatInputRef extends ChatEditorRef {} -export const ChatInput: FC = ({ +const _ChatInput: FC = ({ ref, className, editorClassName, @@ -66,11 +68,23 @@ export const ChatInput: FC = ({ onSend }) => { const editorRef = useRef(null) + const { pluginRegistry, isPluginRegistryLoaded } = usePluginRegistry() + const { getSelectedFiles, setSelectedFiles } = + usePluginFilesSelectorProviders() + const mentionOptions = useMentionOptions() + const [conversation, setConversation, applyConversation] = useCloneState( _conversation, _setConversation ) + // sync conversation plugin states with plugin registry + useEffect(() => { + Object.entries(conversation.pluginStates).forEach(([pluginId, state]) => { + pluginRegistry?.setState(pluginId as PluginId, state) + }) + }, [isPluginRegistryLoaded, conversation.pluginStates]) + const handleEditorChange = async (editorState: EditorState) => { const newRichText = tryStringifyJSON(editorState.toJSON()) || '' @@ -82,12 +96,13 @@ export const ChatInput: FC = ({ editorState.read(() => $getRoot().getTextContent()) ) ) - draft.attachments = getAttachmentsFromEditorState( - editorState, - draft.attachments - ) } }) + + updatePluginStatesFromEditorState(editorState, mentionOptions) + setConversation(draft => { + draft.pluginStates = pluginRegistry?.providerManagers.state.getAll() || {} + }) } const initialEditorState = (editor: LexicalEditor) => { @@ -125,22 +140,10 @@ export const ChatInput: FC = ({ handleSend() } - const selectedFiles = - conversation.attachments?.fileContext?.selectedFiles?.filter( - file => file.source === ContextInfoSource.FileSelector - ) || [] + const selectedFiles = getSelectedFiles?.() || [] const handleSelectedFiles = (files: FileInfo[]) => { - setConversation(draft => { - draft.attachments = overrideAttachmentItemsBySource( - ContextInfoSource.FileSelector, - draft.attachments, - files.map(file => ({ - type: AttachmentType.Files, - data: file - })) - ) - }) + setSelectedFiles?.(files) } const focusOnEditor = () => editorRef.current?.focusOnEditor() @@ -235,3 +238,5 @@ export const ChatInput: FC = ({ ) } + +export const ChatInput = WithPluginRegistryProvider(_ChatInput) diff --git a/src/webview/components/chat/messages/markdown/pre/pre.tsx b/src/webview/components/chat/messages/markdown/pre/pre.tsx index 9642f4d..25d42c7 100644 --- a/src/webview/components/chat/messages/markdown/pre/pre.tsx +++ b/src/webview/components/chat/messages/markdown/pre/pre.tsx @@ -52,5 +52,3 @@ export const PreMermaid: FC = ({ {children} ) - -export default Pre diff --git a/src/webview/components/chat/selectors/context-selector.tsx b/src/webview/components/chat/selectors/context-selector.tsx index 5998745..c449e53 100644 --- a/src/webview/components/chat/selectors/context-selector.tsx +++ b/src/webview/components/chat/selectors/context-selector.tsx @@ -1,10 +1,9 @@ /* eslint-disable unused-imports/no-unused-vars */ import React, { useState } from 'react' import { ImageIcon } from '@radix-ui/react-icons' -import { getDefaultConversationAttachments } from '@shared/utils/get-default-conversation-attachments' import { Button } from '@webview/components/ui/button' +import { usePluginImagesSelectorProviders } from '@webview/hooks/chat/use-plugin-providers' import { - ContextInfoSource, type ChatContext, type Conversation, type ModelOption @@ -36,6 +35,7 @@ export const ContextSelector: React.FC = ({ ]) const [selectedModel, setSelectedModel] = useState(modelOptions[0]) + const { addSelectedImage } = usePluginImagesSelectorProviders() const handleSelectModel = (model: ModelOption) => { setSelectedModel(model) @@ -51,20 +51,15 @@ export const ContextSelector: React.FC = ({ input.onchange = event => { const file = (event.target as HTMLInputElement).files?.[0] if (file) { - console.log('Selected image:', file) + const reader = new FileReader() + reader.onload = e => { + const base64Image = e.target?.result as string + addSelectedImage?.({ url: base64Image }) + } + reader.readAsDataURL(file) } } input.click() - setConversation(draft => { - if (!draft.attachments) { - draft.attachments = getDefaultConversationAttachments() - } - - draft.attachments.fileContext.selectedImages.push({ - url: 'https://example.com/image.jpg', - source: ContextInfoSource.FileSelector - }) - }) } return ( diff --git a/src/webview/components/chat/selectors/file-selector/index.tsx b/src/webview/components/chat/selectors/file-selector/index.tsx index 85f15c9..5ef67e7 100644 --- a/src/webview/components/chat/selectors/file-selector/index.tsx +++ b/src/webview/components/chat/selectors/file-selector/index.tsx @@ -20,7 +20,7 @@ import { import { useFilesSearch } from '@webview/hooks/chat/use-files-search' import { useControllableState } from '@webview/hooks/use-controllable-state' import { useKeyboardNavigation } from '@webview/hooks/use-keyboard-navigation' -import { ContextInfoSource, type FileInfo } from '@webview/types/chat' +import { type FileInfo } from '@webview/types/chat' import { useEvent } from 'react-use' import { FileListView } from './file-list-view' @@ -64,11 +64,6 @@ export const FileSelector: React.FC = ({ const inputRef = useRef(null) const tabRefs = useRef<(HTMLButtonElement | null)[]>([]) - const filteredFilesWithSource = filteredFiles.map(file => ({ - ...file, - source: ContextInfoSource.FileSelector - })) - const { handleKeyDown, setFocusedIndex } = useKeyboardNavigation({ itemCount: tabOptions.length, itemRefs: tabRefs, @@ -162,14 +157,14 @@ export const FileSelector: React.FC = ({
(null) + +export const PluginRegistryProvider: FC = ({ + children +}) => { + const queryClient = useQueryClient() + const [pluginStates, updatePluginStates] = useImmer>( + {} as Record + ) + const [isLoaded, setIsLoaded] = useState(false) + + const getState = useCallbackRef( + (pluginId: PluginId) => pluginStates[pluginId] || {} + ) + const setState = useCallbackRef((pluginId: PluginId, newState: any) => { + updatePluginStates(draft => { + draft[pluginId] = newState + }) + }) + const pluginRegistryRef = useRef(null) + + useAsyncEffect( + async () => { + const pluginRegistry = new ClientPluginRegistry({ + queryClient, + getState, + setState + }) + const plugins = createClientPlugins() + + await Promise.allSettled( + plugins.map(plugin => pluginRegistry.loadPlugin(plugin)) + ) + + pluginRegistryRef.current = pluginRegistry + setIsLoaded(true) + }, + async () => { + setIsLoaded(false) + await pluginRegistryRef.current?.unloadAllPlugins() + pluginRegistryRef.current = null + }, + [getState, setState] + ) + + return ( + + {children} + + ) +} + +export const usePluginRegistry = () => { + const context = useContext(PluginRegistryContext) + + if (context === null) { + throw new Error( + 'usePluginRegistry must be used within a PluginRegistryProvider' + ) + } + + return context +} + +export function WithPluginRegistryProvider

( + WrappedComponent: React.ComponentType

+) { + const WithPluginRegistryProvider: React.FC

= props => ( + + + + ) + + WithPluginRegistryProvider.displayName = `WithPluginRegistryProvider(${getDisplayName(WrappedComponent)})` + + return WithPluginRegistryProvider +} + +function getDisplayName

(WrappedComponent: React.ComponentType

): string { + return WrappedComponent.displayName || WrappedComponent.name || 'Component' +} diff --git a/src/webview/contexts/providers.tsx b/src/webview/contexts/providers.tsx index abc6358..9c8e454 100644 --- a/src/webview/contexts/providers.tsx +++ b/src/webview/contexts/providers.tsx @@ -2,9 +2,9 @@ import { useRef } from 'react' import { TooltipProvider } from '@radix-ui/react-tooltip' import { QueryClientProvider, type QueryClient } from '@tanstack/react-query' +import { Toaster } from '@webview/components/ui/sonner' import { createQueryClient } from '@webview/services/react-query/query-client' import { ThemeProvider as NextThemesProvider } from 'next-themes' -import { Toaster } from 'sonner' export function Providers({ children }: React.PropsWithChildren) { const queryClientRef = useRef(null) diff --git a/src/webview/hooks/api/use-folders.ts b/src/webview/hooks/api/use-folders.ts deleted file mode 100644 index a5c18fb..0000000 --- a/src/webview/hooks/api/use-folders.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { useQuery } from '@tanstack/react-query' -import { api } from '@webview/services/api-client' - -export const useFolders = () => - useQuery({ - queryKey: ['realtime', 'folders'], - queryFn: () => api.file.traverseWorkspaceFolders({ folders: ['./'] }) - }) diff --git a/src/webview/hooks/api/use-git-commits.ts b/src/webview/hooks/api/use-git-commits.ts deleted file mode 100644 index 24307a3..0000000 --- a/src/webview/hooks/api/use-git-commits.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { useQuery } from '@tanstack/react-query' -import { api } from '@webview/services/api-client' - -export const useGitCommits = () => - useQuery({ - queryKey: ['realtime', 'git-commits'], - queryFn: () => - api.git.getHistoryCommits({ - maxCount: 50 - }) - }) diff --git a/src/webview/hooks/chat/use-mention-options.tsx b/src/webview/hooks/chat/use-mention-options.tsx index 20415fc..50e7936 100644 --- a/src/webview/hooks/chat/use-mention-options.tsx +++ b/src/webview/hooks/chat/use-mention-options.tsx @@ -1,225 +1,19 @@ -import { - CardStackIcon, - ChevronRightIcon, - CodeIcon, - CommitIcon, - CubeIcon, - FileIcon, - GlobeIcon, - IdCardIcon, - MaskOffIcon, - TransformIcon -} from '@radix-ui/react-icons' -import { MentionFilePreview } from '@webview/components/chat/selectors/mention-selector/files/mention-file-preview' -import { MentionFolderPreview } from '@webview/components/chat/selectors/mention-selector/folders/mention-folder-preview' -import { FileIcon as FileIcon2 } from '@webview/components/file-icon' -import { - AttachmentType, - ContextInfoSource, - SearchSortStrategy, - type DocSiteName, - type FileInfo, - type FolderInfo, - type GitCommit, - type MentionOption -} from '@webview/types/chat' -import { getFileNameFromPath } from '@webview/utils/path' - -import { useDocSites } from '../api/use-doc-sites' -import { useFiles } from '../api/use-files' -import { useFolders } from '../api/use-folders' -import { useGitCommits } from '../api/use-git-commits' +import { useQuery } from '@tanstack/react-query' +import { usePluginRegistry } from '@webview/contexts/plugin-registry-context' export const useMentionOptions = () => { - const { data: files = [] } = useFiles() - const { data: folders = [] } = useFolders() - const { data: gitCommits = [] } = useGitCommits() - const { data: docSites = [] } = useDocSites() - - const filesMentionOptions: MentionOption[] = files.map( - file => - ({ - id: `file#${file.fullPath}`, - label: getFileNameFromPath(file.fullPath), - type: AttachmentType.Files, - searchKeywords: [file.relativePath], - searchSortStrategy: SearchSortStrategy.EndMatch, - data: { ...file, source: ContextInfoSource.Editor } satisfies FileInfo, - itemLayoutProps: { - icon: ( - - ), - label: getFileNameFromPath(file.fullPath), - details: file.relativePath - }, - customRenderPreview: MentionFilePreview - }) satisfies MentionOption, - [files] - ) - - const foldersMentionOptions: MentionOption[] = folders.map( - folder => - ({ - id: `folder#${folder.fullPath}`, - label: getFileNameFromPath(folder.fullPath), - type: AttachmentType.Folders, - searchKeywords: [folder.relativePath], - searchSortStrategy: SearchSortStrategy.EndMatch, - data: { - ...folder, - source: ContextInfoSource.Editor - } satisfies FolderInfo, - itemLayoutProps: { - icon: ( - <> - - - - ), - label: getFileNameFromPath(folder.fullPath), - details: folder.relativePath - }, - customRenderPreview: MentionFolderPreview - }) satisfies MentionOption - ) + const { pluginRegistry, isPluginRegistryLoaded } = usePluginRegistry() - const gitCommitsMentionOptions: MentionOption[] = gitCommits.map( - commit => - ({ - id: `git-commit#${commit.sha}`, - label: commit.message, - type: AttachmentType.GitCommit, - searchKeywords: [commit.sha, commit.message], - data: { - ...commit, - source: ContextInfoSource.Editor - } satisfies GitCommit, - itemLayoutProps: { - icon: , - label: commit.message, - details: commit.sha - } - }) satisfies MentionOption - ) + const { data: mentionOptions = [] } = useQuery({ + queryKey: ['realtime', 'useMentionOptions', isPluginRegistryLoaded], + queryFn: async () => { + const editorProvider = pluginRegistry?.providerManagers.editor.mergeAll() + const result = (await editorProvider?.getMentionOptions?.()) || [] - const docSiteNamesMentionOptions: MentionOption[] = docSites.map(site => ({ - id: `doc-site#${site.id}`, - label: site.name, - type: AttachmentType.Docs, - searchKeywords: [site.name, site.url], - data: { - name: site.name, - source: ContextInfoSource.Editor - } satisfies DocSiteName, - itemLayoutProps: { - icon: , - label: site.name, - details: site.url - } - })) - - const mentionOptions: MentionOption[] = [ - { - id: 'files', - label: 'Files', - type: AttachmentType.Files, - searchKeywords: ['files'], - children: filesMentionOptions, - itemLayoutProps: { - icon: , - label: 'Files' - } - }, - { - id: 'folders', - label: 'Folders', - type: AttachmentType.Folders, - searchKeywords: ['folders'], - children: foldersMentionOptions, - itemLayoutProps: { - icon: , - label: 'Folders' - } - }, - { - id: 'code', - label: 'Code', - type: AttachmentType.Code, - searchKeywords: ['code'], - itemLayoutProps: { - icon: , - label: 'Code' - } - }, - { - id: 'web', - label: 'Web', - type: AttachmentType.Web, - searchKeywords: ['web'], - itemLayoutProps: { - icon: , - label: 'Web' - } - }, - { - id: 'docs', - label: 'Docs', - type: AttachmentType.Docs, - searchKeywords: ['docs'], - itemLayoutProps: { - icon: , - label: 'Docs' - }, - children: docSiteNamesMentionOptions - }, - { - id: 'git', - label: 'Git', - searchKeywords: ['git'], - itemLayoutProps: { - icon: , - label: 'Git' - }, - children: [ - { - id: 'git#diff', - label: 'Diff (Diff of Working State)', - type: AttachmentType.GitDiff, - searchKeywords: ['diff'], - itemLayoutProps: { - icon: , - label: 'Diff (Diff of Working State)' - } - }, - { - id: 'git#pull-request', - label: 'PR (Diff with Main Branch)', - type: AttachmentType.GitPr, - searchKeywords: ['pull request', 'pr', 'diff'], - itemLayoutProps: { - icon: , - label: 'PR (Diff with Main Branch)' - } - }, - ...gitCommitsMentionOptions - ] + return result }, - { - id: 'codebase', - label: 'Codebase', - type: AttachmentType.Codebase, - searchKeywords: ['codebase'], - itemLayoutProps: { - icon: , - label: 'Codebase' - } - } - ] + enabled: isPluginRegistryLoaded + }) return mentionOptions } diff --git a/src/webview/hooks/chat/use-plugin-providers.ts b/src/webview/hooks/chat/use-plugin-providers.ts new file mode 100644 index 0000000..e26078f --- /dev/null +++ b/src/webview/hooks/chat/use-plugin-providers.ts @@ -0,0 +1,42 @@ +import { useMemo } from 'react' +import { usePluginRegistry } from '@webview/contexts/plugin-registry-context' + +export const usePluginEditorProviders = () => { + const { pluginRegistry, isPluginRegistryLoaded } = usePluginRegistry() + const merged = useMemo( + () => pluginRegistry?.providerManagers.editor.mergeAll() || {}, + [isPluginRegistryLoaded] + ) + + return merged +} + +export const usePluginFilesSelectorProviders = () => { + const { pluginRegistry, isPluginRegistryLoaded } = usePluginRegistry() + const merged = useMemo( + () => pluginRegistry?.providerManagers.filesSelector.mergeAll() || {}, + [isPluginRegistryLoaded] + ) + + return merged +} + +export const usePluginImagesSelectorProviders = () => { + const { pluginRegistry, isPluginRegistryLoaded } = usePluginRegistry() + const merged = useMemo( + () => pluginRegistry?.providerManagers.imagesSelector.mergeAll() || {}, + [isPluginRegistryLoaded] + ) + + return merged +} + +export const usePluginStates = () => { + const { pluginRegistry, isPluginRegistryLoaded } = usePluginRegistry() + const states = useMemo( + () => pluginRegistry?.providerManagers.state.getAll() || {}, + [isPluginRegistryLoaded] + ) + + return states +} diff --git a/src/webview/hooks/use-async-effect.ts b/src/webview/hooks/use-async-effect.ts new file mode 100644 index 0000000..2de8ce5 --- /dev/null +++ b/src/webview/hooks/use-async-effect.ts @@ -0,0 +1,69 @@ +import { useCallback, useEffect, useRef, useState } from 'react' +import { logger } from '@webview/utils/logger' + +export const useAsyncEffect = ( + mountCallback: () => Promise, + unmountCallback: () => Promise, + deps: any[] = [] +): UseAsyncEffectResult => { + const isMounted = useRef(false) + const [state, setState] = useState>({ + isLoading: true, + error: undefined, + result: undefined + }) + + const setStateIfMounted = useCallback( + (newState: Partial>) => { + if (isMounted.current) { + setState(prev => ({ ...prev, ...newState })) + } + }, + [] + ) + + useEffect(() => { + isMounted.current = true + return () => { + isMounted.current = false + } + }, []) + + useEffect(() => { + let cleanup: (() => void) | undefined + + const execute = async () => { + setStateIfMounted({ isLoading: true, error: undefined }) + try { + const result = await mountCallback() + setStateIfMounted({ result, isLoading: false }) + if (typeof result === 'function') { + cleanup = result as () => void + } + } catch (error) { + setStateIfMounted({ error, isLoading: false }) + } + } + + execute() + + return () => { + if (cleanup) { + cleanup() + } + unmountCallback().catch(error => { + logger.error('Error in unmount callback:', error) + }) + } + }, deps) + + return state +} + +interface UseAsyncEffectState { + result: T | undefined + error: unknown + isLoading: boolean +} + +export type UseAsyncEffectResult = UseAsyncEffectState diff --git a/src/webview/lexical/nodes/mention-node.tsx b/src/webview/lexical/nodes/mention-node.tsx index 1642f84..272151e 100644 --- a/src/webview/lexical/nodes/mention-node.tsx +++ b/src/webview/lexical/nodes/mention-node.tsx @@ -1,6 +1,5 @@ /* eslint-disable unused-imports/no-unused-vars */ import React from 'react' -import type { AttachmentType } from '@webview/types/chat' import { $applyNodeReplacement, $createTextNode, @@ -19,7 +18,7 @@ import { export type SerializedMentionNode = Spread< { - mentionType: AttachmentType + mentionType: string mentionData: any text: string }, @@ -31,7 +30,7 @@ function convertMentionElement( ): DOMConversionOutput | null { const mentionType = domNode.getAttribute( 'data-lexical-mention-type' - ) as AttachmentType + ) as string const mentionData = domNode.getAttribute('data-lexical-mention-data') const text = domNode.textContent @@ -47,7 +46,7 @@ function convertMentionElement( } export class MentionNode extends DecoratorNode { - __mentionType: AttachmentType + __mentionType: string __mentionData: any @@ -67,7 +66,7 @@ export class MentionNode extends DecoratorNode { } constructor( - mentionType: AttachmentType, + mentionType: string, mentionData: any, text: string, key?: NodeKey @@ -202,7 +201,7 @@ export class MentionNode extends DecoratorNode { } export function $createMentionNode( - mentionType: AttachmentType, + mentionType: string, mentionData: any, text: string ): MentionNode { diff --git a/src/webview/types/chat.ts b/src/webview/types/chat.ts index a4a4360..d685c0e 100644 --- a/src/webview/types/chat.ts +++ b/src/webview/types/chat.ts @@ -1,14 +1,11 @@ import type { FC } from 'react' -import type { - Attachments, - Conversation -} from '@extension/webview-api/chat-context-processor/types/chat-context' +import type { Conversation } from '@shared/types/chat-context' import type { MentionItemLayoutProps } from '@webview/components/chat/selectors/mention-selector/mention-item-layout' export type { DocSite } from '@extension/webview-api/lowdb/doc-sites-db' - export type { ProgressInfo } from '@extension/webview-api/chat-context-processor/utils/process-reporter' -export * from '@extension/webview-api/chat-context-processor/types/chat-context' +export * from '@shared/types/chat-context' +export type { FileInfo, FolderInfo } from '@extension/file-utils/traverse-fs' export interface ModelOption { value: string @@ -20,53 +17,24 @@ export enum SearchSortStrategy { EndMatch = 'EndMatch' } -export interface MentionOption { +export interface MentionOption { id: string label: string - type?: AttachmentType + type?: string + onAddOne?: (data: T) => void + onRemoveOne?: (data: T) => void + onReplaceAll?: (dataArr: T[]) => void + + topLevelSort?: number searchKeywords?: string[] searchSortStrategy?: SearchSortStrategy children?: MentionOption[] - data?: any + data?: T itemLayoutProps?: MentionItemLayoutProps customRenderItem?: FC customRenderPreview?: FC } -export enum AttachmentType { - Files = 'Files', - Folders = 'Folders', - Images = 'Images', - Code = 'Code', - Web = 'Web', - Docs = 'Docs', - GitDiff = 'GitDiff', - GitCommit = 'GitCommit', - GitPr = 'GitPr', - Codebase = 'Codebase' -} - -export type AttachmentItem = { - type: AttachmentType - data: any -} - -export interface IMentionStrategy { - readonly category: AttachmentType - readonly name: string - - buildLexicalNodeAfterAddMention?: ( - data: any, - currentAttachments: Attachments, - currentConversation: Conversation - ) => Promise - - buildNewAttachmentsAfterAddMention: ( - data: any, - currentAttachments: Attachments - ) => Promise> -} - export interface ConversationUIState { isEditMode?: boolean isLoading?: boolean diff --git a/src/webview/utils/attachments.ts b/src/webview/utils/attachments.ts deleted file mode 100644 index d53008e..0000000 --- a/src/webview/utils/attachments.ts +++ /dev/null @@ -1,330 +0,0 @@ -import { removeDuplicates } from '@shared/utils/common' -import { getDefaultConversationAttachments } from '@shared/utils/get-default-conversation-attachments' -import { $isMentionNode } from '@webview/lexical/nodes/mention-node' -import { - AttachmentItem, - Attachments, - AttachmentType, - ContextInfoSource, - type BaseContextInfo, - type GitDiff -} from '@webview/types/chat' -import { produce } from 'immer' -import { - $getRoot, - $isElementNode, - type EditorState, - type LexicalNode -} from 'lexical' - -const deduplicateAttachments = ( - attachments: Attachments, - onlyDeduplicateTypes?: Set, - priorityRemoveSource: Set = new Set([ - ContextInfoSource.Editor - ]) -): Attachments => - produce(attachments, draft => { - const prioritySelector = (a: T, b: T) => - priorityRemoveSource?.has(a.source) ? b : a - - if ( - !onlyDeduplicateTypes || - onlyDeduplicateTypes?.has(AttachmentType.Files) - ) { - draft.fileContext.selectedFiles = removeDuplicates( - draft.fileContext.selectedFiles, - ['fullPath'], - prioritySelector - ) - } - - if ( - !onlyDeduplicateTypes || - onlyDeduplicateTypes?.has(AttachmentType.Folders) - ) { - draft.fileContext.selectedFolders = removeDuplicates( - draft.fileContext.selectedFolders, - ['fullPath'], - prioritySelector - ) - } - - if ( - !onlyDeduplicateTypes || - onlyDeduplicateTypes?.has(AttachmentType.Images) - ) { - draft.fileContext.selectedImages = removeDuplicates( - draft.fileContext.selectedImages, - ['url'], - prioritySelector - ) - } - - if ( - !onlyDeduplicateTypes || - onlyDeduplicateTypes?.has(AttachmentType.GitCommit) - ) { - draft.gitContext.gitCommits = removeDuplicates( - draft.gitContext.gitCommits, - ['sha'], - prioritySelector - ) - } - - if ( - !onlyDeduplicateTypes || - onlyDeduplicateTypes?.has(AttachmentType.GitDiff) - ) { - draft.gitContext.gitDiffs = removeDuplicates( - draft.gitContext.gitDiffs, - diff => - `${diff.from}|${diff.to}|${diff.chunks.map(chunk => chunk.content).join('|')}`, - prioritySelector - ) - } - - if ( - !onlyDeduplicateTypes || - onlyDeduplicateTypes?.has(AttachmentType.Docs) - ) { - draft.docContext.allowSearchDocSiteNames = removeDuplicates( - draft.docContext.allowSearchDocSiteNames, - ['name'], - prioritySelector - ) - } - - if ( - !onlyDeduplicateTypes || - onlyDeduplicateTypes?.has(AttachmentType.Code) - ) { - draft.codeContext.codeChunks = removeDuplicates( - draft.codeContext.codeChunks, - ['relativePath', 'code'], - prioritySelector - ) - } - }) - -export const addAttachmentItems = ( - currentAttachments: Attachments | undefined, - newItems: AttachmentItem[], - priorityRemoveSource?: Set -): Attachments => { - const deduplicateAttachmentTypes = new Set() - - const result = produce( - currentAttachments || getDefaultConversationAttachments(), - draft => { - newItems.forEach(item => { - switch (item.type) { - case AttachmentType.Files: - deduplicateAttachmentTypes.add(AttachmentType.Files) - draft.fileContext.selectedFiles.push(item.data) - break - case AttachmentType.Folders: - deduplicateAttachmentTypes.add(AttachmentType.Folders) - draft.fileContext.selectedFolders.push(item.data) - break - case AttachmentType.Images: - deduplicateAttachmentTypes.add(AttachmentType.Images) - draft.fileContext.selectedImages.push(item.data) - break - case AttachmentType.GitCommit: - deduplicateAttachmentTypes.add(AttachmentType.GitCommit) - draft.gitContext.gitCommits.push(item.data) - break - case AttachmentType.GitDiff: - case AttachmentType.GitPr: - deduplicateAttachmentTypes.add(AttachmentType.GitDiff) - draft.gitContext.gitDiffs.push(item.data) - break - case AttachmentType.Web: - draft.webContext.enableTool = true - break - case AttachmentType.Docs: - deduplicateAttachmentTypes.add(AttachmentType.Docs) - draft.docContext.allowSearchDocSiteNames.push(item.data) - break - case AttachmentType.Code: - deduplicateAttachmentTypes.add(AttachmentType.Code) - draft.codeContext.codeChunks.push(item.data) - break - case AttachmentType.Codebase: - draft.codebaseContext.enableTool = true - break - default: - break - } - }) - } - ) - - return deduplicateAttachments( - result, - deduplicateAttachmentTypes, - priorityRemoveSource - ) -} - -export const removeAttachmentItems = ( - currentAttachments: Attachments | undefined, - itemsToRemove: AttachmentItem[], - priorityRemoveSource?: Set -): Attachments => { - if (!currentAttachments) return getDefaultConversationAttachments() - - const deduplicateAttachmentTypes = new Set() - - const result = produce(currentAttachments, draft => { - itemsToRemove.forEach(item => { - switch (item.type) { - case AttachmentType.Files: - deduplicateAttachmentTypes.add(AttachmentType.Files) - draft.fileContext.selectedFiles = - draft.fileContext.selectedFiles.filter( - file => file.fullPath !== item.data.fullPath - ) - break - case AttachmentType.Folders: - deduplicateAttachmentTypes.add(AttachmentType.Folders) - draft.fileContext.selectedFolders = - draft.fileContext.selectedFolders.filter( - folder => folder.fullPath !== item.data.fullPath - ) - break - case AttachmentType.Images: - deduplicateAttachmentTypes.add(AttachmentType.Images) - draft.fileContext.selectedImages = - draft.fileContext.selectedImages.filter( - image => image.url !== item.data.url - ) - break - case AttachmentType.GitCommit: - deduplicateAttachmentTypes.add(AttachmentType.GitCommit) - draft.gitContext.gitCommits = draft.gitContext.gitCommits.filter( - commit => commit.sha !== item.data.sha - ) - break - case AttachmentType.GitDiff: - case AttachmentType.GitPr: - deduplicateAttachmentTypes.add(AttachmentType.GitDiff) - draft.gitContext.gitDiffs = draft.gitContext.gitDiffs.filter( - diff => - `${diff.from}|${diff.to}|${diff.chunks.map(chunk => chunk.content).join('|')}` !== - `${item.data.from}|${item.data.to}|${(item.data as GitDiff).chunks.map(chunk => chunk.content).join('|')}` - ) - break - case AttachmentType.Docs: - deduplicateAttachmentTypes.add(AttachmentType.Docs) - draft.docContext.allowSearchDocSiteNames = - draft.docContext.allowSearchDocSiteNames.filter( - name => name !== item.data - ) - break - case AttachmentType.Code: - deduplicateAttachmentTypes.add(AttachmentType.Code) - draft.codeContext.codeChunks = draft.codeContext.codeChunks.filter( - chunk => - !( - chunk.relativePath === item.data.relativePath && - chunk.code === item.data.code - ) - ) - break - default: - break - } - }) - }) - - return deduplicateAttachments( - result, - deduplicateAttachmentTypes, - priorityRemoveSource - ) -} - -export const overrideAttachmentItemsBySource = ( - activeSource: ContextInfoSource, - currentAttachments: Attachments | undefined, - newItems: AttachmentItem[], - priorityRemoveSource?: Set -): Attachments => { - let cleanedCurrentAttachments = currentAttachments - - if (!currentAttachments) { - cleanedCurrentAttachments = getDefaultConversationAttachments() - } else { - cleanedCurrentAttachments = produce(currentAttachments, draft => { - // remove the source items - draft.fileContext.selectedFiles = draft.fileContext.selectedFiles.filter( - file => file.source !== activeSource - ) - - draft.fileContext.selectedFolders = - draft.fileContext.selectedFolders.filter( - folder => folder.source !== activeSource - ) - - draft.fileContext.selectedImages = - draft.fileContext.selectedImages.filter( - image => image.source !== activeSource - ) - - draft.gitContext.gitCommits = draft.gitContext.gitCommits.filter( - commit => commit.source !== activeSource - ) - - draft.gitContext.gitDiffs = draft.gitContext.gitDiffs.filter( - diff => diff.source !== activeSource - ) - - draft.webContext.enableTool = false - - draft.docContext.allowSearchDocSiteNames = - draft.docContext.allowSearchDocSiteNames.filter( - name => name.source !== activeSource - ) - - draft.codeContext.codeChunks = draft.codeContext.codeChunks.filter( - chunk => chunk.source !== activeSource - ) - - draft.codebaseContext.enableTool = false - }) - } - - return addAttachmentItems( - cleanedCurrentAttachments, - newItems, - priorityRemoveSource - ) -} - -export const getAttachmentsFromEditorState = ( - editorState: EditorState, - currentAttachments: Attachments | undefined -): Attachments => - editorState.read(() => { - const root = $getRoot() - const attachmentItems: AttachmentItem[] = [] - - const traverseNodes = (node: LexicalNode) => { - if ($isMentionNode(node)) { - const { mentionType, mentionData } = node.exportJSON() - attachmentItems.push({ type: mentionType, data: mentionData }) - } else if ($isElementNode(node)) { - node.getChildren().forEach(traverseNodes) - } - } - - traverseNodes(root) - - return overrideAttachmentItemsBySource( - ContextInfoSource.Editor, - currentAttachments, - attachmentItems - ) - }) diff --git a/src/webview/utils/plugin-states.ts b/src/webview/utils/plugin-states.ts new file mode 100644 index 0000000..c15c2b9 --- /dev/null +++ b/src/webview/utils/plugin-states.ts @@ -0,0 +1,54 @@ +import { $isMentionNode } from '@webview/lexical/nodes/mention-node' +import type { MentionOption } from '@webview/types/chat' +import { + $getRoot, + $isElementNode, + type EditorState, + type LexicalNode +} from 'lexical' + +export const updatePluginStatesFromEditorState = ( + editorState: EditorState, + mentionOptions: MentionOption[] +): void => + editorState.read(() => { + const root = $getRoot() + const mentionTypeDataArr: Record = {} + + const traverseNodes = (node: LexicalNode) => { + if ($isMentionNode(node)) { + const { mentionType, mentionData } = node.exportJSON() + mentionTypeDataArr[mentionType] ||= [] + mentionTypeDataArr[mentionType]!.push(mentionData) + } else if ($isElementNode(node)) { + node.getChildren().forEach(traverseNodes) + } + } + + traverseNodes(root) + + Object.entries(mentionTypeDataArr).forEach(([type, dataArr]) => { + const found = findMentionOptionByMentionType(mentionOptions, type) + found?.onReplaceAll?.(dataArr) + }) + }) + +const findMentionOptionByMentionType = ( + mentionOptions: MentionOption[], + mentionType: string +): MentionOption | undefined => { + for (const option of mentionOptions) { + if (option.children) { + const found = findMentionOptionByMentionType(option.children, mentionType) + if (found) { + return found + } + } + + if (option.type === mentionType) { + return option + } + } + + return undefined +}