Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion extensions/assistant-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default class JanAssistantExtension extends AssistantExtension {
'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 have access to a set of tools to help you answer the user’s question. You can use only one tool per message, and you’ll receive the result of that tool in the user’s next response. To complete a task, use tools step by step—each step should be guided by the outcome of the previous one.\nTool Usage Rules:\n1. Always provide the correct values as arguments when using tools. Do not pass variable names—use actual values instead.\n2. You may perform multiple tool steps to complete a task.\n3. Avoid repeating a tool call with exactly the same parameters to prevent infinite loops.',
'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.',
tools: [
{
type: 'retrieval',
Expand Down
74 changes: 39 additions & 35 deletions web-app/src/hooks/__tests__/useAssistant.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,99 +22,99 @@ describe('useAssistant', () => {

it('should initialize with default state', () => {
const { result } = renderHook(() => useAssistant())

expect(result.current.assistants).toEqual([defaultAssistant])
expect(result.current.currentAssistant).toEqual(defaultAssistant)
})

it('should add assistant', () => {
const { result } = renderHook(() => useAssistant())

const newAssistant = {
id: 'assistant-2',
name: 'New Assistant',
avatar: '🤖',
description: 'A new assistant',
instructions: 'Help the user',
created_at: Date.now(),
parameters: {}
parameters: {},
}

act(() => {
result.current.addAssistant(newAssistant)
})

expect(result.current.assistants).toHaveLength(2)
expect(result.current.assistants).toContain(newAssistant)
})

it('should update assistant', () => {
const { result } = renderHook(() => useAssistant())

const updatedAssistant = {
...defaultAssistant,
name: 'Updated Jan',
description: 'Updated description'
description: 'Updated description',
}

act(() => {
result.current.updateAssistant(updatedAssistant)
})

expect(result.current.assistants[0].name).toBe('Updated Jan')
expect(result.current.assistants[0].description).toBe('Updated description')
})

it('should delete assistant', () => {
const { result } = renderHook(() => useAssistant())

const assistant2 = {
id: 'assistant-2',
name: 'Assistant 2',
avatar: '🤖',
description: 'Second assistant',
instructions: 'Help the user',
created_at: Date.now(),
parameters: {}
parameters: {},
}

act(() => {
result.current.addAssistant(assistant2)
})

expect(result.current.assistants).toHaveLength(2)

act(() => {
result.current.deleteAssistant('assistant-2')
})

expect(result.current.assistants).toHaveLength(1)
expect(result.current.assistants[0].id).toBe('jan')
})

it('should set current assistant', () => {
const { result } = renderHook(() => useAssistant())

const newAssistant = {
id: 'assistant-2',
name: 'New Current Assistant',
avatar: '🤖',
description: 'New current assistant',
instructions: 'Help the user',
created_at: Date.now(),
parameters: {}
parameters: {},
}

act(() => {
result.current.setCurrentAssistant(newAssistant)
})

expect(result.current.currentAssistant).toEqual(newAssistant)
})

it('should set assistants', () => {
const { result } = renderHook(() => useAssistant())

const assistants = [
{
id: 'assistant-1',
Expand All @@ -123,7 +123,7 @@ describe('useAssistant', () => {
description: 'First assistant',
instructions: 'Help the user',
created_at: Date.now(),
parameters: {}
parameters: {},
},
{
id: 'assistant-2',
Expand All @@ -132,52 +132,56 @@ describe('useAssistant', () => {
description: 'Second assistant',
instructions: 'Help with tasks',
created_at: Date.now(),
parameters: {}
}
parameters: {},
},
]

act(() => {
result.current.setAssistants(assistants)
})

expect(result.current.assistants).toEqual(assistants)
expect(result.current.assistants).toHaveLength(2)
})

it('should maintain assistant structure', () => {
const { result } = renderHook(() => useAssistant())

expect(result.current.currentAssistant.id).toBe('jan')
expect(result.current.currentAssistant.name).toBe('Jan')
expect(result.current.currentAssistant.avatar).toBe('👋')
expect(result.current.currentAssistant.description).toContain('helpful desktop assistant')
expect(result.current.currentAssistant.instructions).toContain('access to a set of tools')
expect(result.current.currentAssistant.description).toContain(
'helpful desktop assistant'
)
expect(result.current.currentAssistant.instructions).toContain(
'Only use tools when they add real value to your response'
)
expect(typeof result.current.currentAssistant.created_at).toBe('number')
expect(typeof result.current.currentAssistant.parameters).toBe('object')
})

it('should handle empty assistants list', () => {
const { result } = renderHook(() => useAssistant())

act(() => {
result.current.setAssistants([])
})

expect(result.current.assistants).toEqual([])
})

it('should update assistant in current assistant if it matches', () => {
const { result } = renderHook(() => useAssistant())

const updatedDefaultAssistant = {
...defaultAssistant,
name: 'Updated Jan Name'
name: 'Updated Jan Name',
}

act(() => {
result.current.updateAssistant(updatedDefaultAssistant)
})

expect(result.current.currentAssistant.name).toBe('Updated Jan Name')
})
})
})
2 changes: 1 addition & 1 deletion web-app/src/hooks/useAssistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
description:
'Jan is a helpful desktop assistant that can reason through complex tasks and use tools to complete them on the user’s behalf.',
instructions:
'You have access to a set of tools to help you answer the user’s question. You can use only one tool per message, and you’ll receive the result of that tool in the user’s next response. To complete a task, use tools step by step—each step should be guided by the outcome of the previous one.\nTool Usage Rules:\n1. Always provide the correct values as arguments when using tools. Do not pass variable names—use actual values instead.\n2. You may perform multiple tool steps to complete a task.\n3. Avoid repeating a tool call with exactly the same parameters to prevent infinite loops.',
'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.',
}

export const useAssistant = create<AssistantState>()((set, get) => ({
Expand All @@ -30,7 +30,7 @@
addAssistant: (assistant) => {
set({ assistants: [...get().assistants, assistant] })
createAssistant(assistant as unknown as CoreAssistant).catch((error) => {
console.error('Failed to create assistant:', error)

Check warning on line 33 in web-app/src/hooks/useAssistant.ts

View workflow job for this annotation

GitHub Actions / coverage-check

33 line is not covered with tests
})
},
updateAssistant: (assistant) => {
Expand All @@ -43,18 +43,18 @@
currentAssistant:
state.currentAssistant.id === assistant.id
? assistant
: state.currentAssistant,

Check warning on line 46 in web-app/src/hooks/useAssistant.ts

View workflow job for this annotation

GitHub Actions / coverage-check

46 line is not covered with tests
})
// Create assistant already cover update logic
createAssistant(assistant as unknown as CoreAssistant).catch((error) => {
console.error('Failed to update assistant:', error)

Check warning on line 50 in web-app/src/hooks/useAssistant.ts

View workflow job for this annotation

GitHub Actions / coverage-check

50 line is not covered with tests
})
},
deleteAssistant: (id) => {
deleteAssistant(
get().assistants.find((e) => e.id === id) as unknown as CoreAssistant
).catch((error) => {
console.error('Failed to delete assistant:', error)

Check warning on line 57 in web-app/src/hooks/useAssistant.ts

View workflow job for this annotation

GitHub Actions / coverage-check

57 line is not covered with tests
})
set({ assistants: get().assistants.filter((a) => a.id !== id) })
},
Expand Down
Loading