Skip to content

Commit a311e99

Browse files
committed
feat(vscode): add language model tools for retrieving library documentation and environment details
1 parent 3cd2058 commit a311e99

File tree

9 files changed

+318
-3
lines changed

9 files changed

+318
-3
lines changed

eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default [
1919
"**/docs/",
2020
"**/packages/",
2121
"**/js",
22+
"**/build/",
2223
],
2324
},
2425
{ files: ["**/*.{ts,tsx}"] },

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,6 +1940,66 @@
19401940
}
19411941
]
19421942
}
1943+
],
1944+
"chatParticipants":[
1945+
1946+
],
1947+
"languageModelTools": [
1948+
{
1949+
"name": "robot-get_library_doc",
1950+
"displayName": "Get Library Documentation",
1951+
"toolReferenceName": "robotGetLibraryDoc",
1952+
"modelDescription": "Gets the library documentation for the given library name. This includes keywords, documentation, and other information about the library.",
1953+
"userDescription": "Gets documentation for the given library.",
1954+
"canBeReferencedInPrompt": true,
1955+
"tags": [
1956+
"robot",
1957+
"robotframework",
1958+
"robotframework-library",
1959+
"robotframework-keyword",
1960+
"robotcode"
1961+
],
1962+
"icon": "$(robotcode-robot)",
1963+
"inputSchema": {
1964+
"type": "object",
1965+
"required": [
1966+
"libraryName"
1967+
],
1968+
"properties": {
1969+
"libraryName": {
1970+
"type": "string",
1971+
"description": "The name of the library."
1972+
},
1973+
"resourcePath": {
1974+
"type": "string",
1975+
"description": "The path to the robot framework file or workspace to get the library information for."
1976+
}
1977+
}
1978+
}
1979+
},
1980+
{
1981+
"name": "robot-get_environment_details",
1982+
"displayName": "Get Robot Framework Environment Informations",
1983+
"toolReferenceName": "robotGetEnvironmentInfo",
1984+
"modelDescription": "This tool will retrieve the details of the Robot Framework Environment for the specified file or workspace. This includes informations about the python interpreter, like the version and the executable path, and the versions of robot framework, RobotCode, robocop and robotidy if installed.",
1985+
"userDescription": "Gets informations about the Robot Framework Environment.",
1986+
"canBeReferencedInPrompt": true,
1987+
"tags": [
1988+
"robot",
1989+
"robotframework",
1990+
"robotcode"
1991+
],
1992+
"icon": "$(robotcode-robot)",
1993+
"inputSchema": {
1994+
"type": "object",
1995+
"properties": {
1996+
"resourcePath": {
1997+
"type": "string",
1998+
"description": "The path to the robot framework file or workspace to get the details for."
1999+
}
2000+
}
2001+
}
2002+
}
19432003
]
19442004
},
19452005
"scripts": {
@@ -1961,7 +2021,8 @@
19612021
"dependencies": {
19622022
"ansi-colors": "^4.1.3",
19632023
"fs-extra": "^11.3.0",
1964-
"vscode-languageclient": "^9.0.1"
2024+
"vscode-languageclient": "^9.0.1",
2025+
"@vscode/prompt-tsx": "^0.4.0-alpha.4"
19652026
},
19662027
"devDependencies": {
19672028
"@eslint/compat": "^1.2.9",
@@ -1989,4 +2050,4 @@
19892050
"workspaces": [
19902051
"docs"
19912052
]
1992-
}
2053+
}

packages/language_server/src/robotcode/language_server/robotframework/parts/keywords_treeview.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import TYPE_CHECKING, Any, List, Optional
33

44
from robotcode.core.lsp.types import TextDocumentIdentifier
5+
from robotcode.core.uri import Uri
56
from robotcode.core.utils.dataclasses import CamelSnakeMixin
67
from robotcode.core.utils.logging import LoggingDescriptor
78
from robotcode.jsonrpc2.protocol import rpc_method
@@ -18,6 +19,12 @@ class GetDocumentImportsParams(CamelSnakeMixin):
1819
text_document: TextDocumentIdentifier
1920

2021

22+
@dataclass(repr=False)
23+
class GetLibraryDocumentationParams(CamelSnakeMixin):
24+
workspace_folder_uri: str
25+
library_name: str
26+
27+
2128
@dataclass(repr=False)
2229
class Keyword(CamelSnakeMixin):
2330
name: str
@@ -26,6 +33,14 @@ class Keyword(CamelSnakeMixin):
2633
documentation: Optional[str] = None
2734

2835

36+
@dataclass(repr=False)
37+
class LibraryDocumentation(CamelSnakeMixin):
38+
name: str
39+
documentation: Optional[str] = None
40+
keywords: Optional[List[Keyword]] = None
41+
initializers: Optional[List[Keyword]] = None
42+
43+
2944
@dataclass(repr=False)
3045
class DocumentImport(CamelSnakeMixin):
3146
name: str
@@ -165,3 +180,43 @@ def _get_documentation_url(
165180
)
166181

167182
return None
183+
184+
@rpc_method(
185+
name="robot/keywordsview/getLibraryDocumentation", param_type=GetLibraryDocumentationParams, threaded=True
186+
)
187+
@_logger.call
188+
def _get_library_documentation(
189+
self,
190+
workspace_folder_uri: str,
191+
library_name: str,
192+
*args: Any,
193+
**kwargs: Any,
194+
) -> Optional[LibraryDocumentation]:
195+
imports_manager = self.parent.documents_cache.get_imports_manager_for_uri(Uri(workspace_folder_uri))
196+
197+
libdoc = imports_manager.get_libdoc_for_library_import(library_name, (), ".")
198+
if libdoc.errors:
199+
raise ValueError(f"Errors while loading library documentation: {libdoc.errors}")
200+
201+
return LibraryDocumentation(
202+
name=libdoc.name,
203+
documentation=libdoc.to_markdown(),
204+
keywords=[
205+
Keyword(
206+
l.name,
207+
str(hash(l)),
208+
l.parameter_signature(),
209+
l.to_markdown(),
210+
)
211+
for l in libdoc.keywords.values()
212+
],
213+
initializers=[
214+
Keyword(
215+
s.name,
216+
str(hash(s)),
217+
s.parameter_signature(),
218+
s.to_markdown(),
219+
)
220+
for s in libdoc.inits.values()
221+
],
222+
)

packages/language_server/src/robotcode/language_server/robotframework/parts/project_info.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
from dataclasses import dataclass
23
from typing import TYPE_CHECKING, Any, Optional
34

@@ -7,6 +8,7 @@
78
from robotcode.core.utils.logging import LoggingDescriptor
89
from robotcode.jsonrpc2.protocol import rpc_method
910

11+
from ...__version__ import __version__ as robotcode_version
1012
from .protocol_part import RobotLanguageServerProtocolPart
1113
from .robocop_tidy_mixin import RoboCopTidyMixin
1214

@@ -19,6 +21,9 @@ class ProjectInfo(CamelSnakeMixin):
1921
robot_version_string: str
2022
robocop_version_string: Optional[str]
2123
tidy_version_string: Optional[str] = None
24+
python_version_string: Optional[str] = None
25+
python_executable: Optional[str] = None
26+
robot_code_version_string: Optional[str] = None
2227

2328

2429
class ProjectInfoPart(RobotLanguageServerProtocolPart, RoboCopTidyMixin):
@@ -46,4 +51,7 @@ def _robot_project_info(
4651
robot_version_string=get_version(),
4752
robocop_version_string=robocop_version_string,
4853
tidy_version_string=tidy_version_string,
54+
python_version_string=sys.version,
55+
python_executable=sys.executable,
56+
robot_code_version_string=robotcode_version,
4957
)

vscode-client/extension/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { KeywordsTreeViewProvider } from "./keywordsTreeViewProvider";
77
import { LanguageToolsManager } from "./languageToolsManager";
88
import { NotebookManager } from "./notebook";
99
import path from "path";
10+
import { GetEnvironmentDetails, GetLibDocTool } from "./lmTools";
1011

1112
class TerminalLink extends vscode.TerminalLink {
1213
constructor(
@@ -153,6 +154,11 @@ export async function activateAsync(context: vscode.ExtensionContext): Promise<v
153154
}, 1000);
154155
}
155156
}),
157+
vscode.lm.registerTool("robot-get_library_doc", new GetLibDocTool(context, languageClientManger, outputChannel)),
158+
vscode.lm.registerTool(
159+
"robot-get_environment_details",
160+
new GetEnvironmentDetails(context, languageClientManger, outputChannel),
161+
),
156162
);
157163

158164
const collection = context.environmentVariableCollection;

vscode-client/extension/languageclientsmanger.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ export interface Keyword {
4343
documentation?: string;
4444
}
4545

46+
export interface LibraryDocumentation {
47+
name: string;
48+
documentation?: string;
49+
keywords?: Keyword[];
50+
initializers?: DocumentImport[];
51+
}
52+
4653
export interface DocumentImport {
4754
name: string;
4855
alias?: string;
@@ -106,6 +113,9 @@ export interface ProjectInfo {
106113
robotVersionString?: string;
107114
robocopVersionString?: string;
108115
tidyVersionString?: string;
116+
pythonVersionString?: string;
117+
pythonExecutable?: string;
118+
robotCodeVersionString?: string;
109119
}
110120

111121
interface RobotCodeContributions {
@@ -900,6 +910,27 @@ export class LanguageClientsManager {
900910
);
901911
}
902912

913+
public async getLibraryDocumentation(
914+
workspace_folder: vscode.WorkspaceFolder,
915+
libraryName: string,
916+
token?: vscode.CancellationToken | undefined,
917+
): Promise<LibraryDocumentation | undefined> {
918+
const client = await this.getLanguageClientForResource(workspace_folder.uri);
919+
920+
if (!client) return undefined;
921+
922+
return (
923+
(await client.sendRequest<LibraryDocumentation>(
924+
"robot/keywordsview/getLibraryDocumentation",
925+
{
926+
workspaceFolderUri: workspace_folder.uri.toString(),
927+
libraryName: libraryName,
928+
},
929+
token ?? new vscode.CancellationTokenSource().token,
930+
)) ?? undefined
931+
);
932+
}
933+
903934
public async getDocumentKeywords(
904935
document: vscode.TextDocument,
905936
token?: vscode.CancellationToken | undefined,

0 commit comments

Comments
 (0)