From c59328479a60847147d7141f0053fb208821d49a Mon Sep 17 00:00:00 2001 From: aaronvg Date: Tue, 26 Nov 2024 13:52:03 -0800 Subject: [PATCH] Add vscode config to disable proxying (#1197) > [!IMPORTANT] > Add `enablePlaygroundProxy` setting to BAML VSCode extension to optionally disable proxying, with updates to configuration, RPC, and logic handling. > > - **Behavior**: > - Adds `enablePlaygroundProxy` setting to `bamlConfigSchema` in `bamlConfig.ts` and `package.json`. > - Updates `WebPanelView.ts` to handle `GET_VSCODE_SETTINGS` command, returning `enablePlaygroundProxy` status. > - Modifies `EventListener.tsx` to filter out `BOUNDARY_PROXY_URL` from environment variables if proxying is disabled. > - **RPC and API**: > - Adds `GetVSCodeSettingsRequest` and `GetVSCodeSettingsResponse` to `rpc.ts`. > - Implements `getIsProxyEnabled()` in `vscode.ts` to fetch proxy setting. > - **Testing and Hooks**: > - Updates `useRunHooks` in `testHooks.ts` to check `enablePlaygroundProxy` status. > - **Misc**: > - Minor logging changes in `vscode.ts` and `testHooks.ts`. > > This description was created by [Ellipsis](https://www.ellipsis.dev?ref=BoundaryML%2Fbaml&utm_source=github&utm_medium=referral) for 440a5dac70846859e15bf09567ba93a76053f58c. It will automatically update as commits are pushed. --- .../src/baml_wasm_web/EventListener.tsx | 23 +++++++++++++++++++ .../src/baml_wasm_web/rpc.ts | 9 ++++++++ .../src/baml_wasm_web/test_uis/testHooks.ts | 13 +++++++++-- .../playground-common/src/utils/vscode.ts | 16 ++++++++++++- .../language-server/src/bamlConfig.ts | 1 + typescript/vscode-ext/packages/package.json | 5 ++++ .../vscode/src/panels/WebPanelView.ts | 14 ++++++++++- .../src/plugins/language-server/index.ts | 6 ++--- 8 files changed, 80 insertions(+), 7 deletions(-) diff --git a/typescript/playground-common/src/baml_wasm_web/EventListener.tsx b/typescript/playground-common/src/baml_wasm_web/EventListener.tsx index fb40f1c60..1282f9453 100644 --- a/typescript/playground-common/src/baml_wasm_web/EventListener.tsx +++ b/typescript/playground-common/src/baml_wasm_web/EventListener.tsx @@ -32,6 +32,22 @@ const wasmAtomAsync = atom(async () => { return wasm }) +const vscodeSettingsAtom = unwrap( + atom(async () => { + try { + const res = await vscode.getIsProxyEnabled() + return { + enablePlaygroundProxy: res, + } + } catch (e) { + console.error(`Error occurred while getting vscode settings:\n${e}`) + return { + enablePlaygroundProxy: false, + } + } + }), +) + export const wasmAtom = unwrap(wasmAtomAsync) const defaultEnvKeyValues: [string, string][] = (() => { @@ -119,6 +135,13 @@ type Selection = { } export const envVarsAtom = atom((get) => { + const vscodeSettings = get(vscodeSettingsAtom) + if (vscodeSettings?.enablePlaygroundProxy !== undefined && !vscodeSettings?.enablePlaygroundProxy) { + // filter it out + const envKeyValues = get(envKeyValuesAtom) + return Object.fromEntries(envKeyValues.map(([k, v]) => [k, v]).filter(([k]) => k !== 'BOUNDARY_PROXY_URL')) + } + const envKeyValues = get(envKeyValuesAtom) return Object.fromEntries(envKeyValues.map(([k, v]) => [k, v])) }) diff --git a/typescript/playground-common/src/baml_wasm_web/rpc.ts b/typescript/playground-common/src/baml_wasm_web/rpc.ts index 86e13c097..35f311b60 100644 --- a/typescript/playground-common/src/baml_wasm_web/rpc.ts +++ b/typescript/playground-common/src/baml_wasm_web/rpc.ts @@ -94,11 +94,20 @@ export interface GetWebviewUriResponse { readError?: string } +export interface GetVSCodeSettingsRequest { + vscodeCommand: 'GET_VSCODE_SETTINGS' +} + +export interface GetVSCodeSettingsResponse { + enablePlaygroundProxy: boolean +} + type ApiPairs = [ // Echo is included here as an example of what a request/response pair looks like [EchoRequest, EchoResponse], [GetBamlSrcRequest, GetBamlSrcResponse], [GetWebviewUriRequest, GetWebviewUriResponse], + [GetVSCodeSettingsRequest, GetVSCodeSettingsResponse], ] // Serialization for binary data (like images) diff --git a/typescript/playground-common/src/baml_wasm_web/test_uis/testHooks.ts b/typescript/playground-common/src/baml_wasm_web/test_uis/testHooks.ts index a294054e6..a534e7888 100644 --- a/typescript/playground-common/src/baml_wasm_web/test_uis/testHooks.ts +++ b/typescript/playground-common/src/baml_wasm_web/test_uis/testHooks.ts @@ -1,6 +1,6 @@ import { atom, useAtomValue } from 'jotai' import { atomFamily, useAtomCallback } from 'jotai/utils' -import React, { useCallback } from 'react' +import React, { useCallback, useEffect, useState } from 'react' import { selectedFunctionAtom, selectedRuntimeAtom } from '../EventListener' import type { WasmFunctionResponse, WasmTestResponse } from '@gloo-ai/baml-schema-wasm-web/baml_schema_build' import { vscode } from '../../utils/vscode' @@ -86,6 +86,15 @@ function updateTestSuiteState(old_result: TestSuiteSummary, new_result: TestSuit export const useRunHooks = () => { const isRunning = useAtomValue(isRunningAtom) + const [enableProxy, setEnableProxy] = useState() + useEffect(() => { + ;(async () => { + const res = await vscode.getIsProxyEnabled() + console.log('enableproxy call') + setEnableProxy(res) + })() + }, []) + const runTest = useAtomCallback( useCallback( async (get, set, testNames: string[]) => { @@ -241,7 +250,7 @@ export const useRunHooks = () => { set(isRunningAtom, false) }, - [isRunningAtom, selectedRuntimeAtom, selectedFunctionAtom], + [isRunningAtom, selectedRuntimeAtom, selectedFunctionAtom, enableProxy], ), ) diff --git a/typescript/playground-common/src/utils/vscode.ts b/typescript/playground-common/src/utils/vscode.ts index d67b95143..3fe268b13 100644 --- a/typescript/playground-common/src/utils/vscode.ts +++ b/typescript/playground-common/src/utils/vscode.ts @@ -1,4 +1,10 @@ -import { decodeBuffer, GetWebviewUriRequest, GetWebviewUriResponse } from '../baml_wasm_web/rpc' +import { + decodeBuffer, + GetVSCodeSettingsRequest, + GetVSCodeSettingsResponse, + GetWebviewUriRequest, + GetWebviewUriResponse, +} from '../baml_wasm_web/rpc' import type { WebviewApi } from 'vscode-webview' const RPC_TIMEOUT_MS = 5000 @@ -83,6 +89,14 @@ class VSCodeAPIWrapper { return resp.uri } + public async getIsProxyEnabled() { + const resp = await this.rpc({ + vscodeCommand: 'GET_VSCODE_SETTINGS', + }) + console.log('vscode settings', resp) + return resp.enablePlaygroundProxy ?? true + } + public rpc(data: TRequest): Promise { return new Promise((resolve, reject) => { const rpcId = this.rpcId++ diff --git a/typescript/vscode-ext/packages/language-server/src/bamlConfig.ts b/typescript/vscode-ext/packages/language-server/src/bamlConfig.ts index 82127298c..041c70e6f 100644 --- a/typescript/vscode-ext/packages/language-server/src/bamlConfig.ts +++ b/typescript/vscode-ext/packages/language-server/src/bamlConfig.ts @@ -4,6 +4,7 @@ export const bamlConfigSchema = z cliPath: z.optional(z.string().nullable()).default(null), generateCodeOnSave: z.enum(['never', 'always']).default('always'), restartTSServerOnSave: z.boolean().default(false), + enablePlaygroundProxy: z.boolean().default(true), envCommand: z.string().default('env'), fileWatcher: z.boolean().default(false), trace: z.object({ diff --git a/typescript/vscode-ext/packages/package.json b/typescript/vscode-ext/packages/package.json index 86a6ea352..58a39c12d 100644 --- a/typescript/vscode-ext/packages/package.json +++ b/typescript/vscode-ext/packages/package.json @@ -52,6 +52,11 @@ "default": false, "description": "Restart the TypeScript server when generating baml_client code, in case it's not reading the new generated types." }, + "baml.enablePlaygroundProxy": { + "type": "boolean", + "default": true, + "description": "BAML Extension starts a localhost proxy for the playground to send requests to fix any CORS issues with some LLM providers. Disable this if you're having issues communicating with any APIs via the playground" + }, "baml.fileWatcher": { "scope": "window", "type": "boolean", diff --git a/typescript/vscode-ext/packages/vscode/src/panels/WebPanelView.ts b/typescript/vscode-ext/packages/vscode/src/panels/WebPanelView.ts index 49710045d..9efa04afb 100644 --- a/typescript/vscode-ext/packages/vscode/src/panels/WebPanelView.ts +++ b/typescript/vscode-ext/packages/vscode/src/panels/WebPanelView.ts @@ -3,7 +3,14 @@ import { type Disposable, Uri, ViewColumn, type Webview, type WebviewPanel, wind import * as vscode from 'vscode' import { getNonce } from '../utils/getNonce' import { getUri } from '../utils/getUri' -import { EchoResponse, GetBamlSrcResponse, GetWebviewUriResponse, WebviewToVscodeRpc, encodeBuffer } from '../rpc' +import { + EchoResponse, + GetBamlSrcResponse, + GetVSCodeSettingsResponse, + GetWebviewUriResponse, + WebviewToVscodeRpc, + encodeBuffer, +} from '../rpc' import { type Config, adjectives, animals, colors, uniqueNamesGenerator } from 'unique-names-generator' import { URI } from 'vscode-uri' @@ -309,6 +316,11 @@ export class WebPanelView { } this._panel.webview.postMessage({ rpcId: message.rpcId, rpcMethod: vscodeCommand, data: webviewUriResp }) return + case 'GET_VSCODE_SETTINGS': + const responseData: GetVSCodeSettingsResponse = { + enablePlaygroundProxy: bamlConfig.config?.enablePlaygroundProxy ?? true, + } + this._panel.webview.postMessage({ rpcId: message.rpcId, rpcMethod: vscodeCommand, data: responseData }) } }, undefined, diff --git a/typescript/vscode-ext/packages/vscode/src/plugins/language-server/index.ts b/typescript/vscode-ext/packages/vscode/src/plugins/language-server/index.ts index a6036c094..7a89a459f 100644 --- a/typescript/vscode-ext/packages/vscode/src/plugins/language-server/index.ts +++ b/typescript/vscode-ext/packages/vscode/src/plugins/language-server/index.ts @@ -21,6 +21,7 @@ const packageJson = require('../../../../package.json') // eslint-disable-line const BamlConfig = z.optional( z.object({ path: z.string().optional(), + enablePlaygroundProxy: z.boolean().default(true), trace: z.optional( z.object({ server: z.string(), @@ -29,7 +30,6 @@ const BamlConfig = z.optional( }), ) type BamlConfig = z.infer -let config: BamlConfig | null = null let client: LanguageClient let serverModule: string let telemetry: TelemetryReporter @@ -130,9 +130,9 @@ const sleep = (time: number) => { const getConfig = async () => { try { console.log('getting config') - const configResponse = await workspace.getConfiguration('baml') + const configResponse = workspace.getConfiguration('baml') console.log('configResponse ' + JSON.stringify(configResponse, null, 2)) - config = BamlConfig.parse(configResponse) + bamlConfig.config = BamlConfig.parse(configResponse) } catch (e: any) { if (e instanceof Error) { console.log('Error getting config' + e.message + ' ' + e.stack)