From 01d89d2278e9676e5d021c54177ee26c3616f420 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Mon, 12 Aug 2024 19:45:13 -0700 Subject: [PATCH] connection tree view (#616) * show connection tree * ui to analyze connections * fix token counting in vscode llms * tweak pr descr --- packages/cli/src/nodehost.ts | 1 + packages/core/src/connection.ts | 6 +- packages/sample/genaisrc/pr-review.genai.js | 1 + packages/vscode/package.json | 10 +++ packages/vscode/src/connectioninfotree.ts | 86 +++++++++++++++++++++ packages/vscode/src/extension.ts | 14 ++++ packages/vscode/src/lmaccess.ts | 11 ++- 7 files changed, 120 insertions(+), 9 deletions(-) create mode 100644 packages/vscode/src/connectioninfotree.ts diff --git a/packages/cli/src/nodehost.ts b/packages/cli/src/nodehost.ts index 563c1f7aac..f31a36e86e 100644 --- a/packages/cli/src/nodehost.ts +++ b/packages/cli/src/nodehost.ts @@ -152,6 +152,7 @@ export class NodeHost implements RuntimeHost { const { signal, token: askToken } = options || {} await this.parseDefaults() const tok = await parseTokenFromEnv(process.env, modelId) + if (!askToken && tok?.token) tok.token = "***" if ( askToken && tok && diff --git a/packages/core/src/connection.ts b/packages/core/src/connection.ts index 95a343778f..ad59bb6884 100644 --- a/packages/core/src/connection.ts +++ b/packages/core/src/connection.ts @@ -331,9 +331,9 @@ OPENAI_API_TYPE="localai" if (provider === MODEL_PROVIDER_GITHUB) return { config: ` - ## GitHub Models ${DOCS_CONFIGURATION_GITHUB_URL} - # use "${MODEL_PROVIDER_GITHUB}:" in script({ model: ... }) - # GITHUB_MODELS_TOKEN="${PLACEHOLDER_API_KEY}" # use a personal access token if not available +## GitHub Models ${DOCS_CONFIGURATION_GITHUB_URL} +# use "${MODEL_PROVIDER_GITHUB}:" in script({ model: ... }) +# GITHUB_MODELS_TOKEN="${PLACEHOLDER_API_KEY}" # use a personal access token if not available `, model: `${MODEL_PROVIDER_GITHUB}:gpt-4o`, } diff --git a/packages/sample/genaisrc/pr-review.genai.js b/packages/sample/genaisrc/pr-review.genai.js index 6d6239fe02..88a9080f0a 100644 --- a/packages/sample/genaisrc/pr-review.genai.js +++ b/packages/sample/genaisrc/pr-review.genai.js @@ -41,4 +41,5 @@ If the changes look good, respond "LGTM :rocket:". If you have any concerns, pro - only report functional issues - Use emojis - If available, suggest code fixes and improvements using a diff format. +- do not report about individual lines of code, summarize changes ` diff --git a/packages/vscode/package.json b/packages/vscode/package.json index 21175ace1b..4619daa9e3 100644 --- a/packages/vscode/package.json +++ b/packages/vscode/package.json @@ -122,6 +122,11 @@ "id": "genaiscript.trace", "name": "Trace" }, + { + "id": "genaiscript.connections", + "name": "Connections", + "visibility": "collapsed" + }, { "id": "genaiscript.prompts", "name": "Scripts", @@ -345,6 +350,11 @@ "command": "genaiscript.info.env", "title": "Configuration information...", "category": "GenAIScript" + }, + { + "command": "genaiscript.connection.configure", + "title": "Configure connection...", + "category": "GenAIScript" } ] }, diff --git a/packages/vscode/src/connectioninfotree.ts b/packages/vscode/src/connectioninfotree.ts new file mode 100644 index 0000000000..7b21308489 --- /dev/null +++ b/packages/vscode/src/connectioninfotree.ts @@ -0,0 +1,86 @@ +import * as vscode from "vscode" +import { ExtensionState } from "./state" +import { MODEL_PROVIDERS } from "../../core/src/constants" +import { YAMLStringify } from "../../core/src/yaml" +import { APIType } from "../../core/src/host" + +class ConnectionInfoTreeData { + provider: string + apiType?: APIType +} + +class ConnectionInfoTreeDataProvider + implements vscode.TreeDataProvider +{ + constructor(readonly state: ExtensionState) { + const { context } = state + const { subscriptions } = context + subscriptions.push( + vscode.workspace.onDidChangeConfiguration(() => { + this.refresh() + }) + ) + const watcher = vscode.workspace.createFileSystemWatcher("./.env") + watcher.onDidChange(() => this.refresh()) + watcher.onDidDelete(() => this.refresh()) + subscriptions.push(watcher) + } + + async getTreeItem( + element: ConnectionInfoTreeData + ): Promise { + const item = new vscode.TreeItem(element.provider) + const res = + await this.state.host.server.client.getLanguageModelConfiguration( + element.provider + ":*", + { token: false } + ) + if (res) { + item.description = res.base || "?" + item.tooltip = YAMLStringify(res) + item.command = { + command: "vscode.open", + arguments: [this.state.host.toUri("./.env")], + } + } else { + item.description = "not configured" + item.command = { + command: "genaiscript.connection.configure", + arguments: [element.provider, element.apiType], + } + } + + return item + } + getChildren( + element?: ConnectionInfoTreeData + ): vscode.ProviderResult { + if (!element) return MODEL_PROVIDERS.map(({ id }) => ({ provider: id })) + return undefined + } + + private _onDidChangeTreeData: vscode.EventEmitter< + void | ConnectionInfoTreeData | ConnectionInfoTreeData[] + > = new vscode.EventEmitter< + void | ConnectionInfoTreeData | ConnectionInfoTreeData[] + >() + readonly onDidChangeTreeData: vscode.Event< + void | ConnectionInfoTreeData | ConnectionInfoTreeData[] + > = this._onDidChangeTreeData.event + + refresh( + treeItem?: ConnectionInfoTreeData | ConnectionInfoTreeData[] + ): void { + this._onDidChangeTreeData.fire(treeItem) + } +} + +export function activateConnectionInfoTree(state: ExtensionState) { + const { context } = state + const { subscriptions } = context + const treeDataProvider = new ConnectionInfoTreeDataProvider(state) + const treeView = vscode.window.createTreeView("genaiscript.connections", { + treeDataProvider, + }) + subscriptions.push(treeView) +} diff --git a/packages/vscode/src/extension.ts b/packages/vscode/src/extension.ts index b08a7ea421..861e07356d 100644 --- a/packages/vscode/src/extension.ts +++ b/packages/vscode/src/extension.ts @@ -15,6 +15,9 @@ import { registerCommand } from "./commands" import { EXTENSION_ID, TOOL_NAME } from "../../core/src/constants" import type MarkdownIt from "markdown-it" import MarkdownItGitHubAlerts from "markdown-it-github-alerts" +import { activateConnectionInfoTree } from "./connectioninfotree" +import { updateConnectionConfiguration } from "../../core/src/connection" +import { APIType } from "../../core/src/host" export async function activate(context: ExtensionContext) { const state = new ExtensionState(context) @@ -22,6 +25,7 @@ export async function activate(context: ExtensionContext) { activateFragmentCommands(state) activateMarkdownTextDocumentContentProvider(state) activatePrompTreeDataProvider(state) + activateConnectionInfoTree(state) activateAIRequestTreeDataProvider(state) activateLLMRequestTreeDataProvider(state) activateTraceTreeDataProvider(state) @@ -29,6 +33,16 @@ export async function activate(context: ExtensionContext) { activateDocsNotebook(state) context.subscriptions.push( + registerCommand( + "genaiscript.connection.configure", + async (provider?: string, apiType?: APIType) => { + await updateConnectionConfiguration(provider, apiType) + const doc = await vscode.workspace.openTextDocument( + state.host.toUri("./.env") + ) + await vscode.window.showTextDocument(doc) + } + ), registerCommand("genaiscript.request.abort", async () => { await state.cancelAiRequest() await vscode.window.showInformationMessage( diff --git a/packages/vscode/src/lmaccess.ts b/packages/vscode/src/lmaccess.ts index 39b3637b1c..b2f26c8bc1 100644 --- a/packages/vscode/src/lmaccess.ts +++ b/packages/vscode/src/lmaccess.ts @@ -13,7 +13,6 @@ import { } from "../../core/src/constants" import { APIType } from "../../core/src/host" import { parseModelIdentifier } from "../../core/src/models" -import { updateConnectionConfiguration } from "../../core/src/connection" import { ChatCompletionMessageParam } from "../../core/src/chattypes" import { LanguageModelChatRequest } from "../../core/src/server/client" import { ChatStart } from "../../core/src/server/messages" @@ -143,11 +142,11 @@ export async function pickLanguageModel( if (res.model) return res.model else { - await updateConnectionConfiguration(res.provider, res.apiType) - const doc = await vscode.workspace.openTextDocument( - state.host.toUri("./.env") + await vscode.commands.executeCommand( + "genaiscript.connection.configure", + res.provider, + res.apiType ) - await vscode.window.showTextDocument(doc) return undefined } } @@ -226,7 +225,7 @@ export function createChatModelRunner( text += fragment onChunk({ chunk: fragment, - tokens: await chatModel.countTokens(text), + tokens: await chatModel.countTokens(fragment), finishReason: undefined, model: chatModel.id, })