Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai>
This commit is contained in:
parent
52b96e69a5
commit
1fc9c4e220
@ -22,7 +22,8 @@
|
|||||||
"postinstall": "rimraf *.tgz --glob && npm run build && npm run downloadnitro:linux-cpu && npm run downloadnitro:linux-cuda && npm run downloadnitro:mac-arm64 && npm run downloadnitro:mac-x64 && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
"postinstall": "rimraf *.tgz --glob && npm run build && npm run downloadnitro:linux-cpu && npm run downloadnitro:linux-cuda && npm run downloadnitro:mac-arm64 && npm run downloadnitro:mac-x64 && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
||||||
"postinstall:dev": "rimraf *.tgz --glob && npm run build && npm run downloadnitro:mac-arm64 && npm run downloadnitro:mac-x64 && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
"postinstall:dev": "rimraf *.tgz --glob && npm run build && npm run downloadnitro:mac-arm64 && npm run downloadnitro:mac-x64 && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
||||||
"postinstall:windows": "rimraf *.tgz --glob && npm run build && npm run downloadnitro:win-cpu && npm run downloadnitro:win-cuda && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
"postinstall:windows": "rimraf *.tgz --glob && npm run build && npm run downloadnitro:win-cpu && npm run downloadnitro:win-cuda && rimraf dist/nitro/* && cpx \"nitro/**\" \"dist/nitro\"",
|
||||||
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install"
|
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install",
|
||||||
|
"build:debug": "rimraf *.tgz --glob && npm run build && npm pack && cpx *.tgz ../../electron/core/pre-install"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./dist/index.js",
|
".": "./dist/index.js",
|
||||||
@ -40,7 +41,8 @@
|
|||||||
"kill-port": "^2.0.1",
|
"kill-port": "^2.0.1",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"tcp-port-used": "^1.0.2",
|
"tcp-port-used": "^1.0.2",
|
||||||
"ts-loader": "^9.5.0"
|
"ts-loader": "^9.5.0",
|
||||||
|
"ulid": "^2.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
export const generateMessageId = () => {
|
|
||||||
return `m-${Date.now()}`
|
|
||||||
}
|
|
||||||
@ -16,7 +16,7 @@ import {
|
|||||||
} from "@janhq/core";
|
} from "@janhq/core";
|
||||||
import { InferencePlugin } from "@janhq/core/lib/plugins";
|
import { InferencePlugin } from "@janhq/core/lib/plugins";
|
||||||
import { requestInference } from "./helpers/sse";
|
import { requestInference } from "./helpers/sse";
|
||||||
import { generateMessageId } from "./helpers/message";
|
import { ulid } from "ulid";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that implements the InferencePlugin interface from the @janhq/core package.
|
* A class that implements the InferencePlugin interface from the @janhq/core package.
|
||||||
@ -112,13 +112,13 @@ export default class JanInferencePlugin implements InferencePlugin {
|
|||||||
content: data.message,
|
content: data.message,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const recentMessages = await (data.history ?? prompts);
|
const recentMessages = data.history ?? prompts;
|
||||||
const message = {
|
const message = {
|
||||||
...data,
|
...data,
|
||||||
message: "",
|
message: "",
|
||||||
user: "assistant",
|
user: "assistant",
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
_id: generateMessageId(),
|
_id: ulid(),
|
||||||
};
|
};
|
||||||
events.emit(EventName.OnNewMessageResponse, message);
|
events.emit(EventName.OnNewMessageResponse, message);
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -b . && webpack --config webpack.config.js",
|
"build": "tsc -b . && webpack --config webpack.config.js",
|
||||||
"postinstall": "rimraf *.tgz --glob && npm run build",
|
"postinstall": "rimraf *.tgz --glob && npm run build",
|
||||||
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install"
|
"build:publish": "npm pack && cpx *.tgz ../../electron/core/pre-install",
|
||||||
|
"build:debug": "rimraf *.tgz --glob && npm run build && npm pack && cpx *.tgz ../../electron/core/pre-install"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"cpx": "^1.5.0",
|
"cpx": "^1.5.0",
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import {
|
|||||||
import { downloadingModelsAtom } from '@/helpers/atoms/Model.atom'
|
import { downloadingModelsAtom } from '@/helpers/atoms/Model.atom'
|
||||||
import { MessageStatus, toChatMessage } from '@/models/ChatMessage'
|
import { MessageStatus, toChatMessage } from '@/models/ChatMessage'
|
||||||
import { pluginManager } from '@/plugin'
|
import { pluginManager } from '@/plugin'
|
||||||
|
import { ChatMessage, Conversation } from '@/types/chatMessage'
|
||||||
|
|
||||||
let currentConversation: Conversation | undefined = undefined
|
let currentConversation: Conversation | undefined = undefined
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { atom } from 'jotai'
|
|||||||
|
|
||||||
import { getActiveConvoIdAtom } from './Conversation.atom'
|
import { getActiveConvoIdAtom } from './Conversation.atom'
|
||||||
|
|
||||||
import { MessageStatus } from '@/models/ChatMessage'
|
import { ChatMessage, MessageStatus } from '@/models/ChatMessage'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores all chat messages for all conversations
|
* Stores all chat messages for all conversations
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { Conversation, ConversationState } from '@/types/chatMessage'
|
||||||
import { atom } from 'jotai'
|
import { atom } from 'jotai'
|
||||||
|
|
||||||
// import { MainViewState, setMainViewStateAtom } from './MainView.atom'
|
// import { MainViewState, setMainViewStateAtom } from './MainView.atom'
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import {
|
|||||||
addNewConversationStateAtom,
|
addNewConversationStateAtom,
|
||||||
} from '@/helpers/atoms/Conversation.atom'
|
} from '@/helpers/atoms/Conversation.atom'
|
||||||
import { pluginManager } from '@/plugin'
|
import { pluginManager } from '@/plugin'
|
||||||
|
import { Conversation } from '@/types/chatMessage'
|
||||||
|
|
||||||
export const useCreateConversation = () => {
|
export const useCreateConversation = () => {
|
||||||
const [userConversations, setUserConversations] = useAtom(
|
const [userConversations, setUserConversations] = useAtom(
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { useActiveModel } from './useActiveModel'
|
|||||||
import { useGetDownloadedModels } from './useGetDownloadedModels'
|
import { useGetDownloadedModels } from './useGetDownloadedModels'
|
||||||
|
|
||||||
import { currentConversationAtom } from '@/helpers/atoms/Conversation.atom'
|
import { currentConversationAtom } from '@/helpers/atoms/Conversation.atom'
|
||||||
|
import { Conversation } from '@/types/chatMessage'
|
||||||
|
|
||||||
export default function useGetInputState() {
|
export default function useGetInputState() {
|
||||||
const [inputState, setInputState] = useState<InputType>('loading')
|
const [inputState, setInputState] = useState<InputType>('loading')
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
} from '@/helpers/atoms/Conversation.atom'
|
} from '@/helpers/atoms/Conversation.atom'
|
||||||
import { toChatMessage } from '@/models/ChatMessage'
|
import { toChatMessage } from '@/models/ChatMessage'
|
||||||
import { pluginManager } from '@/plugin/PluginManager'
|
import { pluginManager } from '@/plugin/PluginManager'
|
||||||
|
import { ChatMessage, ConversationState } from '@/types/chatMessage'
|
||||||
|
|
||||||
const useGetUserConversations = () => {
|
const useGetUserConversations = () => {
|
||||||
const setConversationStates = useSetAtom(conversationStatesAtom)
|
const setConversationStates = useSetAtom(conversationStatesAtom)
|
||||||
|
|||||||
@ -12,9 +12,7 @@ import { Message } from '@janhq/core/lib/types'
|
|||||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
||||||
|
|
||||||
import { currentPromptAtom } from '@/containers/Providers/Jotai'
|
import { currentPromptAtom } from '@/containers/Providers/Jotai'
|
||||||
|
import { ulid } from 'ulid'
|
||||||
import { generateMessageId } from '@/utils/message'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
addNewMessageAtom,
|
addNewMessageAtom,
|
||||||
getCurrentChatMessagesAtom,
|
getCurrentChatMessagesAtom,
|
||||||
@ -24,9 +22,10 @@ import {
|
|||||||
updateConversationAtom,
|
updateConversationAtom,
|
||||||
updateConversationWaitingForResponseAtom,
|
updateConversationWaitingForResponseAtom,
|
||||||
} from '@/helpers/atoms/Conversation.atom'
|
} from '@/helpers/atoms/Conversation.atom'
|
||||||
import { toChatMessage } from '@/models/ChatMessage'
|
import { MessageSenderType, toChatMessage } from '@/models/ChatMessage'
|
||||||
|
|
||||||
import { pluginManager } from '@/plugin/PluginManager'
|
import { pluginManager } from '@/plugin/PluginManager'
|
||||||
|
import { ChatMessage, Conversation } from '@/types/chatMessage'
|
||||||
|
|
||||||
export default function useSendChatMessage() {
|
export default function useSendChatMessage() {
|
||||||
const currentConvo = useAtomValue(currentConversationAtom)
|
const currentConvo = useAtomValue(currentConversationAtom)
|
||||||
@ -73,16 +72,13 @@ export default function useSendChatMessage() {
|
|||||||
...updatedConv,
|
...updatedConv,
|
||||||
name: updatedConv.name ?? '',
|
name: updatedConv.name ?? '',
|
||||||
message: updatedConv.lastMessage ?? '',
|
message: updatedConv.lastMessage ?? '',
|
||||||
messages: currentMessages.map<Message>((e: ChatMessage) => {
|
messages: currentMessages.map<Message>((e: ChatMessage) => ({
|
||||||
return {
|
_id: e.id,
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
message: e.text,
|
||||||
_id: e.id,
|
user: e.senderUid,
|
||||||
message: e.text,
|
updatedAt: new Date(e.createdAt).toISOString(),
|
||||||
user: e.senderUid,
|
createdAt: new Date(e.createdAt).toISOString(),
|
||||||
updatedAt: new Date(e.createdAt).toISOString(),
|
})),
|
||||||
createdAt: new Date(e.createdAt).toISOString(),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
@ -98,25 +94,23 @@ export default function useSendChatMessage() {
|
|||||||
|
|
||||||
const prompt = currentPrompt.trim()
|
const prompt = currentPrompt.trim()
|
||||||
const messageHistory: MessageHistory[] = currentMessages
|
const messageHistory: MessageHistory[] = currentMessages
|
||||||
.map((msg) => {
|
.map((msg) => ({
|
||||||
return {
|
role: msg.senderUid,
|
||||||
role: msg.senderUid === 'user' ? 'user' : 'assistant',
|
content: msg.text ?? '',
|
||||||
content: msg.text ?? '',
|
}))
|
||||||
}
|
|
||||||
})
|
|
||||||
.reverse()
|
.reverse()
|
||||||
.concat([
|
.concat([
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: MessageSenderType.User,
|
||||||
content: prompt,
|
content: prompt,
|
||||||
} as MessageHistory,
|
} as MessageHistory,
|
||||||
])
|
])
|
||||||
const newMessage: NewMessageRequest = {
|
const newMessage: NewMessageRequest = {
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
_id: generateMessageId(),
|
_id: ulid(),
|
||||||
conversationId: convoId,
|
conversationId: convoId,
|
||||||
message: prompt,
|
message: prompt,
|
||||||
user: 'user',
|
user: MessageSenderType.User,
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
history: messageHistory,
|
history: messageHistory,
|
||||||
}
|
}
|
||||||
@ -124,6 +118,11 @@ export default function useSendChatMessage() {
|
|||||||
const newChatMessage = toChatMessage(newMessage)
|
const newChatMessage = toChatMessage(newMessage)
|
||||||
addNewMessage(newChatMessage)
|
addNewMessage(newChatMessage)
|
||||||
|
|
||||||
|
// delay randomly from 50 - 100ms
|
||||||
|
// to prevent duplicate message id
|
||||||
|
const delay = Math.floor(Math.random() * 50) + 50
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, delay))
|
||||||
|
|
||||||
events.emit(EventName.OnNewMessageRequest, newMessage)
|
events.emit(EventName.OnNewMessageRequest, newMessage)
|
||||||
if (!currentConvo?.summary && currentConvo) {
|
if (!currentConvo?.summary && currentConvo) {
|
||||||
const updatedConv: Conversation = {
|
const updatedConv: Conversation = {
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
"tailwindcss": "3.3.5",
|
"tailwindcss": "3.3.5",
|
||||||
"typescript": "5.2.2",
|
"typescript": "5.2.2",
|
||||||
|
"ulid": "^2.3.0",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React, { forwardRef } from 'react'
|
import React, { forwardRef } from 'react'
|
||||||
|
|
||||||
import SimpleTextMessage from '../SimpleTextMessage'
|
import SimpleTextMessage from '../SimpleTextMessage'
|
||||||
|
import { ChatMessage } from '@/types/chatMessage'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
message: ChatMessage
|
message: ChatMessage
|
||||||
@ -8,20 +9,18 @@ type Props = {
|
|||||||
|
|
||||||
type Ref = HTMLDivElement
|
type Ref = HTMLDivElement
|
||||||
|
|
||||||
const ChatItem = forwardRef<Ref, Props>(({ message }, ref) => {
|
const ChatItem = forwardRef<Ref, Props>(({ message }, ref) => (
|
||||||
return (
|
<div ref={ref} className="py-4 even:bg-secondary dark:even:bg-secondary/20">
|
||||||
<div ref={ref} className="py-4 even:bg-secondary dark:even:bg-secondary/20">
|
<SimpleTextMessage
|
||||||
<SimpleTextMessage
|
status={message.status}
|
||||||
status={message.status}
|
key={message.id}
|
||||||
key={message.id}
|
avatarUrl={message.senderAvatarUrl}
|
||||||
avatarUrl={message.senderAvatarUrl}
|
senderName={message.senderName}
|
||||||
senderName={message.senderName}
|
createdAt={message.createdAt}
|
||||||
createdAt={message.createdAt}
|
senderType={message.messageSenderType}
|
||||||
senderType={message.messageSenderType}
|
text={message.text}
|
||||||
text={message.text}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
))
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
export default ChatItem
|
export default ChatItem
|
||||||
|
|||||||
2
web/types/chatMessage.d.ts
vendored
2
web/types/chatMessage.d.ts
vendored
@ -6,7 +6,7 @@ enum MessageType {
|
|||||||
Error = 'Error',
|
Error = 'Error',
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MessageSenderType {
|
export enum MessageSenderType {
|
||||||
Ai = 'assistant',
|
Ai = 'assistant',
|
||||||
User = 'user',
|
User = 'user',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,3 @@ export function mergeAndRemoveDuplicates(
|
|||||||
|
|
||||||
return result.reverse()
|
return result.reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const generateMessageId = () => {
|
|
||||||
return `m-${Date.now()}`
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user