feat: allow users to enable and disable tools
This commit is contained in:
parent
5e80587138
commit
1630e2eb77
@ -63,7 +63,8 @@ export function useTollCallPromiseModal() {
|
|||||||
<div className="mt-4 flex justify-end gap-x-2">
|
<div className="mt-4 flex justify-end gap-x-2">
|
||||||
<ModalClose asChild>
|
<ModalClose asChild>
|
||||||
<Button
|
<Button
|
||||||
theme="ghost" variant="outline"
|
theme="ghost"
|
||||||
|
variant="outline"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setApprovedToolsAtom((prev) => {
|
setApprovedToolsAtom((prev) => {
|
||||||
const newState = { ...prev }
|
const newState = { ...prev }
|
||||||
@ -87,7 +88,12 @@ export function useTollCallPromiseModal() {
|
|||||||
</Button>
|
</Button>
|
||||||
</ModalClose>
|
</ModalClose>
|
||||||
<ModalClose asChild>
|
<ModalClose asChild>
|
||||||
<Button theme="ghost" variant="outline" onClick={handleConfirm} autoFocus>
|
<Button
|
||||||
|
theme="ghost"
|
||||||
|
variant="outline"
|
||||||
|
onClick={handleConfirm}
|
||||||
|
autoFocus
|
||||||
|
>
|
||||||
Allow once
|
Allow once
|
||||||
</Button>
|
</Button>
|
||||||
</ModalClose>
|
</ModalClose>
|
||||||
|
|||||||
@ -24,6 +24,7 @@ enum ThreadStorageAtomKeys {
|
|||||||
ThreadStates = 'threadStates',
|
ThreadStates = 'threadStates',
|
||||||
ThreadList = 'threadList',
|
ThreadList = 'threadList',
|
||||||
ThreadListReady = 'threadListReady',
|
ThreadListReady = 'threadListReady',
|
||||||
|
DisabledTools = 'disabledTools',
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Threads Atom
|
//// Threads Atom
|
||||||
@ -73,10 +74,18 @@ export const threadDataReadyAtom = atomWithStorage<boolean>(
|
|||||||
export const threadModelParamsAtom = atom<Record<string, ModelParams>>({})
|
export const threadModelParamsAtom = atom<Record<string, ModelParams>>({})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store the tool call approval thread id
|
* Store the tool call approval for thread id
|
||||||
*/
|
*/
|
||||||
export const approvedThreadToolsAtom = atom<Record<string, string[]>>({})
|
export const approvedThreadToolsAtom = atom<Record<string, string[]>>({})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the tool call disabled for thread id
|
||||||
|
*/
|
||||||
|
export const disabledThreadToolsAtom = atomWithStorage<string[]>(
|
||||||
|
ThreadStorageAtomKeys.DisabledTools,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
//// End Thread Atom
|
//// End Thread Atom
|
||||||
|
|
||||||
/// Active Thread Atom
|
/// Active Thread Atom
|
||||||
|
|||||||
@ -56,6 +56,7 @@ import { selectedModelAtom } from '@/helpers/atoms/Model.atom'
|
|||||||
import {
|
import {
|
||||||
activeThreadAtom,
|
activeThreadAtom,
|
||||||
approvedThreadToolsAtom,
|
approvedThreadToolsAtom,
|
||||||
|
disabledThreadToolsAtom,
|
||||||
engineParamsUpdateAtom,
|
engineParamsUpdateAtom,
|
||||||
getActiveThreadModelParamsAtom,
|
getActiveThreadModelParamsAtom,
|
||||||
isGeneratingResponseAtom,
|
isGeneratingResponseAtom,
|
||||||
@ -78,6 +79,7 @@ export default function useSendChatMessage(
|
|||||||
const deleteMessage = useSetAtom(deleteMessageAtom)
|
const deleteMessage = useSetAtom(deleteMessageAtom)
|
||||||
const setEditPrompt = useSetAtom(editPromptAtom)
|
const setEditPrompt = useSetAtom(editPromptAtom)
|
||||||
const approvedTools = useAtomValue(approvedThreadToolsAtom)
|
const approvedTools = useAtomValue(approvedThreadToolsAtom)
|
||||||
|
const disabledTools = useAtomValue(disabledThreadToolsAtom)
|
||||||
|
|
||||||
const currentMessages = useAtomValue(getCurrentChatMessagesAtom)
|
const currentMessages = useAtomValue(getCurrentChatMessagesAtom)
|
||||||
const selectedModel = useAtomValue(selectedModelAtom)
|
const selectedModel = useAtomValue(selectedModelAtom)
|
||||||
@ -196,15 +198,17 @@ export default function useSendChatMessage(
|
|||||||
},
|
},
|
||||||
activeThread,
|
activeThread,
|
||||||
messages ?? currentMessages,
|
messages ?? currentMessages,
|
||||||
(await window.core.api.getTools())?.map((tool: ModelTool) => ({
|
(await window.core.api.getTools())
|
||||||
type: 'function' as const,
|
?.filter((tool: ModelTool) => !disabledTools.includes(tool.name))
|
||||||
function: {
|
.map((tool: ModelTool) => ({
|
||||||
name: tool.name,
|
type: 'function' as const,
|
||||||
description: tool.description?.slice(0, 1024),
|
function: {
|
||||||
parameters: tool.inputSchema,
|
name: tool.name,
|
||||||
strict: false,
|
description: tool.description?.slice(0, 1024),
|
||||||
},
|
parameters: tool.inputSchema,
|
||||||
}))
|
strict: false,
|
||||||
|
},
|
||||||
|
}))
|
||||||
).addSystemMessage(activeAssistant.instructions)
|
).addSystemMessage(activeAssistant.instructions)
|
||||||
|
|
||||||
requestBuilder.pushMessage(prompt, base64Blob, fileUpload)
|
requestBuilder.pushMessage(prompt, base64Blob, fileUpload)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { useContext, useEffect, useRef, useState } from 'react'
|
import { useContext, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
|
|
||||||
import { InferenceEngine } from '@janhq/core'
|
import { InferenceEngine } from '@janhq/core'
|
||||||
|
|
||||||
@ -11,6 +11,7 @@ import {
|
|||||||
badgeVariants,
|
badgeVariants,
|
||||||
Badge,
|
Badge,
|
||||||
Modal,
|
Modal,
|
||||||
|
Switch,
|
||||||
} from '@janhq/joi'
|
} from '@janhq/joi'
|
||||||
import { useAtom, useAtomValue } from 'jotai'
|
import { useAtom, useAtomValue } from 'jotai'
|
||||||
import {
|
import {
|
||||||
@ -51,6 +52,7 @@ import { spellCheckAtom } from '@/helpers/atoms/Setting.atom'
|
|||||||
import {
|
import {
|
||||||
activeSettingInputBoxAtom,
|
activeSettingInputBoxAtom,
|
||||||
activeThreadAtom,
|
activeThreadAtom,
|
||||||
|
disabledThreadToolsAtom,
|
||||||
getActiveThreadIdAtom,
|
getActiveThreadIdAtom,
|
||||||
isBlockingSendAtom,
|
isBlockingSendAtom,
|
||||||
} from '@/helpers/atoms/Thread.atom'
|
} from '@/helpers/atoms/Thread.atom'
|
||||||
@ -69,6 +71,7 @@ const ChatInput = () => {
|
|||||||
const { showApprovalModal } = useContext(ChatContext)
|
const { showApprovalModal } = useContext(ChatContext)
|
||||||
const { sendChatMessage } = useSendChatMessage(showApprovalModal)
|
const { sendChatMessage } = useSendChatMessage(showApprovalModal)
|
||||||
const selectedModel = useAtomValue(selectedModelAtom)
|
const selectedModel = useAtomValue(selectedModelAtom)
|
||||||
|
const [disabledTools, setDisableTools] = useAtom(disabledThreadToolsAtom)
|
||||||
|
|
||||||
const activeThreadId = useAtomValue(getActiveThreadIdAtom)
|
const activeThreadId = useAtomValue(getActiveThreadIdAtom)
|
||||||
const [fileUpload, setFileUpload] = useAtom(fileUploadAtom)
|
const [fileUpload, setFileUpload] = useAtom(fileUploadAtom)
|
||||||
@ -89,6 +92,10 @@ const ChatInput = () => {
|
|||||||
activeTabThreadRightPanelAtom
|
activeTabThreadRightPanelAtom
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const availableTools = useMemo(() => {
|
||||||
|
return tools.filter((tool: ModelTool) => !disabledTools.includes(tool.name))
|
||||||
|
}, [tools, disabledTools])
|
||||||
|
|
||||||
const refAttachmentMenus = useClickOutside(() =>
|
const refAttachmentMenus = useClickOutside(() =>
|
||||||
setShowAttachmentMenus(false)
|
setShowAttachmentMenus(false)
|
||||||
)
|
)
|
||||||
@ -420,7 +427,7 @@ const ChatInput = () => {
|
|||||||
size={16}
|
size={16}
|
||||||
className="flex-shrink-0 cursor-pointer text-[hsla(var(--text-secondary))]"
|
className="flex-shrink-0 cursor-pointer text-[hsla(var(--text-secondary))]"
|
||||||
/>
|
/>
|
||||||
<span className="text-xs">{tools.length}</span>
|
<span className="text-xs">{availableTools.length}</span>
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
@ -449,11 +456,26 @@ const ChatInput = () => {
|
|||||||
size={16}
|
size={16}
|
||||||
className="flex-shrink-0 text-[hsla(var(--text-secondary))]"
|
className="flex-shrink-0 text-[hsla(var(--text-secondary))]"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div className="flex w-full flex-1 flex-row justify-between">
|
||||||
<div className="font-medium">{tool.name}</div>
|
<div>
|
||||||
<div className="text-sm text-[hsla(var(--text-secondary))]">
|
<div className="font-medium">{tool.name}</div>
|
||||||
{tool.description}
|
<div className="text-sm text-[hsla(var(--text-secondary))]">
|
||||||
|
{tool.description}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Switch
|
||||||
|
checked={!disabledTools.includes(tool.name)}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
setDisableTools((prev) =>
|
||||||
|
prev.filter((t) => t !== tool.name)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
setDisableTools([...disabledTools, tool.name])
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="flex-shrink-0"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user