Skip to content

Commit

Permalink
execute mutliple roles
Browse files Browse the repository at this point in the history
  • Loading branch information
madox2 committed Dec 12, 2024
1 parent 5226564 commit c9bc248
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions doc/vim-ai.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 28 additions & 5 deletions py/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,17 +334,40 @@ def load_role_config(role):
'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
Expand Down

0 comments on commit c9bc248

Please sign in to comment.