From b0f7e3b8d92289d1a8086e3eed206f8b5757328b Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Sat, 9 Mar 2024 18:06:14 +0100 Subject: read role prompt from config --- py/utils.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'py/utils.py') diff --git a/py/utils.py b/py/utils.py index 19de7c4..7a1a574 100644 --- a/py/utils.py +++ b/py/utils.py @@ -11,6 +11,7 @@ import re from urllib.error import URLError from urllib.error import HTTPError import traceback +import configparser is_debugging = vim.eval("g:vim_ai_debug") == "1" debug_log_file = vim.eval("g:vim_ai_debug_log_file") @@ -261,3 +262,26 @@ def handle_completion_error(error): def clear_echo_message(): # https://neovim.discourse.group/t/how-to-clear-the-echo-message-in-the-command-line/268/3 vim.command("call feedkeys(':','nx')") + +def load_role_config(role): + roles_config_path = os.path.expanduser('~/.vim/roles.ini') # TODO configure + roles = configparser.ConfigParser() + roles.read(roles_config_path) + if not role in roles: + raise KnownError(f"Role {role} not found") # TODO handle errors + return roles[role] + +def parse_prompt_and_role(raw_prompt): + prompt = raw_prompt.strip() + role = re.split(' |:', prompt)[0] + if not role.startswith('/'): + # does not require role + return (prompt, {}) + + prompt = prompt[len(role):].strip() + role = role[1:] + + role_config = load_role_config(role) + delim = '' if prompt.startswith(':') else ':\n' + prompt = role_config['prompt'] + delim + prompt + return (prompt, {}) -- cgit v1.2.3 From bdd1069562967bd07921e75873d54eb75d62144d Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Sat, 9 Mar 2024 18:32:45 +0100 Subject: parse role options --- py/utils.py | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'py/utils.py') diff --git a/py/utils.py b/py/utils.py index 7a1a574..52e538d 100644 --- a/py/utils.py +++ b/py/utils.py @@ -269,19 +269,37 @@ def load_role_config(role): roles.read(roles_config_path) if not role in roles: raise KnownError(f"Role {role} not found") # TODO handle errors - return roles[role] + + options = roles[f"{role}.options"] if f"{role}.options" in roles else {} + options_complete =roles[f"{role}.options-complete"] if f"{role}.options-complete" in roles else {} + options_chat = roles[f"{role}.options-chat"] if f"{role}.options-chat" in roles else {} + + return { + 'role': dict(roles[role]), + 'options': { + 'options_default': dict(options), + 'options_complete': dict(options_complete), + 'options_chat': dict(options_chat), + }, + } + +empty_role_options = { + 'options_default': {}, + 'options_complete': {}, + 'options_chat': {}, +} def parse_prompt_and_role(raw_prompt): prompt = raw_prompt.strip() role = re.split(' |:', prompt)[0] if not role.startswith('/'): # does not require role - return (prompt, {}) + return (prompt, empty_role_options) prompt = prompt[len(role):].strip() role = role[1:] - role_config = load_role_config(role) + config = load_role_config(role) delim = '' if prompt.startswith(':') else ':\n' - prompt = role_config['prompt'] + delim + prompt - return (prompt, {}) + prompt = config['role']['prompt'] + delim + prompt + return (prompt, config['options']) -- cgit v1.2.3 From f4130feb986760a8d956983cb5cfe8d7106e7d4a Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Sat, 9 Mar 2024 19:37:55 +0100 Subject: roles example file --- py/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'py/utils.py') diff --git a/py/utils.py b/py/utils.py index 52e538d..6600fc3 100644 --- a/py/utils.py +++ b/py/utils.py @@ -264,7 +264,7 @@ def clear_echo_message(): vim.command("call feedkeys(':','nx')") def load_role_config(role): - roles_config_path = os.path.expanduser('~/.vim/roles.ini') # TODO configure + roles_config_path = os.path.expanduser(vim.eval("g:vim_ai_roles_config_file")) roles = configparser.ConfigParser() roles.read(roles_config_path) if not role in roles: -- cgit v1.2.3 From 188d07f5efa8a4cde3407e71ca2013c10c051bba Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Sat, 9 Mar 2024 20:02:24 +0100 Subject: simple error handling --- py/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'py/utils.py') diff --git a/py/utils.py b/py/utils.py index 6600fc3..9ef8b72 100644 --- a/py/utils.py +++ b/py/utils.py @@ -265,10 +265,14 @@ def clear_echo_message(): def load_role_config(role): roles_config_path = os.path.expanduser(vim.eval("g:vim_ai_roles_config_file")) + if not os.path.exists(roles_config_path): + raise Exception(f"Role config file does not exist: {roles_config_path}") + roles = configparser.ConfigParser() roles.read(roles_config_path) + if not role in roles: - raise KnownError(f"Role {role} not found") # TODO handle errors + raise Exception(f"Role `{role}` not found") options = roles[f"{role}.options"] if f"{role}.options" in roles else {} options_complete =roles[f"{role}.options-complete"] if f"{role}.options-complete" in roles else {} -- cgit v1.2.3 From cb4c9e94b2a500f38161227df24feed762000095 Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Sat, 9 Mar 2024 22:18:36 +0100 Subject: supprot config only roles --- py/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'py/utils.py') diff --git a/py/utils.py b/py/utils.py index 9ef8b72..6bd90a1 100644 --- a/py/utils.py +++ b/py/utils.py @@ -304,6 +304,7 @@ def parse_prompt_and_role(raw_prompt): role = role[1:] config = load_role_config(role) - delim = '' if prompt.startswith(':') else ':\n' - prompt = config['role']['prompt'] + delim + prompt + if 'prompt' in config['role'] and config['role']['prompt']: + delim = '' if prompt.startswith(':') else ':\n' + prompt = config['role']['prompt'] + delim + prompt return (prompt, config['options']) -- cgit v1.2.3 From 881fd24a6d2c0de387256b4d6e05f5d0a53cc8e2 Mon Sep 17 00:00:00 2001 From: Konfekt Date: Sun, 10 Mar 2024 21:29:32 +0100 Subject: optionally supplement roles dict by vim function source The application was restricted to loading role configurations only from a predefined config file, which limited extensibility. Enable dynamic role configuration by invoking a custom Vim function if it is defined. This allows users to extend the role configurations beyond the static file. diff --git a/doc/vim-ai.txt b/doc/vim-ai.txt: -The roles in g:vim_ai_roles_config_file are converted to a Vim dictionary. -Optionally, additional roles can be added by defining a function VimAIRoleParser() -whose output is a dictionary of the same format as g:vim_ai_roles_config_file. - diff --git a/py/roles.py b/py/roles.py: -if vim.eval('exists("*VimAIRoleParser")'): - roles.update(vim.eval('VimAIRoleParser()')) - diff --git a/py/utils.py b/py/utils.py: - if vim.eval('exists("*VimAIRoleParser")'): - roles.update(vim.eval('VimAIRoleParser()')) - --- py/utils.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'py/utils.py') diff --git a/py/utils.py b/py/utils.py index 6bd90a1..471b5c4 100644 --- a/py/utils.py +++ b/py/utils.py @@ -271,6 +271,13 @@ def load_role_config(role): roles = configparser.ConfigParser() roles.read(roles_config_path) + if vim.eval("exists('g:vim_ai_roles_config_function')") == '1': + roles_config_function = vim.eval("g:vim_ai_roles_config_function") + if not vim.eval("exists('*" + roles_config_function + "')"): + raise Exception(f"Role config function does not exist: {roles_config_function}") + else: + roles.update(vim.eval(roles_config_function + "()")) + if not role in roles: raise Exception(f"Role `{role}` not found") -- cgit v1.2.3 From 6a053767af08d6edfb46b4be72f05a9b3bc7be04 Mon Sep 17 00:00:00 2001 From: Martin Bielik Date: Sun, 24 Mar 2024 11:29:22 +0100 Subject: reusing parsing code --- py/utils.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'py/utils.py') diff --git a/py/utils.py b/py/utils.py index 471b5c4..963377d 100644 --- a/py/utils.py +++ b/py/utils.py @@ -263,6 +263,14 @@ def clear_echo_message(): # https://neovim.discourse.group/t/how-to-clear-the-echo-message-in-the-command-line/268/3 vim.command("call feedkeys(':','nx')") +def enhance_roles_with_custom_function(roles): + if vim.eval("exists('g:vim_ai_roles_config_function')") == '1': + roles_config_function = vim.eval("g:vim_ai_roles_config_function") + if not vim.eval("exists('*" + roles_config_function + "')"): + raise Exception(f"Role config function does not exist: {roles_config_function}") + else: + roles.update(vim.eval(roles_config_function + "()")) + def load_role_config(role): roles_config_path = os.path.expanduser(vim.eval("g:vim_ai_roles_config_file")) if not os.path.exists(roles_config_path): @@ -271,12 +279,7 @@ def load_role_config(role): roles = configparser.ConfigParser() roles.read(roles_config_path) - if vim.eval("exists('g:vim_ai_roles_config_function')") == '1': - roles_config_function = vim.eval("g:vim_ai_roles_config_function") - if not vim.eval("exists('*" + roles_config_function + "')"): - raise Exception(f"Role config function does not exist: {roles_config_function}") - else: - roles.update(vim.eval(roles_config_function + "()")) + enhance_roles_with_custom_function(roles) if not role in roles: raise Exception(f"Role `{role}` not found") -- cgit v1.2.3