Skip to content

Commit

Permalink
special role
Browse files Browse the repository at this point in the history
  • Loading branch information
madox2 committed Dec 17, 2024
1 parent dda1a41 commit 506669a
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 72 deletions.
113 changes: 57 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,35 @@ To use an AI command, type the command followed by an instruction prompt. You ca

If you are interested in more tips or would like to level up your Vim with more commands like [`:GitCommitMessage`](https://github.com/madox2/vim-ai/wiki/Custom-commands#suggest-a-git-commit-message) - suggesting a git commit message, visit the [Community Wiki](https://github.com/madox2/vim-ai/wiki).

## 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` and `o1-mini` role:

```vim
let g:vim_ai_roles_config_file = '/path/to/my/roles.ini'
```

```ini
# /path/to/my/roles.ini

[grammar]
prompt = fix spelling and grammar
options.temperature = 0.4

[o1-mini]
options.stream = 0
options.model = o1-mini
options.max_completion_tokens = 25000
options.temperature = 1
options.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.

## Reference

In the documentation below, `<selection>` denotes a visual selection or any other range, `{instruction}` an instruction prompt, `{role}` a [custom role](#roles) and `?` symbol an optional parameter.
Expand Down Expand Up @@ -179,56 +208,6 @@ Supported chat roles are **`>>> system`**, **`>>> user`**, **`>>> include`** and
Use this immediately after `AI`/`AIEdit`/`AIChat` command in order to re-try or get an alternative completion.
Note that the randomness of responses heavily depends on the [`temperature`](https://platform.openai.com/docs/api-reference/completions/create#completions/create-temperature) parameter.

## 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` and `o1-mini` role:

```vim
let g:vim_ai_roles_config_file = '/path/to/my/roles.ini'
```

```ini
# /path/to/my/roles.ini

[grammar]
prompt = fix spelling and grammar
options.temperature = 0.4

[o1-mini]
options.stream = 0
options.model = o1-mini
options.max_completion_tokens = 25000
options.temperature = 1
options.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

This plugin does not set any key binding. Create your own bindings in the `.vimrc` to trigger AI commands, for example:

```vim
" complete text on the current line or in visual selection
nnoremap <leader>a :AI<CR>
xnoremap <leader>a :AI<CR>
" edit text with a custom prompt
xnoremap <leader>s :AIEdit fix grammar and spelling<CR>
nnoremap <leader>s :AIEdit fix grammar and spelling<CR>
" trigger chat
xnoremap <leader>c :AIChat<CR>
nnoremap <leader>c :AIChat<CR>
" redo last AI command
nnoremap <leader>r :AIRedo<CR>
```

## Configuration

Each command is configured with a corresponding configuration variable.
Expand All @@ -246,14 +225,15 @@ let g:vim_ai_chat = {
\}
```

Once the above is set, you can modify options directly during the vim session:
Alternatively you can use special `default` role:

```vim
let g:vim_ai_chat['options']['model'] = 'o1-preview'
let g:vim_ai_chat['options']['stream'] = 0
let g:vim_ai_chat['options']['temperature'] = 1
let g:vim_ai_chat['options']['max_completion_tokens'] = 25000
let g:vim_ai_chat['options']['initial_prompt'] = ''
[default]
options.model = o1-preview
options.stream = 0
options.temperature = 1
options.max_completion_tokens = 25000
options.initial_prompt =
```

Or customize the options directly in the chat buffer:
Expand Down Expand Up @@ -481,6 +461,27 @@ let g:vim_ai_complete = complete_engine_config
let g:vim_ai_edit = complete_engine_config
```

## Key bindings

This plugin does not set any key binding. Create your own bindings in the `.vimrc` to trigger AI commands, for example:

```vim
" complete text on the current line or in visual selection
nnoremap <leader>a :AI<CR>
xnoremap <leader>a :AI<CR>
" edit text with a custom prompt
xnoremap <leader>s :AIEdit fix grammar and spelling<CR>
nnoremap <leader>s :AIEdit fix grammar and spelling<CR>
" trigger chat
xnoremap <leader>c :AIChat<CR>
nnoremap <leader>c :AIChat<CR>
" redo last AI command
nnoremap <leader>r :AIRedo<CR>
```

## Custom commands

You might find useful a [collection](https://github.com/madox2/vim-ai/wiki/Custom-commands) of custom commands on the [Community Wiki](https://github.com/madox2/vim-ai/wiki).
Expand Down
7 changes: 4 additions & 3 deletions doc/vim-ai.txt
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,11 @@ a selection of options: >
\ },
\}

Or modify options directly during the vim session: >
Alternatively you can use special `default` role: >

let g:vim_ai_chat['options']['model'] = 'gpt-4'
let g:vim_ai_chat['options']['temperature'] = 0.2
[default]
options.model=gpt-4
options.temperature=0.2

You can also customize the options in the chat header: >

Expand Down
14 changes: 7 additions & 7 deletions py/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ def parse_role_names(prompt):
def parse_prompt_and_role_config(user_instruction, command_type):
user_instruction = user_instruction.strip()
roles = parse_role_names(user_instruction)
if not roles:
# does not require role
return (user_instruction, {})

last_role = roles[-1]
last_role = roles[-1] if roles else ''
user_prompt = user_instruction[user_instruction.index(last_role) + len(last_role):].strip() # strip roles

parsed_role = merge_deep([load_role_config(role) for role in roles])
config = merge_deep([parsed_role['role_default'], parsed_role['role_' + command_type]])
role_results = [load_role_config(role) for role in [DEFAULT_ROLE_NAME] + roles]
parsed_role = merge_deep(role_results)
config = merge_deep([
parsed_role.get('role_default', {}),
parsed_role.get('role_' + command_type, {}),
])
role_prompt = config.get('prompt', '')
return user_prompt, config

Expand Down
2 changes: 2 additions & 0 deletions py/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ def load_ai_role_names(command_type):
if len(parts) == 1 or parts[-1] == command_type:
role_names.add(parts[0])

role_names = [name for name in role_names if name != DEFAULT_ROLE_NAME]

return list(role_names)
2 changes: 2 additions & 0 deletions py/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

utils_py_imported = True

DEFAULT_ROLE_NAME = 'default'

def is_ai_debugging():
return vim.eval("g:vim_ai_debug") == "1"

Expand Down
3 changes: 3 additions & 0 deletions roles-default.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# predefined roles

# default role is always defined even though empty
[default]

[right.chat]
ui.force_new_chat = 1
ui.open_chat_command = preset_right
Expand Down
10 changes: 5 additions & 5 deletions roles-example.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# By default vim-ai reads this configuration file but it is highly recommended to
# set up a custom role location in order to prevent loss of roles while re-installing plugin!
#
# - custom config file location: `let g:vim_ai_roles_config_file = '/path/to/my/roles.ini'`
# - .ini file structure: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
# This is an example, do not modify/use this file!!!
# Instead, configure location of your own role file:
# - let g:vim_ai_roles_config_file = '/path/to/my/roles.ini'

# .ini file structure: https://docs.python.org/3/library/configparser.html#supported-ini-file-structure

[grammar]
prompt = fix spelling and grammar
Expand Down
6 changes: 5 additions & 1 deletion tests/context_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@ def test_default_config():
'user_selection': 'Hello world!',
'command_type': 'chat',
})
expected_options = {
**default_config['options'],
'token_file_path': '/custom/path/ai.token',
}
expected_context = {
'config': default_config,
'config': { **default_config, 'options': expected_options },
'prompt': 'translate to Slovak:\nHello world!',
}
assert expected_context == actual_context
Expand Down
3 changes: 3 additions & 0 deletions tests/resources/roles.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[default]
options.token_file_path = /custom/path/ai.token

[test-role-simple]
prompt = simple role prompt
options.model = o1-preview
Expand Down

0 comments on commit 506669a

Please sign in to comment.