From f1697631eb8652bd676aaa7c3cb86dbe44ac4323 Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Tue, 18 Apr 2023 20:17:27 +0200 Subject: [PATCH 1/4] seleciton block boundary to eliminate empty response --- autoload/vim_ai.vim | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/autoload/vim_ai.vim b/autoload/vim_ai.vim index d1c27a9..ac79f3b 100644 --- a/autoload/vim_ai.vim +++ b/autoload/vim_ai.vim @@ -48,7 +48,14 @@ function! s:MakePrompt(is_selection, lines, instruction) let l:lines = trim(join(a:lines, "\n")) let l:instruction = trim(a:instruction) let l:delimiter = l:instruction != "" && a:is_selection ? ":\n" : "" - let l:selection = a:is_selection || l:instruction == "" ? l:lines : "" + let l:selection = "" + if l:instruction == "" + let l:selection = l:lines + elseif a:is_selection + " TODO: check if lines already contain ##### + " NOTE: surround selection with ##### in order to eliminate empty responses + let l:selection = "#####\n" . l:lines . "\n#####" + endif return join([l:instruction, l:delimiter, l:selection], "") endfunction From ec53d91e7f54cb363b4e68a7ed3f03fca8704902 Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Wed, 19 Apr 2023 19:41:30 +0200 Subject: [PATCH 2/4] use selection block only if it is safe --- autoload/vim_ai.vim | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/autoload/vim_ai.vim b/autoload/vim_ai.vim index ac79f3b..00792dd 100644 --- a/autoload/vim_ai.vim +++ b/autoload/vim_ai.vim @@ -52,9 +52,13 @@ function! s:MakePrompt(is_selection, lines, instruction) if l:instruction == "" let l:selection = l:lines elseif a:is_selection - " TODO: check if lines already contain ##### " NOTE: surround selection with ##### in order to eliminate empty responses - let l:selection = "#####\n" . l:lines . "\n#####" + " TODO: add selection prompt boundary config + if match(l:lines, "#####") != -1 + let l:selection = l:lines + else + let l:selection = "#####\n" . l:lines . "\n#####" + endif endif return join([l:instruction, l:delimiter, l:selection], "") endfunction From e328631901695e5f31b5cdd4eb4b1b955372deb6 Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Thu, 20 Apr 2023 19:26:56 +0200 Subject: [PATCH 3/4] selection boundary config --- README.md | 7 ++++++ autoload/vim_ai.vim | 48 ++++++++++++++++++++++---------------- autoload/vim_ai_config.vim | 3 +++ doc/vim-ai.txt | 3 +++ 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index fc3d5cb..e610583 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ Below are listed all available configuration options, along with their default v ```vim " :AI " - options: openai config (see https://platform.openai.com/docs/api-reference/completions) +" - options.selection_boundary: seleciton prompt wrapper (eliminates empty responses, see #20) " - engine: complete | chat - see how to configure chat engine in the section below let g:vim_ai_complete = { \ "engine": "complete", @@ -194,11 +195,13 @@ let g:vim_ai_complete = { \ "max_tokens": 1000, \ "temperature": 0.1, \ "request_timeout": 20, +\ "selection_boundary": "#####", \ }, \} " :AIEdit " - options: openai config (see https://platform.openai.com/docs/api-reference/completions) +" - options.selection_boundary: seleciton prompt wrapper " - engine: complete | chat - see how to configure chat engine in the section below let g:vim_ai_edit = { \ "engine": "complete", @@ -207,6 +210,7 @@ let g:vim_ai_edit = { \ "max_tokens": 1000, \ "temperature": 0.1, \ "request_timeout": 20, +\ "selection_boundary": "#####", \ }, \} @@ -221,6 +225,7 @@ END " :AIChat " - options: openai config (see https://platform.openai.com/docs/api-reference/chat) " - options.initial_prompt: prompt prepended to every chat request +" - options.selection_boundary: seleciton prompt wrapper " - ui.populate_options: put [chat-options] to the chat header " - ui.open_chat_command: customize how to open chat window " - ui.scratch_buffer_keep_open: re-use scratch buffer within the vim session @@ -230,6 +235,7 @@ let g:vim_ai_chat = { \ "max_tokens": 1000, \ "temperature": 1, \ "request_timeout": 20, +\ "selection_boundary": "", \ "initial_prompt": s:initial_chat_prompt, \ }, \ "ui": { @@ -271,6 +277,7 @@ let chat_engine_config = { \ "max_tokens": 1000, \ "temperature": 0.1, \ "request_timeout": 20, +\ "selection_boundary": "", \ "initial_prompt": initial_prompt, \ }, \} diff --git a/autoload/vim_ai.vim b/autoload/vim_ai.vim index 00792dd..69a0f95 100644 --- a/autoload/vim_ai.vim +++ b/autoload/vim_ai.vim @@ -44,36 +44,42 @@ function! vim_ai#MakeScratchWindow() endif endfunction -function! s:MakePrompt(is_selection, lines, instruction) - let l:lines = trim(join(a:lines, "\n")) - let l:instruction = trim(a:instruction) - let l:delimiter = l:instruction != "" && a:is_selection ? ":\n" : "" +function! s:MakeSelectionPrompt(is_selection, lines, instruction, options) let l:selection = "" - if l:instruction == "" - let l:selection = l:lines + if a:instruction == "" + let l:selection = a:lines elseif a:is_selection - " NOTE: surround selection with ##### in order to eliminate empty responses - " TODO: add selection prompt boundary config - if match(l:lines, "#####") != -1 - let l:selection = l:lines + let l:boundary = a:options['selection_boundary'] + if l:boundary != "" && match(a:lines, l:boundary) == -1 + " NOTE: surround selection with boundary (e.g. #####) in order to eliminate empty responses + let l:selection = l:boundary . "\n" . a:lines . "\n" . l:boundary else - let l:selection = "#####\n" . l:lines . "\n#####" + let l:selection = a:lines endif endif + return l:selection +endfunction + +function! s:MakePrompt(is_selection, lines, instruction, options) + let l:lines = trim(join(a:lines, "\n")) + let l:instruction = trim(a:instruction) + let l:delimiter = l:instruction != "" && a:is_selection ? ":\n" : "" + let l:selection = s:MakeSelectionPrompt(a:is_selection, l:lines, l:instruction, a:options) return join([l:instruction, l:delimiter, l:selection], "") endfunction function! vim_ai#AIRun(is_selection, ...) range + let l:engine = g:vim_ai_complete['engine'] + let l:options = g:vim_ai_complete['options'] + let l:instruction = a:0 ? a:1 : "" let l:lines = getline(a:firstline, a:lastline) - let l:prompt = s:MakePrompt(a:is_selection, l:lines, l:instruction) + let l:prompt = s:MakePrompt(a:is_selection, l:lines, l:instruction, l:options) let s:last_command = "complete" let s:last_instruction = l:instruction let s:last_is_selection = a:is_selection - let l:engine = g:vim_ai_complete['engine'] - let l:options = g:vim_ai_complete['options'] let l:cursor_on_empty_line = trim(join(l:lines, "\n")) == "" set paste if l:cursor_on_empty_line @@ -87,15 +93,16 @@ function! vim_ai#AIRun(is_selection, ...) range endfunction function! vim_ai#AIEditRun(is_selection, ...) range + let l:engine = g:vim_ai_edit['engine'] + let l:options = g:vim_ai_edit['options'] + let l:instruction = a:0 ? a:1 : "" - let l:prompt = s:MakePrompt(a:is_selection, getline(a:firstline, a:lastline), l:instruction) + let l:prompt = s:MakePrompt(a:is_selection, getline(a:firstline, a:lastline), l:instruction, l:options) let s:last_command = "edit" let s:last_instruction = l:instruction let s:last_is_selection = a:is_selection - let l:engine = g:vim_ai_edit['engine'] - let l:options = g:vim_ai_edit['options'] set paste execute "normal! " . a:firstline . "GV" . a:lastline . "Gc" execute "py3file " . s:complete_py @@ -103,6 +110,9 @@ function! vim_ai#AIEditRun(is_selection, ...) range endfunction function! vim_ai#AIChatRun(is_selection, ...) range + let l:options = g:vim_ai_chat['options'] + let l:ui = g:vim_ai_chat['ui'] + let l:instruction = "" let l:lines = getline(a:firstline, a:lastline) set paste @@ -112,7 +122,7 @@ function! vim_ai#AIChatRun(is_selection, ...) range let l:prompt = "" if a:0 || a:is_selection let l:instruction = a:0 ? a:1 : "" - let l:prompt = s:MakePrompt(a:is_selection, l:lines, l:instruction) + let l:prompt = s:MakePrompt(a:is_selection, l:lines, l:instruction, l:options) endif execute "normal! Gi" . l:prompt endif @@ -121,8 +131,6 @@ function! vim_ai#AIChatRun(is_selection, ...) range let s:last_instruction = l:instruction let s:last_is_selection = a:is_selection - let l:options = g:vim_ai_chat['options'] - let l:ui = g:vim_ai_chat['ui'] execute "py3file " . s:chat_py set nopaste endfunction diff --git a/autoload/vim_ai_config.vim b/autoload/vim_ai_config.vim index 92d791a..409070b 100644 --- a/autoload/vim_ai_config.vim +++ b/autoload/vim_ai_config.vim @@ -5,6 +5,7 @@ let g:vim_ai_complete_default = { \ "max_tokens": 1000, \ "temperature": 0.1, \ "request_timeout": 20, +\ "selection_boundary": "#####", \ }, \} let g:vim_ai_edit_default = { @@ -14,6 +15,7 @@ let g:vim_ai_edit_default = { \ "max_tokens": 1000, \ "temperature": 0.1, \ "request_timeout": 20, +\ "selection_boundary": "#####", \ }, \} @@ -29,6 +31,7 @@ let g:vim_ai_chat_default = { \ "max_tokens": 1000, \ "temperature": 1, \ "request_timeout": 20, +\ "selection_boundary": "", \ "initial_prompt": s:initial_chat_prompt, \ }, \ "ui": { diff --git a/doc/vim-ai.txt b/doc/vim-ai.txt index 37d7add..5cc0718 100644 --- a/doc/vim-ai.txt +++ b/doc/vim-ai.txt @@ -28,6 +28,7 @@ Options: > \ "max_tokens": 1000, \ "temperature": 0.1, \ "request_timeout": 20, + \ "selection_boundary": "#####", \ }, \} @@ -48,6 +49,7 @@ Options: > \ "max_tokens": 1000, \ "temperature": 0.1, \ "request_timeout": 20, + \ "selection_boundary": "#####", \ }, \} @@ -75,6 +77,7 @@ Options: > \ "max_tokens": 1000, \ "temperature": 1, \ "request_timeout": 20, + \ "selection_boundary": "#####", \ "initial_prompt": s:initial_chat_prompt, \ }, \ "ui": { From e4c3dad037a1950de5eee153c45c2eddfe0f8f7a Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Thu, 20 Apr 2023 19:34:26 +0200 Subject: [PATCH 4/4] documented request timeout --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e610583..3046570 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ Below are listed all available configuration options, along with their default v ```vim " :AI " - options: openai config (see https://platform.openai.com/docs/api-reference/completions) +" - options.request_timout: request timeout in seconds " - options.selection_boundary: seleciton prompt wrapper (eliminates empty responses, see #20) " - engine: complete | chat - see how to configure chat engine in the section below let g:vim_ai_complete = { @@ -201,6 +202,7 @@ let g:vim_ai_complete = { " :AIEdit " - options: openai config (see https://platform.openai.com/docs/api-reference/completions) +" - options.request_timout: request timeout in seconds " - options.selection_boundary: seleciton prompt wrapper " - engine: complete | chat - see how to configure chat engine in the section below let g:vim_ai_edit = { @@ -225,6 +227,7 @@ END " :AIChat " - options: openai config (see https://platform.openai.com/docs/api-reference/chat) " - options.initial_prompt: prompt prepended to every chat request +" - options.request_timout: request timeout in seconds " - options.selection_boundary: seleciton prompt wrapper " - ui.populate_options: put [chat-options] to the chat header " - ui.open_chat_command: customize how to open chat window