Skip to content

Commit

Permalink
wip - apply feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
abeatrix committed Jan 6, 2025
1 parent 3ac1ef3 commit 9583a67
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 36 deletions.
6 changes: 3 additions & 3 deletions vscode/src/chat/agentic/CodyTool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { mockLocalStorage } from '../../services/LocalStorageProvider'
import type { ContextRetriever } from '../chat-view/ContextRetriever'
import { CodyTool, OpenCtxTool } from './CodyTool'
import { CodyToolProvider, ToolFactory, type ToolStatusCallback } from './CodyToolProvider'
import { toolboxSettings } from './ToolboxManager'
import { toolboxManager } from './ToolboxManager'

const mockCallback: ToolStatusCallback = {
onStart: vi.fn(),
Expand Down Expand Up @@ -210,7 +210,7 @@ describe('CodyTool', () => {

it('should register all default tools based on toolbox settings', () => {
const mockedToolboxSettings = { agent: 'mock-agent', shell: true }
vi.spyOn(toolboxSettings, 'getSettings').mockReturnValue(mockedToolboxSettings)
vi.spyOn(toolboxManager, 'getSettings').mockReturnValue(mockedToolboxSettings)
const localStorageData: { [key: string]: unknown } = {}
mockLocalStorage({
get: (key: string) => localStorageData[key],
Expand All @@ -227,7 +227,7 @@ describe('CodyTool', () => {

// Disable shell and check if terminal tool is removed.
mockedToolboxSettings.shell = false
vi.spyOn(toolboxSettings, 'getSettings').mockReturnValue(mockedToolboxSettings)
vi.spyOn(toolboxManager, 'getSettings').mockReturnValue(mockedToolboxSettings)
const newTools = CodyToolProvider.getTools()
expect(newTools.some(t => t.config.title.includes('Terminal'))).toBeFalsy()
expect(newTools.length).toBe(tools.length - 1)
Expand Down
6 changes: 3 additions & 3 deletions vscode/src/chat/agentic/CodyToolProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { mockLocalStorage } from '../../services/LocalStorageProvider'
import type { ContextRetriever } from '../chat-view/ContextRetriever'
import { CodyTool, type CodyToolConfig } from './CodyTool'
import { CodyToolProvider, type ToolConfiguration, ToolFactory } from './CodyToolProvider'
import { toolboxSettings } from './ToolboxManager'
import { toolboxManager } from './ToolboxManager'

const localStorageData: { [key: string]: unknown } = {}
mockLocalStorage({
Expand Down Expand Up @@ -89,13 +89,13 @@ describe('CodyToolProvider', () => {
})

it('should not include CLI tool if shell is disabled', () => {
vi.spyOn(toolboxSettings, 'getSettings').mockReturnValue({ agent: 'deep-cody', shell: false })
vi.spyOn(toolboxManager, 'getSettings').mockReturnValue({ agent: 'deep-cody', shell: false })
const tools = CodyToolProvider.getTools()
expect(tools.some(tool => tool.config.title === 'Terminal')).toBe(false)
})

it('should include CLI tool if shell is enabled', () => {
vi.spyOn(toolboxSettings, 'getSettings').mockReturnValue({ agent: 'deep-cody', shell: true })
vi.spyOn(toolboxManager, 'getSettings').mockReturnValue({ agent: 'deep-cody', shell: true })
const tools = CodyToolProvider.getTools()
expect(tools.some(tool => tool.config.title === 'Terminal')).toBe(true)
})
Expand Down
18 changes: 13 additions & 5 deletions vscode/src/chat/agentic/CodyToolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import {
type ContextMentionProviderMetadata,
PromptString,
type Unsubscribable,
isDefined,
openCtx,
openCtxProviderMetadata,
ps,
} from '@sourcegraph/cody-shared'
import { map } from 'observable-fns'
import type { ContextRetriever } from '../chat-view/ContextRetriever'
import { type CodyTool, type CodyToolConfig, OpenCtxTool, TOOL_CONFIGS } from './CodyTool'
import { toolboxSettings } from './ToolboxManager'
import { toolboxManager } from './ToolboxManager'
import { OPENCTX_TOOL_CONFIG } from './config'

/**
Expand Down Expand Up @@ -61,15 +62,15 @@ export class ToolFactory {
public getInstances(): CodyTool[] {
// Create fresh instances of all registered tools
return Array.from(this.tools.entries())
.filter(([name]) => name !== 'CliTool' || toolboxSettings.getSettings()?.shell)
.filter(([name]) => name !== 'CliTool' || toolboxManager.getSettings()?.shell)
.map(([_, config]) => config.createInstance(config, this.contextRetriever))
.filter(Boolean) as CodyTool[]
.filter(isDefined) as CodyTool[]
}

public createDefaultTools(contextRetriever?: Pick<ContextRetriever, 'retrieveContext'>): CodyTool[] {
return Object.entries(TOOL_CONFIGS)
.map(([name]) => this.createTool(name, contextRetriever))
.filter(Boolean) as CodyTool[]
.filter(isDefined) as CodyTool[]
}

public createOpenCtxTools(providers: ContextMentionProviderMetadata[]): CodyTool[] {
Expand Down Expand Up @@ -137,7 +138,7 @@ export class ToolFactory {
*/
export namespace CodyToolProvider {
export let factory: ToolFactory
let openCtxSubscription: Unsubscribable
let openCtxSubscription: Unsubscribable | undefined

export function initialize(contextRetriever: Pick<ContextRetriever, 'retrieveContext'>): void {
factory = new ToolFactory(contextRetriever)
Expand Down Expand Up @@ -174,4 +175,11 @@ export namespace CodyToolProvider {
})
}
}

export function dispose(): void {
if (openCtxSubscription) {
openCtxSubscription.unsubscribe()
openCtxSubscription = undefined
}
}
}
12 changes: 6 additions & 6 deletions vscode/src/chat/agentic/ToolboxManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ type StoredToolboxSettings = {
readonly shell: boolean
}

export class ToolboxManager {
/**
* ToolboxManager manages the toolbox settings for the Cody chat agents.
* NOTE: This is a Singleton class.
*/
class ToolboxManager {
private static readonly STORAGE_KEY = 'CODY_CHATAGENTS_TOOLBOX_SETTINGS'
private static instance?: ToolboxManager

private constructor() {
// Using private constructor for singleton pattern
// Using private constructor for Singleton pattern
}

private isEnabled = false
Expand Down Expand Up @@ -99,10 +103,6 @@ export class ToolboxManager {
return this.getSettings()
})
)

public get changes(): Observable<void> {
return this.changeNotifications
}
}

export const toolboxManager = ToolboxManager.getInstance()
8 changes: 4 additions & 4 deletions vscode/src/chat/chat-view/ChatController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ import {
import { openExternalLinks } from '../../services/utils/workspace-action'
import { TestSupport } from '../../test-support'
import type { MessageErrorType } from '../MessageProvider'
import { toolboxSettings } from '../agentic/ToolboxManager'
import { toolboxManager } from '../agentic/ToolboxManager'
import { getMentionMenuData } from '../context/chatContext'
import type { ChatIntentAPIClient } from '../context/chatIntentAPIClient'
import { observeDefaultContext } from '../initialContext'
Expand Down Expand Up @@ -662,7 +662,7 @@ export class ChatController implements vscode.Disposable, vscode.WebviewViewProv
editorState,
intent: detectedIntent,
manuallySelectedIntent: manuallySelectedIntent ? detectedIntent : undefined,
agent: toolboxSettings.getSettings()?.agent,
agent: toolboxManager.getSettings()?.agent,
})
this.postViewTranscript({ speaker: 'assistant' })

Expand Down Expand Up @@ -1534,10 +1534,10 @@ export class ChatController implements vscode.Disposable, vscode.WebviewViewProv
userProductSubscription.pipe(
map(value => (value === pendingOperation ? null : value))
),
toolboxSettings: () => toolboxSettings.settings,
toolboxSettings: () => toolboxManager.settings,
updateToolboxSettings: settings => {
return promiseFactoryToObservable(async () => {
await toolboxSettings.updatetoolboxSettings(settings)
await toolboxManager.updateToolboxSettings(settings)
})
},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AgentToolboxSettings, WebviewToExtensionAPI } from '@sourcegraph/cody-shared'
import { BotIcon, BotOffIcon } from 'lucide-react'
import { BrainIcon } from 'lucide-react'
import { type FC, memo, useCallback, useEffect, useState } from 'react'
import { Badge } from '../../../../../../components/shadcn/ui/badge'
import { Button } from '../../../../../../components/shadcn/ui/button'
Expand Down Expand Up @@ -151,22 +151,12 @@ export const ToolboxButton: FC<ToolboxButtonProps> = memo(({ settings, api }) =>
},
}}
>
<Button variant="ghost" className="!tw-p-1 !tw-opacity-100 tw-relative">
<Button variant="ghost" className="!tw-p-2 tw-relative">
<BrainIcon size={16} strokeWidth={1.25} className="tw-w-8 tw-h-8" />
{settings.agent ? (
<>
<BotIcon
size={16}
strokeWidth={1.25}
className="!tw-opacity-100 tw-w-8 tw-h-8"
/>
<span className="tw-absolute tw-top-0 tw-right-0 tw-w-2 tw-h-2 tw-rounded-full tw-bg-green-500 tw-animate-[pulse_5s_ease-in-out_infinite]" />
</>
<span className="tw-absolute tw-top-0 tw-right-0 tw-w-2 tw-h-2 tw-rounded-full tw-bg-green-500 tw-animate-[pulse_5s_ease-in-out_infinite]" />
) : (
<BotOffIcon
size={16}
strokeWidth={1.25}
className="!tw-opacity-100 tw-w-8 tw-h-8"
/>
<span className="tw-absolute tw-top-0 tw-right-0 tw-w-2 tw-h-2 tw-rounded-full tw-bg-red-500 tw-animate-[pulse_5s_ease-in-out_infinite]" />
)}
</Button>
</ToolbarPopoverItem>
Expand Down

0 comments on commit 9583a67

Please sign in to comment.