diff options
Diffstat (limited to '')
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | doc/vim-ai.txt | 2 | ||||
| -rw-r--r-- | py/utils.py | 33 |
3 files changed, 36 insertions, 6 deletions
@@ -185,7 +185,7 @@ Note that the randomness of responses heavily depends on the [`temperature`](htt ## Roles -In the context of this plugin, a role means a re-usable AI instruction and/or configuration. Roles are defined in the configuration `.ini` file. For example by defining a `grammar` role: +In the context of this plugin, a role means a re-usable AI instruction and/or configuration. Roles are defined in the configuration `.ini` file. For example by defining a `grammar` and `o1-mini` role: ```vim let g:vim_ai_roles_config_file = '/path/to/my/roles.ini' @@ -200,6 +200,9 @@ prompt = fix spelling and grammar [grammar.options] temperature = 0.4 +[grammar] +prompt = fix spelling and grammar + [o1-mini] [o1-mini.options] stream = 0 @@ -211,6 +214,8 @@ initial_prompt = Now you can select text and run it with command `:AIEdit /grammar`. +You can also combine roles `:AI /o1-mini /grammar helo world!` + See [roles-example.ini](./roles-example.ini) for more examples. ## Key bindings diff --git a/doc/vim-ai.txt b/doc/vim-ai.txt index 0d9a410..241e33b 100644 --- a/doc/vim-ai.txt +++ b/doc/vim-ai.txt @@ -202,6 +202,8 @@ Example of a role: > [grammar.options] temperature = 0.4 + +Now you can select text and run it with command `:AIEdit /grammar`. See roles-example.ini for more examples. The roles in g:vim_ai_roles_config_file are converted to a Vim dictionary whose diff --git a/py/utils.py b/py/utils.py index f81eeb8..849152e 100644 --- a/py/utils.py +++ b/py/utils.py @@ -334,17 +334,40 @@ empty_role_options = { 'options_chat': {}, } +def parse_roles(prompt): + chunks = prompt.split() + roles = [] + for chunk in chunks: + if not chunk.startswith("/"): + break + roles.append(chunk) + return [raw_role[1:] for raw_role in roles] + +def merge_role_configs(configs): + merged_options = empty_role_options + merged_role = {} + for config in configs: + options = config['options'] + merged_options = { + 'options_default': { **merged_options['options_default'], **options['options_default'] }, + 'options_complete': { **merged_options['options_complete'], **options['options_complete'] }, + 'options_chat': { **merged_options['options_chat'], **options['options_chat'] }, + } + merged_role ={ **merged_role, **config['role'] } + return { 'role': merged_role, 'options': merged_options } + def parse_prompt_and_role(raw_prompt): prompt = raw_prompt.strip() - role = re.split(' |:', prompt)[0] - if not role.startswith('/'): + roles = parse_roles(prompt) + if not roles: # does not require role return (prompt, empty_role_options) - prompt = prompt[len(role):].strip() - role = role[1:] + last_role = roles[-1] + prompt = prompt[prompt.index(last_role) + len(last_role):].strip() - config = load_role_config(role) + role_configs = [load_role_config(role) for role in roles] + config = merge_role_configs(role_configs) if 'prompt' in config['role'] and config['role']['prompt']: delim = '' if prompt.startswith(':') else ':\n' prompt = config['role']['prompt'] + delim + prompt |