Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/tools/toolHelpers.ts
13406 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { MarkdownString } from '../../../../../base/common/htmlContent.js';
7
import { escapeRegExpCharacters } from '../../../../../base/common/strings.js';
8
import { URI } from '../../../../../base/common/uri.js';
9
import { ITextModel } from '../../../../../editor/common/model.js';
10
import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js';
11
import { IToolResult } from '../../common/tools/languageModelToolsService.js';
12
import { createToolSimpleTextResult } from '../../common/tools/builtinTools/toolHelpers.js';
13
14
export interface ISymbolToolInput {
15
symbol: string;
16
uri?: string;
17
filePath?: string;
18
lineContent: string;
19
}
20
21
/**
22
* Resolves a URI from tool input. Accepts either a full URI string or a
23
* workspace-relative file path.
24
*/
25
export function resolveToolUri(input: ISymbolToolInput, workspaceContextService: IWorkspaceContextService): URI | undefined {
26
if (input.uri) {
27
return URI.parse(input.uri);
28
}
29
if (input.filePath) {
30
const folders = workspaceContextService.getWorkspace().folders;
31
if (folders.length === 1) {
32
return folders[0].toResource(input.filePath);
33
}
34
// try each folder, return the first
35
for (const folder of folders) {
36
return folder.toResource(input.filePath);
37
}
38
}
39
return undefined;
40
}
41
42
/**
43
* Finds the line number in the model that matches the given line content.
44
* Whitespace is normalized so that extra spaces in the input still match.
45
*
46
* @returns The 1-based line number, or `undefined` if not found.
47
*/
48
export function findLineNumber(model: ITextModel, lineContent: string): number | undefined {
49
const parts = lineContent.trim().split(/\s+/);
50
const pattern = parts.map(escapeRegExpCharacters).join('\\s+');
51
const matches = model.findMatches(pattern, false, true, false, null, false, 1);
52
if (matches.length === 0) {
53
return undefined;
54
}
55
return matches[0].range.startLineNumber;
56
}
57
58
/**
59
* Finds the 1-based column of a symbol within a line of text using word
60
* boundary matching.
61
*
62
* @returns The 1-based column, or `undefined` if not found.
63
*/
64
export function findSymbolColumn(lineText: string, symbol: string): number | undefined {
65
const pattern = new RegExp(`\\b${escapeRegExpCharacters(symbol)}\\b`);
66
const match = pattern.exec(lineText);
67
if (match) {
68
return match.index + 1; // 1-based column
69
}
70
return undefined;
71
}
72
73
/**
74
* Creates an error tool result with the given message as both the content
75
* and the tool result message.
76
*/
77
export function errorResult(message: string): IToolResult {
78
const result = createToolSimpleTextResult(message);
79
result.toolResultMessage = new MarkdownString(message);
80
return result;
81
}
82
83