Merge branch 'dev' into docs-pena-team
This commit is contained in:
commit
800789631d
@ -1,26 +1,37 @@
|
|||||||
import {
|
import { useCallback } from 'react'
|
||||||
fs,
|
|
||||||
joinPath,
|
import { fs, joinPath, openFileExplorer } from '@janhq/core'
|
||||||
openFileExplorer,
|
import { useAtomValue } from 'jotai'
|
||||||
getJanDataFolderPath,
|
|
||||||
} from '@janhq/core'
|
import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom'
|
||||||
|
|
||||||
export const useLogs = () => {
|
export const useLogs = () => {
|
||||||
const getLogs = async (file: string) => {
|
const janDataFolderPath = useAtomValue(janDataFolderPathAtom)
|
||||||
const path = await joinPath(['file://logs', `${file}.log`])
|
|
||||||
if (!(await fs.existsSync(path))) return {}
|
|
||||||
const logs = await fs.readFileSync(path, 'utf-8')
|
|
||||||
|
|
||||||
return logs
|
const getLogs = useCallback(
|
||||||
}
|
async (file: string) => {
|
||||||
const openServerLog = async () => {
|
const path = await joinPath(['file://logs', `${file}.log`])
|
||||||
const janDataFolderPath = await getJanDataFolderPath()
|
if (!(await fs.existsSync(path))) return ''
|
||||||
|
const logs = await fs.readFileSync(path, 'utf-8')
|
||||||
|
|
||||||
|
const sanitizedLogs = logs.replace(
|
||||||
|
new RegExp(`${janDataFolderPath}\\/`, 'g'),
|
||||||
|
'jan-data-folder/'
|
||||||
|
)
|
||||||
|
|
||||||
|
return sanitizedLogs
|
||||||
|
},
|
||||||
|
[janDataFolderPath]
|
||||||
|
)
|
||||||
|
|
||||||
|
const openServerLog = useCallback(async () => {
|
||||||
const fullPath = await joinPath([janDataFolderPath, 'logs', 'server.log'])
|
const fullPath = await joinPath([janDataFolderPath, 'logs', 'server.log'])
|
||||||
return openFileExplorer(fullPath)
|
return openFileExplorer(fullPath)
|
||||||
}
|
}, [janDataFolderPath])
|
||||||
|
|
||||||
const clearServerLog = async () => {
|
const clearServerLog = useCallback(async () => {
|
||||||
await fs.writeFileSync(await joinPath(['file://logs', 'server.log']), '')
|
await fs.writeFileSync(await joinPath(['file://logs', 'server.log']), '')
|
||||||
}
|
}, [])
|
||||||
|
|
||||||
return { getLogs, openServerLog, clearServerLog }
|
return { getLogs, openServerLog, clearServerLog }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,13 @@
|
|||||||
import {
|
import { openFileExplorer, joinPath, baseName } from '@janhq/core'
|
||||||
openFileExplorer,
|
|
||||||
joinPath,
|
|
||||||
getJanDataFolderPath,
|
|
||||||
baseName,
|
|
||||||
} from '@janhq/core'
|
|
||||||
import { useAtomValue } from 'jotai'
|
import { useAtomValue } from 'jotai'
|
||||||
|
|
||||||
import { selectedModelAtom } from '@/containers/DropdownListSidebar'
|
import { selectedModelAtom } from '@/containers/DropdownListSidebar'
|
||||||
|
|
||||||
|
import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom'
|
||||||
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
export const usePath = () => {
|
export const usePath = () => {
|
||||||
|
const janDataFolderPath = useAtomValue(janDataFolderPathAtom)
|
||||||
const activeThread = useAtomValue(activeThreadAtom)
|
const activeThread = useAtomValue(activeThreadAtom)
|
||||||
const selectedModel = useAtomValue(selectedModelAtom)
|
const selectedModel = useAtomValue(selectedModelAtom)
|
||||||
|
|
||||||
@ -18,7 +15,6 @@ export const usePath = () => {
|
|||||||
// TODO: this logic should be refactored.
|
// TODO: this logic should be refactored.
|
||||||
if (type !== 'Model' && !activeThread) return
|
if (type !== 'Model' && !activeThread) return
|
||||||
|
|
||||||
const userSpace = await getJanDataFolderPath()
|
|
||||||
let filePath = undefined
|
let filePath = undefined
|
||||||
const assistantId = activeThread?.assistants[0]?.assistant_id
|
const assistantId = activeThread?.assistants[0]?.assistant_id
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -40,7 +36,7 @@ export const usePath = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!filePath) return
|
if (!filePath) return
|
||||||
const fullPath = await joinPath([userSpace, filePath])
|
const fullPath = await joinPath([janDataFolderPath, filePath])
|
||||||
openFileExplorer(fullPath)
|
openFileExplorer(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +44,6 @@ export const usePath = () => {
|
|||||||
// TODO: this logic should be refactored.
|
// TODO: this logic should be refactored.
|
||||||
if (type !== 'Model' && !activeThread) return
|
if (type !== 'Model' && !activeThread) return
|
||||||
|
|
||||||
const userSpace = await getJanDataFolderPath()
|
|
||||||
let filePath = undefined
|
let filePath = undefined
|
||||||
const assistantId = activeThread?.assistants[0]?.assistant_id
|
const assistantId = activeThread?.assistants[0]?.assistant_id
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -74,31 +69,29 @@ export const usePath = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!filePath) return
|
if (!filePath) return
|
||||||
const fullPath = await joinPath([userSpace, filePath])
|
const fullPath = await joinPath([janDataFolderPath, filePath])
|
||||||
openFileExplorer(fullPath)
|
openFileExplorer(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onViewFile = async (id: string) => {
|
const onViewFile = async (id: string) => {
|
||||||
if (!activeThread) return
|
if (!activeThread) return
|
||||||
|
|
||||||
const userSpace = await getJanDataFolderPath()
|
|
||||||
let filePath = undefined
|
let filePath = undefined
|
||||||
|
|
||||||
id = await baseName(id)
|
id = await baseName(id)
|
||||||
filePath = await joinPath(['threads', `${activeThread.id}/files`, `${id}`])
|
filePath = await joinPath(['threads', `${activeThread.id}/files`, `${id}`])
|
||||||
if (!filePath) return
|
if (!filePath) return
|
||||||
const fullPath = await joinPath([userSpace, filePath])
|
const fullPath = await joinPath([janDataFolderPath, filePath])
|
||||||
openFileExplorer(fullPath)
|
openFileExplorer(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onViewFileContainer = async () => {
|
const onViewFileContainer = async () => {
|
||||||
if (!activeThread) return
|
if (!activeThread) return
|
||||||
|
|
||||||
const userSpace = await getJanDataFolderPath()
|
|
||||||
let filePath = undefined
|
let filePath = undefined
|
||||||
filePath = await joinPath(['threads', `${activeThread.id}/files`])
|
filePath = await joinPath(['threads', `${activeThread.id}/files`])
|
||||||
if (!filePath) return
|
if (!filePath) return
|
||||||
const fullPath = await joinPath([userSpace, filePath])
|
const fullPath = await joinPath([janDataFolderPath, filePath])
|
||||||
openFileExplorer(fullPath)
|
openFileExplorer(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -165,8 +165,7 @@ const ChatInput: React.FC = () => {
|
|||||||
if (
|
if (
|
||||||
fileUpload.length > 0 ||
|
fileUpload.length > 0 ||
|
||||||
(activeThread?.assistants[0].tools &&
|
(activeThread?.assistants[0].tools &&
|
||||||
!activeThread?.assistants[0].tools[0]?.enabled &&
|
!activeThread?.assistants[0].tools[0]?.enabled)
|
||||||
!activeThread?.assistants[0].model.settings.vision_model)
|
|
||||||
) {
|
) {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
} else {
|
} else {
|
||||||
@ -178,8 +177,7 @@ const ChatInput: React.FC = () => {
|
|||||||
<TooltipPortal>
|
<TooltipPortal>
|
||||||
{fileUpload.length > 0 ||
|
{fileUpload.length > 0 ||
|
||||||
(activeThread?.assistants[0].tools &&
|
(activeThread?.assistants[0].tools &&
|
||||||
!activeThread?.assistants[0].tools[0]?.enabled &&
|
!activeThread?.assistants[0].tools[0]?.enabled && (
|
||||||
!activeThread?.assistants[0].model.settings.vision_model && (
|
|
||||||
<TooltipContent side="top" className="max-w-[154px] px-3">
|
<TooltipContent side="top" className="max-w-[154px] px-3">
|
||||||
{fileUpload.length !== 0 && (
|
{fileUpload.length !== 0 && (
|
||||||
<span>
|
<span>
|
||||||
@ -205,7 +203,7 @@ const ChatInput: React.FC = () => {
|
|||||||
{showAttacmentMenus && (
|
{showAttacmentMenus && (
|
||||||
<div
|
<div
|
||||||
ref={refAttachmentMenus}
|
ref={refAttachmentMenus}
|
||||||
className="absolute bottom-10 right-0 w-36 cursor-pointer rounded-lg border border-border bg-background py-1 shadow"
|
className="absolute bottom-10 right-0 z-30 w-36 cursor-pointer rounded-lg border border-border bg-background py-1 shadow"
|
||||||
>
|
>
|
||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { useDropzone } from 'react-dropzone'
|
import { Accept, useDropzone } from 'react-dropzone'
|
||||||
|
|
||||||
import { useAtomValue, useSetAtom } from 'jotai'
|
import { useAtomValue, useSetAtom } from 'jotai'
|
||||||
|
|
||||||
@ -68,12 +68,22 @@ const ChatScreen: React.FC = () => {
|
|||||||
|
|
||||||
const isGeneratingResponse = useAtomValue(isGeneratingResponseAtom)
|
const isGeneratingResponse = useAtomValue(isGeneratingResponseAtom)
|
||||||
|
|
||||||
|
const acceptedFormat: Accept = activeThread?.assistants[0].model.settings
|
||||||
|
.vision_model
|
||||||
|
? {
|
||||||
|
'application/pdf': ['.pdf'],
|
||||||
|
'image/jpeg': ['.jpeg'],
|
||||||
|
'image/png': ['.png'],
|
||||||
|
'image/jpg': ['.jpg'],
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
'application/pdf': ['.pdf'],
|
||||||
|
}
|
||||||
|
|
||||||
const { getRootProps, isDragReject } = useDropzone({
|
const { getRootProps, isDragReject } = useDropzone({
|
||||||
noClick: true,
|
noClick: true,
|
||||||
multiple: false,
|
multiple: false,
|
||||||
accept: {
|
accept: acceptedFormat,
|
||||||
'application/pdf': ['.pdf'],
|
|
||||||
},
|
|
||||||
|
|
||||||
onDragOver: (e) => {
|
onDragOver: (e) => {
|
||||||
// Retrieval file drag and drop is experimental feature
|
// Retrieval file drag and drop is experimental feature
|
||||||
@ -164,10 +174,21 @@ const ChatScreen: React.FC = () => {
|
|||||||
<div className="mt-4 text-blue-600">
|
<div className="mt-4 text-blue-600">
|
||||||
<h6 className="font-bold">
|
<h6 className="font-bold">
|
||||||
{isDragReject
|
{isDragReject
|
||||||
? 'Currently, we only support 1 attachment at the same time with PDF format'
|
? `Currently, we only support 1 attachment at the same time with ${
|
||||||
|
activeThread?.assistants[0].model.settings
|
||||||
|
.vision_model
|
||||||
|
? 'PDF, JPEG, JPG, PNG'
|
||||||
|
: 'PDF'
|
||||||
|
} format`
|
||||||
: 'Drop file here'}
|
: 'Drop file here'}
|
||||||
</h6>
|
</h6>
|
||||||
{!isDragReject && <p className="mt-2">(PDF)</p>}
|
{!isDragReject && (
|
||||||
|
<p className="mt-2">
|
||||||
|
{activeThread?.assistants[0].model.settings.vision_model
|
||||||
|
? 'PDF, JPEG, JPG, PNG'
|
||||||
|
: 'PDF'}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user