Skip to content

Commit

Permalink
chore: update pnpm lockfile for modelcontextprotocoltools dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
arafatkatze committed Jan 15, 2025
1 parent 1888719 commit 313448c
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 58 deletions.
2 changes: 1 addition & 1 deletion lib/shared/src/context/openctx/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ export const REMOTE_DIRECTORY_PROVIDER_URI = 'internal-remote-directory-search'
export const WEB_PROVIDER_URI = 'internal-web-provider'
export const GIT_OPENCTX_PROVIDER_URI = 'internal-git-openctx-provider'
export const CODE_SEARCH_PROVIDER_URI = 'internal-code-search-provider'
export const MODEL_CONTEXT_PROVIDER_URI = 'internal-model-context-provider'
export const MODEL_CONTEXT_PROVIDER_URI = 'internal-model-context-provider'
48 changes: 47 additions & 1 deletion vscode/src/chat/agentic/CodyTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type ContextItemWithContent,
type ContextMentionProviderMetadata,
MODEL_CONTEXT_PROVIDER_URI,
type MentionQuery,
PromptString,
firstValueFrom,
logDebug,
Expand Down Expand Up @@ -150,7 +151,7 @@ class CliTool extends CodyTool {
},
prompt: {
instruction: ps`Reject all unsafe and harmful commands with <ban> tags. Execute safe command for its output with <cmd> tags`,
placeholder: ps`SAFE_COMMAND`,
placeholder: PromptString.unsafe_fromUserQuery('INPUT'),
examples: [
ps`Get output for git diff: \`<TOOLCLI><cmd>git diff</cmd></TOOLCLI>\``,
ps`List files in a directory: \`<TOOLCLI><cmd>ls -l</cmd></TOOLCLI>\``,
Expand Down Expand Up @@ -320,6 +321,23 @@ export class OpenCtxTool extends CodyTool {
super(config)
}

parse(): string[] {
if (this.provider.id === 'internal-model-context-provider') {
return [this.unprocessedText]
}
return super.parse()
}

parseMCPMentionQuery(
query: string,
idObject: Pick<ContextMentionProviderMetadata, 'id'>
): MentionQuery {
return {
provider: idObject.id,
text: query,
}
}

async execute(span: Span, queries: string[]): Promise<ContextItem[]> {
span.addEvent('executeOpenCtxTool')
const openCtxClient = openCtx.controller
Expand All @@ -331,7 +349,35 @@ export class OpenCtxTool extends CodyTool {
try {
// TODO: Investigate if we can batch queries for better performance.
// For example, would it cause issues if we fire 10 requests to a OpenCtx provider for fetching Linear?
const toolName = this.config.title

console.log('toolName', toolName)

for (const query of queries) {
if (this.provider.id === 'internal-model-context-provider') {
const mcpResults = await openCtxClient.items(
{ mention: { uri: '', title: this.config.title, data: JSON.parse(query) } },
{ providerUri: MODEL_CONTEXT_PROVIDER_URI }
)
console.log(mcpResults)
const itemsWithContent = mcpResults.map(item => ({
type: 'openctx' as const,
title: item.title || '',
uri: URI.parse(''),
providerUri: MODEL_CONTEXT_PROVIDER_URI,
content: item.ai?.content || '',
provider: 'openctx' as const,
source: ContextItemSource.Agentic,
mention: {
uri: '',
data: item.ai,
description: item.ai?.content,
},
}))
results.push(...itemsWithContent)
continue
}

const mention = parseMentionQuery(query, idObject)
// First get the items without content
const openCtxItems = await getChatContextItemsForMention({ mentionQuery: mention })
Expand Down
117 changes: 65 additions & 52 deletions vscode/src/chat/agentic/CodyToolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import {
isDefined,
openCtx,
openCtxProviderMetadata,
parseMentionQuery,
ps,
} from '@sourcegraph/cody-shared'
import { map } from 'observable-fns'
import type { ContextRetriever } from '../chat-view/ContextRetriever'
import { getChatContextItemsForMention } from '../context/chatContext'
import { type CodyTool, type CodyToolConfig, OpenCtxTool, TOOL_CONFIGS } from './CodyTool'
import { toolboxManager } from './ToolboxManager'
import { OPENCTX_TOOL_CONFIG } from './config'
Expand Down Expand Up @@ -97,18 +95,55 @@ class ToolFactory {
const tools: CodyTool[] = []

for (const provider of providers) {
const toolName = this.generateToolName(provider)
const config = this.getToolConfig(provider)
if (provider.id === 'internal-model-context-provider') {
// For MCP providers, get available tools through the mentions() function
// get the Vscode Regex Here for query
const mcpTools =
(await openCtx.controller?.mentions(
{ query: 'echo' },
{ providerUri: provider.id }
)) ?? []

this.register({
name: toolName,
...config,
createInstance: cfg => new OpenCtxTool(provider, cfg),
})
for (const mcpTool of mcpTools) {
const toolName = this.generateToolName({
...provider,
title: mcpTool.title ?? provider.title,
})
const config = this.createModelContextConfig(
{
title: mcpTool.title ?? '',
description: mcpTool.description ?? '',
data: mcpTool.data,
},
toolName
)

this.register({
name: toolName,
...config,
createInstance: cfg => new OpenCtxTool(provider, cfg),
})

const tool = this.createTool(toolName)
if (tool) {
tools.push(tool)
}
}
} else {
// For regular providers, create a single tool as before
const toolName = this.generateToolName(provider)
const config = this.getToolConfig(provider)

const tool = this.createTool(toolName)
if (tool) {
tools.push(tool)
this.register({
name: toolName,
...config,
createInstance: cfg => new OpenCtxTool(provider, cfg),
})

const tool = this.createTool(toolName)
if (tool) {
tools.push(tool)
}
}
}

Expand Down Expand Up @@ -136,11 +171,6 @@ class ToolFactory {
if (defaultConfig) {
return defaultConfig[1]
}
// Check if the provider is a model context protocol provider
if (provider.id === 'internal-model-context-provider') {
// TODO: Moves createModelContextConfig logic into this function.
return this.createModelContextConfig(provider.id, provider.title)
}
return {
title: provider.title,
tags: {
Expand All @@ -156,24 +186,30 @@ class ToolFactory {
}
// TODO: Handles this in getToolConfig instead of
// having a separate function specific to model context protocol
private createModelContextConfig(mention: any, tagName: string): CodyToolConfig {
private createModelContextConfig(
mention: {
title: string
description: string
data?: any
},
tagName: string
): CodyToolConfig {
// Extract schema properties for better instruction formatting
const schemaProperties = mention.data?.properties || {}

return {
title: `${mention.title} (via MCP)`,
title: mention.title,
tags: {
tag: PromptString.unsafe_fromUserQuery(tagName),
subTag: ps`query`,
subTag: ps`QUERY`,
},
prompt: {
instruction: PromptString.unsafe_fromUserQuery(
`Use ${mention.title} to ${mention.description || 'retrieve context'}. ` +
`Input must follow this schema: ${JSON.stringify(
mention.data?.properties,
null,
2
)}` +
`Input must follow this schema::\n${JSON.stringify(schemaProperties, null, 2)}` +
'Ensure all required properties are provided and types match the schema.'
),
placeholder: ps`QUERY`,
placeholder: PromptString.unsafe_fromUserQuery('INPUT'),
examples: [
PromptString.unsafe_fromUserQuery(
`To use ${mention.title} with valid schema: \`<${tagName}>${JSON.stringify({
Expand Down Expand Up @@ -232,34 +268,11 @@ export class CodyToolProvider {
.metaChanges({}, {})
.pipe(
map(providers =>
providers
.filter(p => !!p.mentions)
.map(async p => {
if (p.providerUri === 'internal-model-context-provider') {
const idObject: Pick<ContextMentionProviderMetadata, 'id'> = {
id: p.providerUri,
}
const mention = parseMentionQuery('', idObject)
const mentions = await getChatContextItemsForMention({
mentionQuery: mention,
})
for (const mention of mentions) {
return openCtxProviderMetadata({
providerUri: p.providerUri.toString(),
name: mention.title ?? 'MCP Tool',
mentions: {
label: 'MCP Tool: ' + mention.title,
},
})
}
}
return openCtxProviderMetadata(p)
})
providers.filter(p => !!p.mentions).map(p => openCtxProviderMetadata(p))
)
)
.subscribe(async providerMeta => {
const resolvedProviders = await Promise.all(providerMeta)
provider.factory.createOpenCtxTools(resolvedProviders)
.subscribe(async providers => {
provider.factory.createOpenCtxTools(providers)
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion vscode/src/chat/context/chatContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export async function getChatContextItemsForMention(
if (!openCtx.controller) {
return []
}

// For MCP provider, we need to call items() with the mention
const items = await openCtx.controller.mentions(
{
query: mentionQuery.text,
Expand Down
10 changes: 10 additions & 0 deletions vscode/src/context/openctx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
type ClientConfiguration,
FeatureFlag,
GIT_OPENCTX_PROVIDER_URI,
MODEL_CONTEXT_PROVIDER_URI,
WEB_PROVIDER_URI,
authStatus,
clientCapabilities,
Expand Down Expand Up @@ -35,6 +36,7 @@ import { logDebug } from '../output-channel-logger'
import { createCodeSearchProvider } from './openctx/codeSearch'
import { gitMentionsProvider } from './openctx/git'
import LinearIssuesProvider from './openctx/linear-issues'
import { createModelContextProvider } from './openctx/modelContextProvider'
import RemoteDirectoryProvider, { createRemoteDirectoryProvider } from './openctx/remoteDirectorySearch'
import RemoteFileProvider, { createRemoteFileProvider } from './openctx/remoteFileSearch'
import RemoteRepositorySearch, { createRemoteRepositoryProvider } from './openctx/remoteRepositorySearch'
Expand Down Expand Up @@ -185,6 +187,14 @@ export function getOpenCtxProviders(
providerUri: CODE_SEARCH_PROVIDER_URI,
})
}
// enable MCP provider
providers.push({
settings: true,
provider: createModelContextProvider(
'file:///Users/arafatkhan/Desktop/servers/src/everything/dist/index.js'
),
providerUri: MODEL_CONTEXT_PROVIDER_URI,
})

return providers
}
Expand Down
5 changes: 2 additions & 3 deletions vscode/src/context/openctx/modelContextProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import proxy from '@openctx/provider-modelcontextprotocoltools'
import { MODEL_CONTEXT_PROVIDER_URI } from '@sourcegraph/cody-shared'
import type { OpenCtxProvider } from './types'

export async function createModelContextProvider(
modelContextProviderToolsURI: string
): Promise<OpenCtxProvider> {
export function createModelContextProvider(modelContextProviderToolsURI: string): OpenCtxProvider {
return {
providerUri: MODEL_CONTEXT_PROVIDER_URI,

Expand All @@ -19,6 +17,7 @@ export async function createModelContextProvider(
)
return {
name: client.name,
mentions: { label: client.name ?? 'Select a tool' },
}
},

Expand Down

0 comments on commit 313448c

Please sign in to comment.