diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9bf4d12b5..62f4edac1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,15 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
- "editor.formatOnSave": true
+ "editor.formatOnSave": true,
+ "eslint.workingDirectories": [
+ {
+ "directory": "./web-app"
+ },
+ {
+ "directory": "./electron"
+ },
+ {
+ "directory": "./docs"
+ }
+ ]
}
diff --git a/extensions/yarn.lock b/extensions/yarn.lock
index 1a8e45497..24458fedc 100644
--- a/extensions/yarn.lock
+++ b/extensions/yarn.lock
@@ -659,64 +659,89 @@ __metadata:
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension":
version: 0.1.10
- resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=5531aa&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
+ resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7c4a2a&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
- checksum: 10c0/ee7fe21267cf795dba890781d1e7807a6cb3ecb915ce9ecbd3a8386a2ebc916a8b70a775ce5d9d9f74d2ec29e20b65cea4ef6cdd0ea250a8ff2d5e6bd2237b1e
+ checksum: 10c0/4708652e05a82d5fb6111708b0f6a9d764ac14032613b8d0edacaaa32d08593a0e4226f50806165da57fde8ad8e3dfe52a141b0d093a45d749a460f5cf869889
languageName: node
linkType: hard
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension":
version: 0.1.10
- resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=5531aa&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
+ resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7c4a2a&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
- checksum: 10c0/ee7fe21267cf795dba890781d1e7807a6cb3ecb915ce9ecbd3a8386a2ebc916a8b70a775ce5d9d9f74d2ec29e20b65cea4ef6cdd0ea250a8ff2d5e6bd2237b1e
+ checksum: 10c0/4708652e05a82d5fb6111708b0f6a9d764ac14032613b8d0edacaaa32d08593a0e4226f50806165da57fde8ad8e3dfe52a141b0d093a45d749a460f5cf869889
+ languageName: node
+ linkType: hard
+
+"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fdownload-extension%40workspace%3Adownload-extension":
+ version: 0.1.10
+ resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7c4a2a&locator=%40janhq%2Fdownload-extension%40workspace%3Adownload-extension"
+ dependencies:
+ rxjs: "npm:^7.8.1"
+ ulidx: "npm:^2.3.0"
+ checksum: 10c0/4708652e05a82d5fb6111708b0f6a9d764ac14032613b8d0edacaaa32d08593a0e4226f50806165da57fde8ad8e3dfe52a141b0d093a45d749a460f5cf869889
languageName: node
linkType: hard
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension":
version: 0.1.10
- resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=5531aa&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
+ resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7c4a2a&locator=%40janhq%2Fengine-management-extension%40workspace%3Aengine-management-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
- checksum: 10c0/ee7fe21267cf795dba890781d1e7807a6cb3ecb915ce9ecbd3a8386a2ebc916a8b70a775ce5d9d9f74d2ec29e20b65cea4ef6cdd0ea250a8ff2d5e6bd2237b1e
+ checksum: 10c0/4708652e05a82d5fb6111708b0f6a9d764ac14032613b8d0edacaaa32d08593a0e4226f50806165da57fde8ad8e3dfe52a141b0d093a45d749a460f5cf869889
languageName: node
linkType: hard
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fhardware-management-extension%40workspace%3Ahardware-management-extension":
version: 0.1.10
- resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=5531aa&locator=%40janhq%2Fhardware-management-extension%40workspace%3Ahardware-management-extension"
+ resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7c4a2a&locator=%40janhq%2Fhardware-management-extension%40workspace%3Ahardware-management-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
- checksum: 10c0/ee7fe21267cf795dba890781d1e7807a6cb3ecb915ce9ecbd3a8386a2ebc916a8b70a775ce5d9d9f74d2ec29e20b65cea4ef6cdd0ea250a8ff2d5e6bd2237b1e
+ checksum: 10c0/4708652e05a82d5fb6111708b0f6a9d764ac14032613b8d0edacaaa32d08593a0e4226f50806165da57fde8ad8e3dfe52a141b0d093a45d749a460f5cf869889
languageName: node
linkType: hard
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension":
version: 0.1.10
- resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=5531aa&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
+ resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7c4a2a&locator=%40janhq%2Finference-cortex-extension%40workspace%3Ainference-cortex-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
- checksum: 10c0/ee7fe21267cf795dba890781d1e7807a6cb3ecb915ce9ecbd3a8386a2ebc916a8b70a775ce5d9d9f74d2ec29e20b65cea4ef6cdd0ea250a8ff2d5e6bd2237b1e
+ checksum: 10c0/4708652e05a82d5fb6111708b0f6a9d764ac14032613b8d0edacaaa32d08593a0e4226f50806165da57fde8ad8e3dfe52a141b0d093a45d749a460f5cf869889
languageName: node
linkType: hard
"@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension":
version: 0.1.10
- resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=5531aa&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
+ resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=7c4a2a&locator=%40janhq%2Fmodel-extension%40workspace%3Amodel-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
- checksum: 10c0/ee7fe21267cf795dba890781d1e7807a6cb3ecb915ce9ecbd3a8386a2ebc916a8b70a775ce5d9d9f74d2ec29e20b65cea4ef6cdd0ea250a8ff2d5e6bd2237b1e
+ checksum: 10c0/4708652e05a82d5fb6111708b0f6a9d764ac14032613b8d0edacaaa32d08593a0e4226f50806165da57fde8ad8e3dfe52a141b0d093a45d749a460f5cf869889
languageName: node
linkType: hard
+"@janhq/download-extension@workspace:download-extension":
+ version: 0.0.0-use.local
+ resolution: "@janhq/download-extension@workspace:download-extension"
+ dependencies:
+ "@janhq/core": ../../core/package.tgz
+ "@tauri-apps/api": "npm:^2.5.0"
+ cpx: "npm:^1.5.0"
+ rimraf: "npm:^3.0.2"
+ rolldown: "npm:1.0.0-beta.1"
+ run-script-os: "npm:^1.1.6"
+ typescript: "npm:5.3.3"
+ vitest: "npm:^3.0.6"
+ languageName: unknown
+ linkType: soft
+
"@janhq/engine-management-extension@workspace:engine-management-extension":
version: 0.0.0-use.local
resolution: "@janhq/engine-management-extension@workspace:engine-management-extension"
@@ -1436,6 +1461,13 @@ __metadata:
languageName: node
linkType: hard
+"@tauri-apps/api@npm:^2.5.0":
+ version: 2.5.0
+ resolution: "@tauri-apps/api@npm:2.5.0"
+ checksum: 10c0/8eeb28049d48f5f89a5419cdf313bb159305204b193a5f27ebddbe0704ff43037c8b2e78518de831d7393e00178f0c0ac66cef1a57b99c632de71eca29f562c0
+ languageName: node
+ linkType: hard
+
"@tybys/wasm-util@npm:^0.9.0":
version: 0.9.0
resolution: "@tybys/wasm-util@npm:0.9.0"
diff --git a/web-app/package.json b/web-app/package.json
index 8b3193817..8163bb3cd 100644
--- a/web-app/package.json
+++ b/web-app/package.json
@@ -44,6 +44,7 @@
"fzf": "^0.5.2",
"i18next": "^25.0.1",
"katex": "^0.16.22",
+ "lodash.clonedeep": "^4.5.0",
"lodash.debounce": "^4.0.8",
"lucide-react": "^0.503.0",
"motion": "^12.10.5",
@@ -76,6 +77,7 @@
"@eslint/js": "^9.22.0",
"@tanstack/router-plugin": "^1.116.1",
"@types/culori": "^2.1.1",
+ "@types/lodash.clonedeep": "^4",
"@types/lodash.debounce": "^4",
"@types/node": "^22.14.1",
"@types/react": "^19.0.10",
diff --git a/web-app/src/containers/ThreadContent.tsx b/web-app/src/containers/ThreadContent.tsx
index 076327ea6..c56bd27b3 100644
--- a/web-app/src/containers/ThreadContent.tsx
+++ b/web-app/src/containers/ThreadContent.tsx
@@ -26,7 +26,6 @@ import {
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'
-import { toast } from 'sonner'
import {
Tooltip,
TooltipContent,
@@ -73,6 +72,57 @@ const CopyButton = ({ text }: { text: string }) => {
)
}
+const EditDialog = ({
+ message,
+ setMessage,
+}: {
+ message: string
+ setMessage: (message: string) => void
+}) => {
+ return (
+
+ )
+}
+
// Use memo to prevent unnecessary re-renders, but allow re-renders when props change
export const ThreadContent = memo(
(
@@ -84,10 +134,9 @@ export const ThreadContent = memo(
streamTools?: any
contextOverflowModal?: React.ReactNode | null
showContextOverflowModal?: () => Promise
+ updateMessage: (item: ThreadMessage, message: string) => void
}
) => {
- const [message, setMessage] = useState(item.content?.[0]?.text?.value || '')
-
// Use useMemo to stabilize the components prop
const linkComponents = useMemo(
() => ({
@@ -167,30 +216,6 @@ export const ThreadContent = memo(
}
}, [deleteMessage, getMessages, item])
- const editMessage = useCallback(
- (messageId: string) => {
- const threadMessages = getMessages(item.thread_id)
-
- const index = threadMessages.findIndex((msg) => msg.id === messageId)
- if (index === -1) return
-
- // Delete all messages after the edited message
- for (let i = threadMessages.length - 1; i >= index; i--) {
- deleteMessage(threadMessages[i].thread_id, threadMessages[i].id)
- }
-
- sendMessage(message, item.showContextOverflowModal)
- },
- [
- deleteMessage,
- getMessages,
- item.thread_id,
- message,
- sendMessage,
- item.showContextOverflowModal,
- ]
- )
-
const isToolCalls =
item.metadata &&
'tool_calls' in item.metadata &&
@@ -217,62 +242,12 @@ export const ThreadContent = memo(
-
+
{
+ item.updateMessage(item, message)
+ }}
+ />