remove assistant from web (#6468)
This commit is contained in:
parent
cf87313f28
commit
491012fa87
@ -1,198 +0,0 @@
|
|||||||
/**
|
|
||||||
* Web Assistant Extension
|
|
||||||
* Implements assistant management using IndexedDB
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Assistant, AssistantExtension } from '@janhq/core'
|
|
||||||
import { getSharedDB } from '../shared/db'
|
|
||||||
|
|
||||||
export default class AssistantExtensionWeb extends AssistantExtension {
|
|
||||||
private db: IDBDatabase | null = null
|
|
||||||
|
|
||||||
private defaultAssistant: Assistant = {
|
|
||||||
avatar: '👋',
|
|
||||||
thread_location: undefined,
|
|
||||||
id: 'jan',
|
|
||||||
object: 'assistant',
|
|
||||||
created_at: Date.now() / 1000,
|
|
||||||
name: 'Jan',
|
|
||||||
description:
|
|
||||||
'Jan is a helpful desktop assistant that can reason through complex tasks and use tools to complete them on the user\'s behalf.',
|
|
||||||
model: '*',
|
|
||||||
instructions:
|
|
||||||
'You are a helpful AI assistant. Your primary goal is to assist users with their questions and tasks to the best of your abilities.\n\n' +
|
|
||||||
'When responding:\n' +
|
|
||||||
'- Answer directly from your knowledge when you can\n' +
|
|
||||||
'- Be concise, clear, and helpful\n' +
|
|
||||||
'- Admit when you\'re unsure rather than making things up\n\n' +
|
|
||||||
'If tools are available to you:\n' +
|
|
||||||
'- Only use tools when they add real value to your response\n' +
|
|
||||||
'- Use tools when the user explicitly asks (e.g., "search for...", "calculate...", "run this code")\n' +
|
|
||||||
'- Use tools for information you don\'t know or that needs verification\n' +
|
|
||||||
'- Never use tools just because they\'re available\n\n' +
|
|
||||||
'When using tools:\n' +
|
|
||||||
'- Use one tool at a time and wait for results\n' +
|
|
||||||
'- Use actual values as arguments, not variable names\n' +
|
|
||||||
'- Learn from each result before deciding next steps\n' +
|
|
||||||
'- Avoid repeating the same tool call with identical parameters\n\n' +
|
|
||||||
'Remember: Most questions can be answered without tools. Think first whether you need them.\n\n' +
|
|
||||||
'Current date: {{current_date}}',
|
|
||||||
tools: [
|
|
||||||
{
|
|
||||||
type: 'retrieval',
|
|
||||||
enabled: false,
|
|
||||||
useTimeWeightedRetriever: false,
|
|
||||||
settings: {
|
|
||||||
top_k: 2,
|
|
||||||
chunk_size: 1024,
|
|
||||||
chunk_overlap: 64,
|
|
||||||
retrieval_template: `Use the following pieces of context to answer the question at the end.
|
|
||||||
{context}
|
|
||||||
Question: {question}
|
|
||||||
Helpful Answer:`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
file_ids: [],
|
|
||||||
metadata: undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
async onLoad() {
|
|
||||||
console.log('Loading Web Assistant Extension')
|
|
||||||
this.db = await getSharedDB()
|
|
||||||
|
|
||||||
// Create default assistant if none exist
|
|
||||||
const assistants = await this.getAssistants()
|
|
||||||
if (assistants.length === 0) {
|
|
||||||
await this.createAssistant(this.defaultAssistant)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onUnload() {
|
|
||||||
// Don't close shared DB, other extensions might be using it
|
|
||||||
this.db = null
|
|
||||||
}
|
|
||||||
|
|
||||||
private ensureDB(): void {
|
|
||||||
if (!this.db) {
|
|
||||||
throw new Error('Database not initialized. Call onLoad() first.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAssistants(): Promise<Assistant[]> {
|
|
||||||
this.ensureDB()
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = this.db!.transaction(['assistants'], 'readonly')
|
|
||||||
const store = transaction.objectStore('assistants')
|
|
||||||
const request = store.getAll()
|
|
||||||
|
|
||||||
request.onsuccess = () => {
|
|
||||||
resolve(request.result || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onerror = () => {
|
|
||||||
reject(request.error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async createAssistant(assistant: Assistant): Promise<void> {
|
|
||||||
this.ensureDB()
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = this.db!.transaction(['assistants'], 'readwrite')
|
|
||||||
const store = transaction.objectStore('assistants')
|
|
||||||
|
|
||||||
const assistantToStore = {
|
|
||||||
...assistant,
|
|
||||||
created_at: assistant.created_at || Date.now() / 1000,
|
|
||||||
}
|
|
||||||
|
|
||||||
const request = store.add(assistantToStore)
|
|
||||||
|
|
||||||
request.onsuccess = () => {
|
|
||||||
console.log('Assistant created:', assistant.id)
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onerror = () => {
|
|
||||||
console.error('Failed to create assistant:', request.error)
|
|
||||||
reject(request.error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateAssistant(id: string, assistant: Partial<Assistant>): Promise<void> {
|
|
||||||
this.ensureDB()
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = this.db!.transaction(['assistants'], 'readwrite')
|
|
||||||
const store = transaction.objectStore('assistants')
|
|
||||||
|
|
||||||
// First get the existing assistant
|
|
||||||
const getRequest = store.get(id)
|
|
||||||
|
|
||||||
getRequest.onsuccess = () => {
|
|
||||||
const existingAssistant = getRequest.result
|
|
||||||
if (!existingAssistant) {
|
|
||||||
reject(new Error(`Assistant with id ${id} not found`))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedAssistant = {
|
|
||||||
...existingAssistant,
|
|
||||||
...assistant,
|
|
||||||
id, // Ensure ID doesn't change
|
|
||||||
}
|
|
||||||
|
|
||||||
const putRequest = store.put(updatedAssistant)
|
|
||||||
|
|
||||||
putRequest.onsuccess = () => resolve()
|
|
||||||
putRequest.onerror = () => reject(putRequest.error)
|
|
||||||
}
|
|
||||||
|
|
||||||
getRequest.onerror = () => {
|
|
||||||
reject(getRequest.error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteAssistant(assistant: Assistant): Promise<void> {
|
|
||||||
this.ensureDB()
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = this.db!.transaction(['assistants'], 'readwrite')
|
|
||||||
const store = transaction.objectStore('assistants')
|
|
||||||
const request = store.delete(assistant.id)
|
|
||||||
|
|
||||||
request.onsuccess = () => {
|
|
||||||
console.log('Assistant deleted:', assistant.id)
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onerror = () => {
|
|
||||||
console.error('Failed to delete assistant:', request.error)
|
|
||||||
reject(request.error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async getAssistant(id: string): Promise<Assistant | null> {
|
|
||||||
this.ensureDB()
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const transaction = this.db!.transaction(['assistants'], 'readonly')
|
|
||||||
const store = transaction.objectStore('assistants')
|
|
||||||
const request = store.get(id)
|
|
||||||
|
|
||||||
request.onsuccess = () => {
|
|
||||||
resolve(request.result || null)
|
|
||||||
}
|
|
||||||
|
|
||||||
request.onerror = () => {
|
|
||||||
reject(request.error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
import type { WebExtensionRegistry } from './types'
|
import type { WebExtensionRegistry } from './types'
|
||||||
|
|
||||||
export { default as AssistantExtensionWeb } from './assistant-web'
|
|
||||||
export { default as ConversationalExtensionWeb } from './conversational-web'
|
export { default as ConversationalExtensionWeb } from './conversational-web'
|
||||||
export { default as JanProviderWeb } from './jan-provider-web'
|
export { default as JanProviderWeb } from './jan-provider-web'
|
||||||
export { default as MCPExtensionWeb } from './mcp-web'
|
export { default as MCPExtensionWeb } from './mcp-web'
|
||||||
@ -16,7 +15,6 @@ export type {
|
|||||||
WebExtensionModule,
|
WebExtensionModule,
|
||||||
WebExtensionName,
|
WebExtensionName,
|
||||||
WebExtensionLoader,
|
WebExtensionLoader,
|
||||||
AssistantWebModule,
|
|
||||||
ConversationalWebModule,
|
ConversationalWebModule,
|
||||||
JanProviderWebModule,
|
JanProviderWebModule,
|
||||||
MCPWebModule
|
MCPWebModule
|
||||||
@ -24,7 +22,6 @@ export type {
|
|||||||
|
|
||||||
// Extension registry for dynamic loading
|
// Extension registry for dynamic loading
|
||||||
export const WEB_EXTENSIONS: WebExtensionRegistry = {
|
export const WEB_EXTENSIONS: WebExtensionRegistry = {
|
||||||
'assistant-web': () => import('./assistant-web'),
|
|
||||||
'conversational-web': () => import('./conversational-web'),
|
'conversational-web': () => import('./conversational-web'),
|
||||||
'jan-provider-web': () => import('./jan-provider-web'),
|
'jan-provider-web': () => import('./jan-provider-web'),
|
||||||
'mcp-web': () => import('./mcp-web'),
|
'mcp-web': () => import('./mcp-web'),
|
||||||
|
|||||||
@ -2,14 +2,10 @@
|
|||||||
* Web Extension Types
|
* Web Extension Types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { AssistantExtension, ConversationalExtension, BaseExtension, AIEngine, MCPExtension } from '@janhq/core'
|
import type { ConversationalExtension, BaseExtension, AIEngine, MCPExtension } from '@janhq/core'
|
||||||
|
|
||||||
type ExtensionConstructorParams = ConstructorParameters<typeof BaseExtension>
|
type ExtensionConstructorParams = ConstructorParameters<typeof BaseExtension>
|
||||||
|
|
||||||
export interface AssistantWebModule {
|
|
||||||
default: new (...args: ExtensionConstructorParams) => AssistantExtension
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ConversationalWebModule {
|
export interface ConversationalWebModule {
|
||||||
default: new (...args: ExtensionConstructorParams) => ConversationalExtension
|
default: new (...args: ExtensionConstructorParams) => ConversationalExtension
|
||||||
}
|
}
|
||||||
@ -22,10 +18,9 @@ export interface MCPWebModule {
|
|||||||
default: new (...args: ExtensionConstructorParams) => MCPExtension
|
default: new (...args: ExtensionConstructorParams) => MCPExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WebExtensionModule = AssistantWebModule | ConversationalWebModule | JanProviderWebModule | MCPWebModule
|
export type WebExtensionModule = ConversationalWebModule | JanProviderWebModule | MCPWebModule
|
||||||
|
|
||||||
export interface WebExtensionRegistry {
|
export interface WebExtensionRegistry {
|
||||||
'assistant-web': () => Promise<AssistantWebModule>
|
|
||||||
'conversational-web': () => Promise<ConversationalWebModule>
|
'conversational-web': () => Promise<ConversationalWebModule>
|
||||||
'jan-provider-web': () => Promise<JanProviderWebModule>
|
'jan-provider-web': () => Promise<JanProviderWebModule>
|
||||||
'mcp-web': () => Promise<MCPWebModule>
|
'mcp-web': () => Promise<MCPWebModule>
|
||||||
|
|||||||
@ -28,7 +28,7 @@ const DropdownAssistant = () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const selectedAssistant =
|
const selectedAssistant =
|
||||||
assistants.find((a) => a.id === currentAssistant.id) || assistants[0]
|
assistants.find((a) => a.id === currentAssistant?.id) || assistants[0]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -46,7 +46,7 @@ const mainMenus = [
|
|||||||
title: 'common:assistants',
|
title: 'common:assistants',
|
||||||
icon: IconClipboardSmileFilled,
|
icon: IconClipboardSmileFilled,
|
||||||
route: route.assistant,
|
route: route.assistant,
|
||||||
isEnabled: true,
|
isEnabled: PlatformFeatures[PlatformFeature.ASSISTANTS],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'common:hub',
|
title: 'common:hub',
|
||||||
|
|||||||
@ -50,7 +50,7 @@ export const useAppState = create<AppState>()((set) => ({
|
|||||||
const currentAssistant = useAssistant.getState().currentAssistant
|
const currentAssistant = useAssistant.getState().currentAssistant
|
||||||
|
|
||||||
const selectedAssistant =
|
const selectedAssistant =
|
||||||
assistants.find((a) => a.id === currentAssistant.id) || assistants[0]
|
assistants.find((a) => a.id === currentAssistant?.id) || assistants[0]
|
||||||
|
|
||||||
set(() => ({
|
set(() => ({
|
||||||
streamingContent: content
|
streamingContent: content
|
||||||
|
|||||||
@ -2,10 +2,12 @@ import { getServiceHub } from '@/hooks/useServiceHub'
|
|||||||
import { Assistant as CoreAssistant } from '@janhq/core'
|
import { Assistant as CoreAssistant } from '@janhq/core'
|
||||||
import { create } from 'zustand'
|
import { create } from 'zustand'
|
||||||
import { localStorageKey } from '@/constants/localStorage'
|
import { localStorageKey } from '@/constants/localStorage'
|
||||||
|
import { PlatformFeatures } from '@/lib/platform/const'
|
||||||
|
import { PlatformFeature } from '@/lib/platform/types'
|
||||||
|
|
||||||
interface AssistantState {
|
interface AssistantState {
|
||||||
assistants: Assistant[]
|
assistants: Assistant[]
|
||||||
currentAssistant: Assistant
|
currentAssistant: Assistant | null
|
||||||
addAssistant: (assistant: Assistant) => void
|
addAssistant: (assistant: Assistant) => void
|
||||||
updateAssistant: (assistant: Assistant) => void
|
updateAssistant: (assistant: Assistant) => void
|
||||||
deleteAssistant: (id: string) => void
|
deleteAssistant: (id: string) => void
|
||||||
@ -46,12 +48,29 @@ export const defaultAssistant: Assistant = {
|
|||||||
'You are a helpful AI assistant. Your primary goal is to assist users with their questions and tasks to the best of your abilities.\n\nWhen responding:\n- Answer directly from your knowledge when you can\n- Be concise, clear, and helpful\n- Admit when you’re unsure rather than making things up\n\nIf tools are available to you:\n- Only use tools when they add real value to your response\n- Use tools when the user explicitly asks (e.g., "search for...", "calculate...", "run this code")\n- Use tools for information you don’t know or that needs verification\n- Never use tools just because they’re available\n\nWhen using tools:\n- Use one tool at a time and wait for results\n- Use actual values as arguments, not variable names\n- Learn from each result before deciding next steps\n- Avoid repeating the same tool call with identical parameters\n\nRemember: Most questions can be answered without tools. Think first whether you need them.\n\nCurrent date: {{current_date}}',
|
'You are a helpful AI assistant. Your primary goal is to assist users with their questions and tasks to the best of your abilities.\n\nWhen responding:\n- Answer directly from your knowledge when you can\n- Be concise, clear, and helpful\n- Admit when you’re unsure rather than making things up\n\nIf tools are available to you:\n- Only use tools when they add real value to your response\n- Use tools when the user explicitly asks (e.g., "search for...", "calculate...", "run this code")\n- Use tools for information you don’t know or that needs verification\n- Never use tools just because they’re available\n\nWhen using tools:\n- Use one tool at a time and wait for results\n- Use actual values as arguments, not variable names\n- Learn from each result before deciding next steps\n- Avoid repeating the same tool call with identical parameters\n\nRemember: Most questions can be answered without tools. Think first whether you need them.\n\nCurrent date: {{current_date}}',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAssistant = create<AssistantState>()((set, get) => ({
|
// Platform-aware initial state
|
||||||
|
const getInitialAssistantState = () => {
|
||||||
|
if (PlatformFeatures[PlatformFeature.ASSISTANTS]) {
|
||||||
|
return {
|
||||||
assistants: [defaultAssistant],
|
assistants: [defaultAssistant],
|
||||||
currentAssistant: defaultAssistant,
|
currentAssistant: defaultAssistant,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
assistants: [],
|
||||||
|
currentAssistant: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAssistant = create<AssistantState>((set, get) => ({
|
||||||
|
...getInitialAssistantState(),
|
||||||
addAssistant: (assistant) => {
|
addAssistant: (assistant) => {
|
||||||
set({ assistants: [...get().assistants, assistant] })
|
set({ assistants: [...get().assistants, assistant] })
|
||||||
getServiceHub().assistants().createAssistant(assistant as unknown as CoreAssistant).catch((error) => {
|
getServiceHub()
|
||||||
|
.assistants()
|
||||||
|
.createAssistant(assistant as unknown as CoreAssistant)
|
||||||
|
.catch((error) => {
|
||||||
console.error('Failed to create assistant:', error)
|
console.error('Failed to create assistant:', error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -63,25 +82,31 @@ export const useAssistant = create<AssistantState>()((set, get) => ({
|
|||||||
),
|
),
|
||||||
// Update currentAssistant if it's the same assistant being updated
|
// Update currentAssistant if it's the same assistant being updated
|
||||||
currentAssistant:
|
currentAssistant:
|
||||||
state.currentAssistant.id === assistant.id
|
state.currentAssistant?.id === assistant.id
|
||||||
? assistant
|
? assistant
|
||||||
: state.currentAssistant,
|
: state.currentAssistant,
|
||||||
})
|
})
|
||||||
// Create assistant already cover update logic
|
// Create assistant already cover update logic
|
||||||
getServiceHub().assistants().createAssistant(assistant as unknown as CoreAssistant).catch((error) => {
|
getServiceHub()
|
||||||
|
.assistants()
|
||||||
|
.createAssistant(assistant as unknown as CoreAssistant)
|
||||||
|
.catch((error) => {
|
||||||
console.error('Failed to update assistant:', error)
|
console.error('Failed to update assistant:', error)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
deleteAssistant: (id) => {
|
deleteAssistant: (id) => {
|
||||||
const state = get()
|
const state = get()
|
||||||
getServiceHub().assistants().deleteAssistant(
|
getServiceHub()
|
||||||
|
.assistants()
|
||||||
|
.deleteAssistant(
|
||||||
state.assistants.find((e) => e.id === id) as unknown as CoreAssistant
|
state.assistants.find((e) => e.id === id) as unknown as CoreAssistant
|
||||||
).catch((error) => {
|
)
|
||||||
|
.catch((error) => {
|
||||||
console.error('Failed to delete assistant:', error)
|
console.error('Failed to delete assistant:', error)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Check if we're deleting the current assistant
|
// Check if we're deleting the current assistant
|
||||||
const wasCurrentAssistant = state.currentAssistant.id === id
|
const wasCurrentAssistant = state.currentAssistant?.id === id
|
||||||
|
|
||||||
set({ assistants: state.assistants.filter((a) => a.id !== id) })
|
set({ assistants: state.assistants.filter((a) => a.id !== id) })
|
||||||
|
|
||||||
|
|||||||
@ -73,7 +73,7 @@ export const useChat = () => {
|
|||||||
}, [provider, selectedProvider])
|
}, [provider, selectedProvider])
|
||||||
|
|
||||||
const selectedAssistant =
|
const selectedAssistant =
|
||||||
assistants.find((a) => a.id === currentAssistant.id) || assistants[0]
|
assistants.find((a) => a.id === currentAssistant?.id) || assistants[0]
|
||||||
|
|
||||||
const getCurrentThread = useCallback(async () => {
|
const getCurrentThread = useCallback(async () => {
|
||||||
let currentThread = retrieveThread()
|
let currentThread = retrieveThread()
|
||||||
@ -237,7 +237,7 @@ export const useChat = () => {
|
|||||||
|
|
||||||
const builder = new CompletionMessagesBuilder(
|
const builder = new CompletionMessagesBuilder(
|
||||||
messages,
|
messages,
|
||||||
renderInstructions(currentAssistant?.instructions)
|
currentAssistant ? renderInstructions(currentAssistant.instructions) : undefined
|
||||||
)
|
)
|
||||||
if (troubleshooting) builder.addUserMessage(message, attachments)
|
if (troubleshooting) builder.addUserMessage(message, attachments)
|
||||||
|
|
||||||
@ -284,10 +284,10 @@ export const useChat = () => {
|
|||||||
builder.getMessages(),
|
builder.getMessages(),
|
||||||
abortController,
|
abortController,
|
||||||
availableTools,
|
availableTools,
|
||||||
currentAssistant.parameters?.stream === false ? false : true,
|
currentAssistant?.parameters?.stream === false ? false : true,
|
||||||
{
|
{
|
||||||
...modelSettings,
|
...modelSettings,
|
||||||
...currentAssistant.parameters,
|
...(currentAssistant?.parameters || {}),
|
||||||
} as unknown as Record<string, object>
|
} as unknown as Record<string, object>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export const useMessages = create<MessageState>()((set, get) => ({
|
|||||||
const currentAssistant = useAssistant.getState().currentAssistant
|
const currentAssistant = useAssistant.getState().currentAssistant
|
||||||
|
|
||||||
const selectedAssistant =
|
const selectedAssistant =
|
||||||
assistants.find((a) => a.id === currentAssistant.id) || assistants[0]
|
assistants.find((a) => a.id === currentAssistant?.id) || assistants[0]
|
||||||
|
|
||||||
const newMessage = {
|
const newMessage = {
|
||||||
...message,
|
...message,
|
||||||
|
|||||||
@ -49,4 +49,7 @@ export const PlatformFeatures: Record<PlatformFeature, boolean> = {
|
|||||||
|
|
||||||
// Extensions settings page - disabled for web
|
// Extensions settings page - disabled for web
|
||||||
[PlatformFeature.EXTENSIONS_SETTINGS]: isPlatformTauri(),
|
[PlatformFeature.EXTENSIONS_SETTINGS]: isPlatformTauri(),
|
||||||
|
|
||||||
|
// Assistant functionality - disabled for web
|
||||||
|
[PlatformFeature.ASSISTANTS]: isPlatformTauri(),
|
||||||
}
|
}
|
||||||
@ -51,4 +51,7 @@ export enum PlatformFeature {
|
|||||||
|
|
||||||
// Extensions settings page management
|
// Extensions settings page management
|
||||||
EXTENSIONS_SETTINGS = 'extensionsSettings',
|
EXTENSIONS_SETTINGS = 'extensionsSettings',
|
||||||
|
|
||||||
|
// Assistant functionality (creation, editing, management)
|
||||||
|
ASSISTANTS = 'assistants',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import AddEditAssistant from '@/containers/dialogs/AddEditAssistant'
|
|||||||
import { DeleteAssistantDialog } from '@/containers/dialogs'
|
import { DeleteAssistantDialog } from '@/containers/dialogs'
|
||||||
import { AvatarEmoji } from '@/containers/AvatarEmoji'
|
import { AvatarEmoji } from '@/containers/AvatarEmoji'
|
||||||
import { useTranslation } from '@/i18n/react-i18next-compat'
|
import { useTranslation } from '@/i18n/react-i18next-compat'
|
||||||
|
import { PlatformGuard } from '@/lib/platform/PlatformGuard'
|
||||||
|
import { PlatformFeature } from '@/lib/platform/types'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export const Route = createFileRoute(route.assistant as any)({
|
export const Route = createFileRoute(route.assistant as any)({
|
||||||
@ -17,6 +19,14 @@ export const Route = createFileRoute(route.assistant as any)({
|
|||||||
})
|
})
|
||||||
|
|
||||||
function Assistant() {
|
function Assistant() {
|
||||||
|
return (
|
||||||
|
<PlatformGuard feature={PlatformFeature.ASSISTANTS}>
|
||||||
|
<AssistantContent />
|
||||||
|
</PlatformGuard>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function AssistantContent() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { assistants, addAssistant, updateAssistant, deleteAssistant } =
|
const { assistants, addAssistant, updateAssistant, deleteAssistant } =
|
||||||
useAssistant()
|
useAssistant()
|
||||||
|
|||||||
@ -18,6 +18,8 @@ type SearchParams = {
|
|||||||
import DropdownAssistant from '@/containers/DropdownAssistant'
|
import DropdownAssistant from '@/containers/DropdownAssistant'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useThreads } from '@/hooks/useThreads'
|
import { useThreads } from '@/hooks/useThreads'
|
||||||
|
import { PlatformFeatures } from '@/lib/platform/const'
|
||||||
|
import { PlatformFeature } from '@/lib/platform/types'
|
||||||
|
|
||||||
export const Route = createFileRoute(route.home as any)({
|
export const Route = createFileRoute(route.home as any)({
|
||||||
component: Index,
|
component: Index,
|
||||||
@ -54,7 +56,7 @@ function Index() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col flex-justify-center">
|
<div className="flex h-full flex-col flex-justify-center">
|
||||||
<HeaderPage>
|
<HeaderPage>
|
||||||
<DropdownAssistant />
|
{PlatformFeatures[PlatformFeature.ASSISTANTS] && <DropdownAssistant />}
|
||||||
</HeaderPage>
|
</HeaderPage>
|
||||||
<div className="h-full px-4 md:px-8 overflow-y-auto flex flex-col gap-2 justify-center">
|
<div className="h-full px-4 md:px-8 overflow-y-auto flex flex-col gap-2 justify-center">
|
||||||
<div className="w-full md:w-4/6 mx-auto">
|
<div className="w-full md:w-4/6 mx-auto">
|
||||||
|
|||||||
@ -24,6 +24,8 @@ import { useTranslation } from '@/i18n/react-i18next-compat'
|
|||||||
import { useChat } from '@/hooks/useChat'
|
import { useChat } from '@/hooks/useChat'
|
||||||
import { useSmallScreen } from '@/hooks/useMediaQuery'
|
import { useSmallScreen } from '@/hooks/useMediaQuery'
|
||||||
import { useTools } from '@/hooks/useTools'
|
import { useTools } from '@/hooks/useTools'
|
||||||
|
import { PlatformFeatures } from '@/lib/platform/const'
|
||||||
|
import { PlatformFeature } from '@/lib/platform/types'
|
||||||
|
|
||||||
// as route.threadsDetail
|
// as route.threadsDetail
|
||||||
export const Route = createFileRoute('/threads/$threadId')({
|
export const Route = createFileRoute('/threads/$threadId')({
|
||||||
@ -300,7 +302,7 @@ function ThreadDetail() {
|
|||||||
<div className="flex flex-col h-full">
|
<div className="flex flex-col h-full">
|
||||||
<HeaderPage>
|
<HeaderPage>
|
||||||
<div className="flex items-center justify-between w-full pr-2">
|
<div className="flex items-center justify-between w-full pr-2">
|
||||||
<DropdownAssistant />
|
{PlatformFeatures[PlatformFeature.ASSISTANTS] && <DropdownAssistant />}
|
||||||
</div>
|
</div>
|
||||||
</HeaderPage>
|
</HeaderPage>
|
||||||
<div className="flex flex-col h-[calc(100%-40px)]">
|
<div className="flex flex-col h-[calc(100%-40px)]">
|
||||||
|
|||||||
@ -23,6 +23,7 @@ vi.mock('@/lib/platform/const', () => ({
|
|||||||
mcpAutoApproveTools: false,
|
mcpAutoApproveTools: false,
|
||||||
mcpServersSettings: true,
|
mcpServersSettings: true,
|
||||||
extensionsSettings: true,
|
extensionsSettings: true,
|
||||||
|
assistants: true,
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user