diff --git a/.vscode/launch.json b/.vscode/launch.json index 670d6e66c..39b5eb0b3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,8 @@ "type": "extensionHost", "request": "launch", "args": [ - "--extensionDevelopmentPath=${workspaceFolder}" + "--extensionDevelopmentPath=${workspaceFolder}", + "--allow-insecure-localhost" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" diff --git a/package.json b/package.json index 3cbd2ef28..3ac48effb 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "url": "https://github.com/smallcloudai/refact-vscode/issues", "email": "support@smallcloud.tech" }, - "version": "6.5.0", + "version": "6.5.22", "dependencies": { "@types/marked": "^4.0.8", "@types/vscode": "^1.69.0", @@ -229,7 +229,10 @@ "order": 14 }, "refactai.activeGroup": { - "type": ["object", "null"], + "type": [ + "object", + "null" + ], "default": null, "description": "Active selected group in your Team Workspace. Modify via settings.json in your workspace", "scope": "machine-overridable", diff --git a/src/codeLens.ts b/src/codeLens.ts index e9725597c..2d3492003 100644 --- a/src/codeLens.ts +++ b/src/codeLens.ts @@ -5,9 +5,7 @@ import * as estate from "./estate"; import * as fetchH2 from 'fetch-h2'; import * as fetchAPI from "./fetchAPI"; import { - type ChatMessages, type ChatMessage, - type ToolUse, setInputValue, isUserMessage, UserMessage, @@ -169,10 +167,10 @@ const createMessageBlock = ( cursor: number | null, text: string ) => { - if (typeof message.content === 'string') { - return replaceVariablesInText(message.content, relative_path, cursor, text); + if (typeof message.ftm_content === 'string') { + return replaceVariablesInText(message.ftm_content, relative_path, cursor, text); } else { - return message.content.map(content => { + return message.ftm_content.map(content => { if (('type' in content) && content.type === 'text') { return replaceVariablesInText(content.text, relative_path, cursor, text); } @@ -185,13 +183,13 @@ const formatMultipleMessagesForCodeLens = ( relative_path: string, cursor: number | null, text: string -) => { +): ChatMessage[] => { return messages.map(message => { if (isUserMessage(message)) { - if (typeof message.content === 'string') { + if (typeof message.ftm_content === 'string') { return { ...message, - content: replaceVariablesInText(message.content, relative_path, cursor, text) + ftm_content: replaceVariablesInText(message.ftm_content, relative_path, cursor, text) }; } } @@ -206,7 +204,12 @@ export async function code_lens_execute(code_lens: string, range: any) { if (custom_code_lens) { const auto_submit = custom_code_lens[code_lens]["auto_submit"]; const new_tab = custom_code_lens[code_lens]["new_tab"]; - let messages: ChatMessage[] = custom_code_lens[code_lens]["messages"]; + let messages: ChatMessage[] = custom_code_lens[code_lens]["messages"].map((message: {role: string, content: unknown}) => { + return { + ftm_role: message.role, + ftm_content: message.content, + }; + }); const start_of_line = new vscode.Position(range.start.line, 0); const end_of_line = new vscode.Position(range.end.line + 1, 0); diff --git a/src/fetchAPI.ts b/src/fetchAPI.ts index fbfe2c5d8..4fd32c413 100644 --- a/src/fetchAPI.ts +++ b/src/fetchAPI.ts @@ -5,8 +5,6 @@ import * as usabilityHints from "./usabilityHints"; import * as estate from "./estate"; import * as statusBar from "./statusBar"; import { - type CapsResponse, - type CustomPromptsResponse, ChatMessages, } from "refact-chat-js/dist/events"; @@ -458,28 +456,40 @@ export function look_for_common_errors(json: any, scope: string, url: string): b return false; } -export async function get_caps(): Promise { - let url = rust_url("/v1/caps"); - if (!url) { - return Promise.reject("read_caps no rust binary working, very strange"); - } - - let req = new fetchH2.Request(url, { - method: "GET", - redirect: "follow", - cache: "no-cache", - referrer: "no-referrer", - }); - - let resp = await fetchH2.fetch(req); - if (resp.status !== 200) { - console.log(["read_caps http status", resp.status]); - return Promise.reject("read_caps bad status"); - } - let json = await resp.json(); - console.log(["successful read_caps", json]); - return json as CapsResponse; -} +// TODO: this has moved (also not used) +// export async function get_caps(): Promise { +// let url = rust_url("/v1/caps"); +// if (!url) { +// return Promise.reject("read_caps no rust binary working, very strange"); +// } + +// let req = new fetchH2.Request(url, { +// method: "GET", +// redirect: "follow", +// cache: "no-cache", +// referrer: "no-referrer", +// }); + +// let resp = await fetchH2.fetch(req); +// if (resp.status !== 200) { +// console.log(["read_caps http status", resp.status]); +// return Promise.reject("read_caps bad status"); +// } +// let json = await resp.json(); +// console.log(["successful read_caps", json]); +// return json as CapsResponse; +// } + +type SystemPrompt = { + text: string; + description: string; +}; + +type SystemPrompts = Record; +type CustomPromptsResponse = { + system_prompts: SystemPrompts; + toolbox_commands: Record; +}; export async function get_prompt_customization(): Promise { const url = rust_url("/v1/customization"); diff --git a/src/launchRust.ts b/src/launchRust.ts index 5c02152ed..498186217 100644 --- a/src/launchRust.ts +++ b/src/launchRust.ts @@ -83,8 +83,9 @@ export class RustBinaryBlob { let port: number; let ping_response: string; - // const maybe_active_workspace = global.global_context.globalState.get('active_workspace') as Workspace | undefined; - // const active_workspace_id = maybe_active_workspace ? maybe_active_workspace.workspace_id : null; + + const team = global.side_panel?.context.workspaceState.get('refactai.activeGroup'); + if (xdebug === 0) { if (this.lsp_client) { // running port = this.port; // keep the same port @@ -128,10 +129,10 @@ export class RustBinaryBlob { "--basic-telemetry", ]; - // if (active_workspace_id !== null && active_workspace_id !== undefined) { - // new_cmdline.push("--active-workspace-id"); - // new_cmdline.push(active_workspace_id.toString()); - // } + if (team && team.id) { + new_cmdline.push("--active-group-id"); + new_cmdline.push(team.id.toString()); + } if (vscode.workspace.getConfiguration().get("refactai.vecdb")) { new_cmdline.push("--vecdb"); @@ -166,7 +167,9 @@ export class RustBinaryBlob { break; } } + global.side_panel?.handleSettingsChange(); + } public async launch() { diff --git a/src/sidebar.ts b/src/sidebar.ts index d6021bb3f..a53c71214 100644 --- a/src/sidebar.ts +++ b/src/sidebar.ts @@ -24,7 +24,7 @@ import { ideNewFileAction, ideOpenSettingsAction, ideDiffPasteBackAction, - type ChatThread, + // type ChatThread, ideAnimateFileStart, ideAnimateFileStop, ideChatPageChange, @@ -40,8 +40,11 @@ import { ideSetLoginMessage, ideSetActiveTeamsGroup, ideClearActiveTeamsGroup, + ideSetActiveTeamsWorkspace, + ideClearActiveTeamsWorkspace, OpenFilePayload, - TeamsGroup + type TeamsGroup, + type TeamsWorkspace } from "refact-chat-js/dist/events"; import { basename, join } from "path"; import { diff_paste_back } from "./chatTab"; @@ -56,6 +59,7 @@ function composeHandlers(...eventHandlers: Handler[]) { return (data: any) => eventHandlers.forEach(fn => fn && fn(data)); } +// here export async function open_chat_tab( question: string, editor: vscode.TextEditor | undefined, @@ -70,18 +74,20 @@ export async function open_chat_tab( } if (global.side_panel && global.side_panel._view) { - const chat: ChatThread = { - id: uuidv4(), - messages: question ? [ - ...messages, - {role: "user", content: question}, - ] : [], - model: model, - new_chat_suggested: { - wasSuggested: false, - } - }; - global.side_panel.goto_chat(chat); // changes html + // TODO: ChatThread is no longer used + // const chat: ChatThread = { + // id: uuidv4(), + // messages: question ? [ + // ...messages, + // {ftm_role: "user", ftm_content: question}, + // ] : [], + // model: model, + // new_chat_suggested: { + // wasSuggested: false, + // } + // }; + // global.side_panel.goto_chat(chat); + global.side_panel.goto_chat(); // changes html } return; @@ -280,6 +286,8 @@ export class PanelWebview implements vscode.WebviewViewProvider { .getConfiguration() ?.get("refactai.ast") ?? false; + const connections = vscode.workspace.getConfiguration()?.get("refactai.xperimental") ?? false; + const apiKey = vscode.workspace.getConfiguration()?.get("refactai.apiKey") ?? ""; const addressURL = vscode.workspace.getConfiguration()?.get("refactai.addressURL") ?? ""; @@ -293,11 +301,12 @@ export class PanelWebview implements vscode.WebviewViewProvider { addressURL, lspPort: port, shiftEnterToSubmit: submitChatWithShiftEnter, - features: {vecdb, ast}, + features: {vecdb, ast, connections}, currentWorkspaceName: currentActiveWorkspaceName }); this._view?.webview.postMessage(message); + } public attachFile(path: string) { @@ -399,7 +408,7 @@ export class PanelWebview implements vscode.WebviewViewProvider { } // can change this to - public async goto_chat(chat_thread?: ChatThread) + public async goto_chat() { // this.html_main_screen(this._view.webview); // this.address = chat.chat_id; @@ -412,7 +421,7 @@ export class PanelWebview implements vscode.WebviewViewProvider { // ); // Could throw? - const html = await this.html_main_screen(this._view.webview, chat_thread); + const html = await this.html_main_screen(this._view.webview); this._view.webview.html = html; // this.update_webview(); } @@ -636,6 +645,7 @@ export class PanelWebview implements vscode.WebviewViewProvider { return this.handleSetLoginMessage(e.payload); } + // here if (ideSetActiveTeamsGroup.match(e)) { return this.handleSetActiveGroup(e.payload); } @@ -644,6 +654,14 @@ export class PanelWebview implements vscode.WebviewViewProvider { return this.handleClearActiveGroup(); } + if (ideSetActiveTeamsWorkspace.match(e)) { + return this.handleSetActiveWorkspace(e.payload); + } + + if (ideClearActiveTeamsWorkspace.match(e)) { + return this.handleClearActiveWorkspace(); + } + if(ideEscapeKeyPressed.match(e)) { return this.handleEscapePressed(e.payload); } @@ -815,16 +833,15 @@ export class PanelWebview implements vscode.WebviewViewProvider { usabilityHints.show_message_from_server('InferenceServer', message); } - async handleSetActiveGroup (group:TeamsGroup) { + async handleSetActiveGroup(group: TeamsGroup) { await this.context.workspaceState.update( 'refactai.activeGroup', group, ); - console.log(`[DEBUG]: updated locally active group in ./.vscode/settings.json: `, group); this.handleSettingsChange(); } - async handleClearActiveGroup () { + async handleClearActiveGroup() { await this.context.workspaceState.update( 'refactai.activeGroup', undefined, @@ -832,6 +849,22 @@ export class PanelWebview implements vscode.WebviewViewProvider { this.handleSettingsChange(); } + async handleSetActiveWorkspace(workspace: TeamsWorkspace) { + await global.global_context.globalState.update( + 'activeTeamsWorkspace', + workspace, + ); + this.handleSettingsChange(); + } + + async handleClearActiveWorkspace() { + await global.global_context.globalState.update( + 'activeTeamsWorkspace', + undefined, + ); + this.handleSettingsChange(); + } + async handleEscapePressed(mode: string) { const editor = vscode.window.activeTextEditor; if (!editor) { return; } @@ -976,7 +1009,8 @@ export class PanelWebview implements vscode.WebviewViewProvider { } - async createInitialState(thread?: ChatThread, tabbed = false): Promise> { + // TODO: chat thread has changed + async createInitialState(tabbed = false): Promise> { const fontSize = vscode.workspace.getConfiguration().get("editor.fontSize") ?? 12; const scaling = fontSize < 14 ? "90%" : "100%"; const activeColorTheme = this.getColorTheme(); @@ -984,13 +1018,16 @@ export class PanelWebview implements vscode.WebviewViewProvider { const ast = vscode.workspace.getConfiguration()?.get("refactai.ast") ?? false; const apiKey = vscode.workspace.getConfiguration()?.get("refactai.apiKey") ?? ""; const addressURL = vscode.workspace.getConfiguration()?.get("refactai.addressURL") ?? ""; - const activeTeamsGroup = this.context.workspaceState.get('refactai.activeGroup') ?? null; const port = global.rust_binary_blob?.get_port() ?? 8001; const completeManual = await getKeyBindingForChat("refactaicmd.completionManual"); const shiftEnterToSubmit = vscode.workspace.getConfiguration()?.get("refactai.shiftEnterToSubmit")?? false; - + + const activeTeamsWorkspace = global.global_context.globalState.get('activeTeamsWorkspace') ?? null; + const activeTeamsGroup = this.context.workspaceState.get('refactai.activeGroup') ?? null; const currentActiveWorkspaceName = this.getActiveWorkspace(); + const connections = vscode.workspace.getConfiguration()?.get("refactai.xperimental") ?? false; + const config: InitialState["config"] = { host: "vscode", tabbed, @@ -1006,6 +1043,7 @@ export class PanelWebview implements vscode.WebviewViewProvider { ast, images: true, statistics: true, + connections, }, keyBindings: { completeManual, @@ -1018,7 +1056,9 @@ export class PanelWebview implements vscode.WebviewViewProvider { const state: Partial = { teams: { + workspace: activeTeamsWorkspace, group: activeTeamsGroup, + skipped: false, }, current_project: {name: vscode.workspace.name ?? ""}, config, @@ -1032,26 +1072,27 @@ export class PanelWebview implements vscode.WebviewViewProvider { state.selected_snippet = snippet; } - if(thread) { - const chat: InitialState["chat"] = { - streaming: false, - error: null, - prevent_send: true, - waiting_for_response: false, - tool_use: thread.tool_use ? thread.tool_use : "explore", - cache: {}, - system_prompt: {}, - send_immediately: thread.messages.length > 0, - thread, - }; - state.chat = chat; - state.pages = [{name: "login page"}, {name: "history"}, {name: "chat"}]; - } + // if(thread) { + // // TODO: update this the messageThread + // const chat: InitialState["chat"] = { + // streaming: false, + // error: null, + // prevent_send: true, + // waiting_for_response: false, + // tool_use: thread.tool_use ? thread.tool_use : "explore", + // cache: {}, + // // system_prompt: {}, + // send_immediately: thread.messages.length > 0, + // thread, + // }; + // state.chat = chat; + // state.pages = [{name: "login page"}, {name: "history"}, {name: "chat"}]; + // } return state; } - private async html_main_screen(webview: vscode.Webview, chat_thread?: ChatThread, tabbed?: boolean) + private async html_main_screen(webview: vscode.Webview, tabbed?: boolean) { // TODO: add send immediately flag for context menu and toolbar const extensionUri = this.context.extensionUri; @@ -1073,7 +1114,7 @@ export class PanelWebview implements vscode.WebviewViewProvider { existing_address = ""; } - const initialState = await this.createInitialState(chat_thread, tabbed); + const initialState = await this.createInitialState(tabbed); let stringifiedInitialState = JSON.stringify(initialState); stringifiedInitialState = stringifiedInitialState.replace(/\<\/script>/gi, "");