Skip to content

Commit

Permalink
Add metadata to context items (#5153)
Browse files Browse the repository at this point in the history
Context items now include optional metadata about their source or
scoring, which can help developers understand why certain items are
appearing in the context. This change adds a `metadata` field to the
`ContextItemCommon` interface and populates it for context items from
Sourcegraph search, the local symbol index, and live search results.

You can view these by setting `"cody.internal.debug.context": true` in
settings. The `cody.internal.showContextAlternatives` has been removed
and replaced by this one.
  • Loading branch information
beyang authored Aug 9, 2024
1 parent 9eb02a5 commit 869de99
Show file tree
Hide file tree
Showing 15 changed files with 77 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ data class ContextItemFile(
val isTooLargeReason: String? = null,
val provider: String? = null,
val icon: String? = null,
val metadata: List<String>? = null,
val type: TypeEnum, // Oneof: file
val remoteRepositoryName: String? = null,
) : ContextItem() {
Expand All @@ -63,6 +64,7 @@ data class ContextItemRepository(
val isTooLargeReason: String? = null,
val provider: String? = null,
val icon: String? = null,
val metadata: List<String>? = null,
val type: TypeEnum, // Oneof: repository
val repoID: String,
) : ContextItem() {
Expand All @@ -87,6 +89,7 @@ data class ContextItemTree(
val isTooLargeReason: String? = null,
val provider: String? = null,
val icon: String? = null,
val metadata: List<String>? = null,
val type: TypeEnum, // Oneof: tree
val isWorkspaceRoot: Boolean,
val name: String,
Expand All @@ -112,6 +115,7 @@ data class ContextItemSymbol(
val isTooLargeReason: String? = null,
val provider: String? = null,
val icon: String? = null,
val metadata: List<String>? = null,
val type: TypeEnum, // Oneof: symbol
val symbolName: String,
val kind: SymbolKind, // Oneof: class, function, method
Expand All @@ -138,6 +142,7 @@ data class ContextItemOpenCtx(
val isTooLargeReason: String? = null,
val provider: String? = null,
val icon: String? = null,
val metadata: List<String>? = null,
val type: TypeEnum, // Oneof: openctx
val providerUri: String,
val mention: MentionParams? = null,
Expand Down
6 changes: 6 additions & 0 deletions lib/shared/src/codebase-context/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ interface ContextItemCommon {
* Lucid icon name for the context item
*/
icon?: string

/**
* Optional metadata about where this context item came from or how it was scored, which
* can help a user or dev working on Cody understand why this item is appearing in context.
*/
metadata?: string[]
}

/**
Expand Down
1 change: 1 addition & 0 deletions lib/shared/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export interface Configuration {
* Unstable Features for internal testing only
*/
internalUnstable: boolean
internalDebugContext?: boolean

/**
* Experimental autocomplete
Expand Down
2 changes: 2 additions & 0 deletions lib/shared/src/local-context/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ export interface Result {
file: URI
range: Range
summary: string
blugeScore: number
heuristicBoostID?: string
}
6 changes: 0 additions & 6 deletions vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1267,12 +1267,6 @@
"type": "boolean",
"markdownDescription": "[INTERNAL ONLY] Enable all unstable experimental features.",
"default": false
},
"cody.internal.showContextAlternatives": {
"order": 999,
"type": "boolean",
"markdownDescription": "[INTERNAL ONLY] Show alternative context lists in chat",
"default": false
}
}
},
Expand Down
15 changes: 4 additions & 11 deletions vscode/src/chat/chat-view/ChatController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ export class ChatController implements vscode.Disposable, vscode.WebviewViewProv
experimentalNoodle: config.experimentalNoodle,
experimentalSmartApply,
webviewType,
internalDebugContext: config.internalDebugContext,
}
}

Expand Down Expand Up @@ -1259,18 +1260,10 @@ export class ChatController implements vscode.Disposable, vscode.WebviewViewProv
)
abortSignal.throwIfAborted()

// Update UI based on prompt construction
// Includes the excluded context items to display in the UI
if (vscode.workspace.getConfiguration().get<boolean>('cody.internal.showContextAlternatives')) {
this.chatModel.setLastMessageContext(
[...context.used, ...context.ignored],
contextAlternatives
)
} else {
this.chatModel.setLastMessageContext([...context.used, ...context.ignored])
}
// Update UI based on prompt construction. Includes the excluded context items to display in the UI
this.chatModel.setLastMessageContext([...context.used, ...context.ignored], contextAlternatives)

// this is not awaited, so we kick the call off but don't block on it returning
// This is not awaited, so we kick the call off but don't block on it returning
this.contextAPIClient?.recordContext(requestID, context.used, context.ignored)

if (sendTelemetry) {
Expand Down
7 changes: 6 additions & 1 deletion vscode/src/chat/chat-view/ContextRetriever.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ export class ContextRetriever implements vscode.Disposable {
range,
source: ContextItemSource.Search,
content: text,
metadata: ['source:symf-live'],
}
})
)
Expand Down Expand Up @@ -313,7 +314,11 @@ export class ContextRetriever implements vscode.Disposable {
if (isError(remoteResult)) {
throw remoteResult
}
return remoteResult?.flatMap(r => contextSearchResultToContextItem(r) ?? []) ?? []
const finalResults = remoteResult?.flatMap(r => contextSearchResultToContextItem(r) ?? []) ?? []
for (const r of finalResults) {
r.metadata = (r.metadata ?? []).concat(['source:sourcegraph'])
}
return finalResults
}

private async retrieveIndexedContextLocally(
Expand Down
9 changes: 9 additions & 0 deletions vscode/src/chat/chat-view/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,21 @@ export async function searchSymf(
logError('ChatController.searchSymf', `Error getting file contents: ${error}`)
return []
}

const metadata: string[] = [
'source:symf-index',
'score:' + result.blugeScore.toFixed(0),
]
if (result.heuristicBoostID) {
metadata.push('boost:' + result.heuristicBoostID)
}
return {
type: 'file',
uri: result.file,
range,
source: ContextItemSource.Search,
content: text,
metadata,
}
}
)
Expand Down
6 changes: 5 additions & 1 deletion vscode/src/chat/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,11 @@ export interface ExtensionTranscriptMessage {
export interface ConfigurationSubsetForWebview
extends Pick<
ConfigurationWithAccessToken,
'experimentalNoodle' | 'serverEndpoint' | 'agentIDE' | 'agentExtensionVersion'
| 'experimentalNoodle'
| 'serverEndpoint'
| 'agentIDE'
| 'agentExtensionVersion'
| 'internalDebugContext'
> {
experimentalSmartApply: boolean
webviewType?: WebviewType | undefined | null
Expand Down
3 changes: 3 additions & 0 deletions vscode/src/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ describe('getConfiguration', () => {
return undefined
case 'cody.internal.unstable':
return false
case 'cody.internal.debug.context':
return false
case 'cody.experimental.supercompletions':
return false
case 'cody.experimental.noodle':
Expand Down Expand Up @@ -134,6 +136,7 @@ describe('getConfiguration', () => {
isRunningInsideAgent: false,
agentIDE: undefined,
internalUnstable: false,
internalDebugContext: false,
debugVerbose: true,
debugFilter: /.*/,
telemetryLevel: 'off',
Expand Down
1 change: 1 addition & 0 deletions vscode/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export function getConfiguration(
*/

internalUnstable: getHiddenSetting('internal.unstable', isTesting),
internalDebugContext: getHiddenSetting('internal.debug.context', false),

autocompleteExperimentalGraphContext,
experimentalCommitMessage: getHiddenSetting('experimental.commitMessage', true),
Expand Down
16 changes: 15 additions & 1 deletion vscode/src/local-context/symf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,19 @@ function parseSymfStdout(stdout: string): Result[] {
}
const results = JSON.parse(stdout) as RawSymfResult[]
return results.map(result => {
const { fqname, name, type, doc, exported, lang, file: fsPath, range, summary } = result
const {
fqname,
name,
type,
doc,
exported,
lang,
file: fsPath,
range,
summary,
blugeScore,
heuristicBoostID,
} = result

const { row: startRow, col: startColumn } = range.startPoint
const { row: endRow, col: endColumn } = range.endPoint
Expand Down Expand Up @@ -626,6 +638,8 @@ function parseSymfStdout(stdout: string): Result[] {
col: endColumn,
},
},
blugeScore,
heuristicBoostID,
} satisfies Result
})
}
Expand Down
1 change: 1 addition & 0 deletions vscode/src/testutils/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ export const DEFAULT_VSCODE_SETTINGS = {
debugFilter: null,
telemetryLevel: 'all',
internalUnstable: false,
internalDebugContext: false,
autocompleteAdvancedProvider: null,
autocompleteAdvancedModel: null,
autocompleteCompleteSuggestWidgetSelection: true,
Expand Down
6 changes: 6 additions & 0 deletions vscode/webviews/chat/cells/contextCell/ContextCell.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
padding: 2px 4px 2px 2px;
}

.context-item-metadata {
color: var(--vscode-disabledForeground);
padding-left: 0.1rem;
text-wrap: nowrap;
}

.context-item-link {
background: none;
border: none;
Expand Down
14 changes: 13 additions & 1 deletion vscode/webviews/chat/cells/contextCell/ContextCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { Tooltip, TooltipContent, TooltipTrigger } from '../../../components/shadcn/ui/tooltip'
import { SourcegraphLogo } from '../../../icons/SourcegraphLogo'
import { getVSCodeAPI } from '../../../utils/VSCodeApi'
import { useConfig } from '../../../utils/useConfig'
import { LoadingDots } from '../../components/LoadingDots'
import { Cell } from '../Cell'
import { NON_HUMAN_CELL_AVATAR_SIZE } from '../messageCell/assistant/AssistantMessageCell'
Expand Down Expand Up @@ -98,6 +99,10 @@ export const ContextCell: FunctionComponent<{
})
}

const {
config: { internalDebugContext },
} = useConfig()

return contextItemsToDisplay === undefined || contextItemsToDisplay.length !== 0 ? (
<Cell
style="context"
Expand Down Expand Up @@ -134,7 +139,7 @@ export const ContextCell: FunctionComponent<{
</span>
</AccordionTrigger>
<AccordionContent>
{contextAlternatives && (
{internalDebugContext && contextAlternatives && (
<div>
<button onClick={prevSelectedAlternative} type="button">
&larr;
Expand Down Expand Up @@ -170,6 +175,13 @@ export const ContextCell: FunctionComponent<{
className={clsx(styles.contextItem, MENTION_CLASS_NAME)}
linkClassName={styles.contextItemLink}
/>
{internalDebugContext &&
item.metadata &&
item.metadata.length > 0 && (
<span className={styles.contextItemMetadata}>
{item.metadata.join(', ')}
</span>
)}
</li>
))}
{!isForFirstMessage && (
Expand Down

0 comments on commit 869de99

Please sign in to comment.