# prompts


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

Each prompt of the tutor has two parts. The variable parts (the concept,
the thread, the JSON shape) stay in code. The instruction text is in
this registry. Each prompt has a name, a plain label, a note on what it
changes, and its default text from code. The Settings page shows each
prompt, and you can change its text there. The tutor reads each prompt
when it calls the model. Thus a change works on the next question, with
no restart.

Import the tools that this module uses. The settings come from
[`settings`](https://vedicreader.github.io/abhyasa/settings.html#settings)
only when a prompt is read, so the import stays light.

## The registry

[`register`](https://vedicreader.github.io/abhyasa/prompts.html#register)
adds a prompt to `PROMPTS` and returns its default text. A `check` can
refuse a bad text: it raises `ValueError` with a plain message.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/abhyasa/blob/main/abhyasa/prompts.py#L16"
target="_blank" style="float:right; font-size:smaller">source</a>

### register

``` python
def register(
    name:str, label:str, note:str, dflt:str, check:NoneType=None
)->str:
```

*Add the prompt `name` with a plain `label`, a `note` on what it
changes, its
[`dflt`](https://vedicreader.github.io/abhyasa/settings.html#dflt) text
and an optional `check`. Return
[`dflt`](https://vedicreader.github.io/abhyasa/settings.html#dflt).*

[`lines`](https://vedicreader.github.io/abhyasa/prompts.html#lines)
gives the lines of a text that are not empty.
[`need_lines`](https://vedicreader.github.io/abhyasa/prompts.html#need_lines)
makes a check that refuses a text without exactly `n` such lines.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/abhyasa/blob/main/abhyasa/prompts.py#L26"
target="_blank" style="float:right; font-size:smaller">source</a>

### need_lines

``` python
def need_lines(
    n:int, what:str
):
```

*A check that refuses a text that does not have `n` lines that are not
empty.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/abhyasa/blob/main/abhyasa/prompts.py#L22"
target="_blank" style="float:right; font-size:smaller">source</a>

### lines

``` python
def lines(
    text:str
)->list:
```

*The lines of `text` that are not empty, without spaces at the ends.*

## Read and save

[`prompt`](https://vedicreader.github.io/abhyasa/prompts.html#prompt)
gives the saved text of a prompt, else its default.
[`set_prompt`](https://vedicreader.github.io/abhyasa/prompts.html#set_prompt)
saves a text in the settings, under the `prompts` key. An empty text, or
a text that is the same as the default, removes the saved text. Then the
default is in use again, also when a new version changes the default.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/abhyasa/blob/main/abhyasa/prompts.py#L43"
target="_blank" style="float:right; font-size:smaller">source</a>

### set_prompt

``` python
def set_prompt(
    name:str, text:str=''
)->str:
```

*Save the text of the prompt `name`. An empty text uses the default. A
text that fails the check raises `ValueError`. Return the text in use.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/abhyasa/blob/main/abhyasa/prompts.py#L38"
target="_blank" style="float:right; font-size:smaller">source</a>

### prompt

``` python
def prompt(
    name:str
)->str:
```

*The text of the prompt `name` now: the saved text, else the default.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/abhyasa/blob/main/abhyasa/prompts.py#L33"
target="_blank" style="float:right; font-size:smaller">source</a>

### saved

``` python
def saved()->dict:
```

*The saved prompt texts: name -\> text.*

## Tests

A small prompt with a check of 2 lines. Its default is in use at first.

``` python
register('greet', 'Greeting', 'The first line.', 'Say hello.\nSay your name.', need_lines(2, 'The greeting'))
test_eq(prompt('greet'), 'Say hello.\nSay your name.')
```

A saved text is in use at once, and the settings keep it under
`prompts`.

``` python
test_eq(set_prompt('greet', 'Say hi.\r\nSay your job.\n'), 'Say hi.\nSay your job.')
test_eq((prompt('greet'), saved()), ('Say hi.\nSay your job.', {'greet': 'Say hi.\nSay your job.'}))
```

A text that fails the check is refused with a plain message, and the
saved text stays.

``` python
test_fail(lambda: set_prompt('greet', 'Only one line.'), contains='needs 2 lines')
test_eq(prompt('greet'), 'Say hi.\nSay your job.')
```

An empty text, or only spaces, removes the saved text, so the default is
in use again. A text that is the same as the default is not kept.

``` python
test_eq(set_prompt('greet', '  \n '), 'Say hello.\nSay your name.')
set_prompt('greet', 'Say hello.\nSay your name.')
test_eq(saved(), {})
```

An unknown name is an error. Then the test prompt goes away.

``` python
test_fail(lambda: prompt('nope'))
del PROMPTS['greet']
```
