e71846aa Andy McCall 1 month ago ↶
1
{% macro panel(base, a, csrf, what) %}
2
< section class = " panel " id = " assistants " >
3
< h2 > AI assistants</ h2 >
4
< p class = " small mute " > {{ what }} An assistant reviews a proposal when asked, or drafts its description; its answers are shown as the person who asked, via the assistant. It never approves.</ p >
5
{% if !a.inherited.is_empty() %}
6
< h3 > Inherited</ h3 >
7
< ul class = " hooks " >
8
{% for i in a.inherited %}
9
< li class = " hook " >
10
< div class = " hook-head " > < strong > {{ i.assistant.name }}</ strong > < span class = " tag " > {{ i.assistant.model }}</ span >
11
{% if i.on() %}< span class = " tag head " > on</ span > {% else if i.off_above %}< span class = " tag dim " > off above</ span > {% else %}< span class = " tag dim " > off</ span > {% endif %}
12
< span class = " small mute " > from {{ i.from }}</ span > </ div >
13
</ li >
14
{% endfor %}
15
</ ul >
16
{% endif %}
17
{% if a.own.is_empty() %}< p class = " mute small " > {% if a.inherited.is_empty() %}None.{% else %}None of its own.{% endif %}</ p > {% else %}
18
< ul class = " hooks " >
19
{% for o in a.own %}{% let r = o.assistant %}
20
< li class = " hook " >
21
< div class = " hook-head " >
22
< strong > {{ r.name }}</ strong > < span class = " tag " > {{ r.model }}</ span > < span class = " tag " > {{ r.api }}</ span >
23
{% if o.on() %}< span class = " tag head " > on</ span > {% else if o.off_above %}< span class = " tag dim " title = " An assistant of this name is turned off at a level above" > off above</ span > {% else %}< span class = " tag dim " > off</ span > {% endif %}
24
</ div >
25
< p class = " small mute " > < code > {{ r.endpoint }}</ code > · token {% if r.has_token() %}set{% else %}none{% endif %} · context {{ r.budget }} characters</ p >
26
< form class = " tiny " method = " post" action = " {{ base }}/assistants" > < input type = " hidden" name = " _csrf" value = " {{ csrf }}" > < input type = " hidden" name = " id" value = " {{ r.id }}" > < button name = " action" value = " toggle" > {% if r.enabled %}turn off{% else %}turn on{% endif %}</ button > < button name = " action" value = " test" > test</ button > < button name = " action" value = " delete" class = " danger-btn " onclick = " return confirm ( ' Delete {{ r.name }}?' ) " > delete</ button > </ form >
27
< details class = " hook-edit " > < summary class = " small " > edit</ summary >
28
< form class = " card " method = " post" action = " {{ base }}/assistants" >
29
< input type = " hidden" name = " _csrf" value = " {{ csrf }}" > < input type = " hidden" name = " id" value = " {{ r.id }}" > < input type = " hidden" name = " action" value = " update" >
30
< label for = " an{{ r.id }}" > Name</ label > < input type = " text" id = " an{{ r.id }} " name = " name" value = " {{ r.name }}" >
31
< label for = " ae{{ r.id }}" > Endpoint</ label > < input type = " text" id = " ae{{ r.id }} " name = " endpoint" value = " {{ r.endpoint }}" autocomplete = " off" >
32
< label for = " aa{{ r.id }}" > API</ label >
33
< select id = " aa{{ r.id }} " name = " api" > {% for api in a.apis %}< option value = " {{ api }}" {% if r.api = = *api %} selected {% endif %}> {{ api }}</ option > {% endfor %}</ select >
34
< label for = " am{{ r.id }}" > Model</ label > < input type = " text" id = " am{{ r.id }} " name = " model" value = " {{ r.model }}" >
35
< label for = " at{{ r.id }}" > Token</ label > < input type = " password" id = " at{{ r.id }} " name = " token" placeholder = " {% if r.has_token() %}unchanged{% else %}none{% endif %}" autocomplete = " new-password" >
36
< label for = " ah{{ r.id }}" > Extra headers</ label > < textarea id = " ah{{ r.id }} " name = " headers" rows = " 2" placeholder = " Name: value" > {{ r.headers }}</ textarea >
37
< label for = " ab{{ r.id }}" > Context budget (characters)</ label > < input type = " text" id = " ab{{ r.id }} " name = " budget" value = " {{ r.budget }}" >
38
< div class = " choice " > < label > < input type = " checkbox" name = " enabled" value = " 1" {% if r.enabled %} checked {% endif %}> on</ label > </ div >
39
< button type = " submit" > SAVE</ button >
40
</ form >
41
</ details >
42
</ li >
43
{% endfor %}
44
</ ul > {% endif %}
45
< form class = " card " method = " post" action = " {{ base }}/assistants" >
46
< input type = " hidden" name = " _csrf" value = " {{ csrf }}" > < input type = " hidden" name = " action" value = " add" >
47
< h3 > Add an assistant</ h3 >
48
< label for = " aname" > Name</ label > < input type = " text" id = " aname " name = " name" placeholder = " Claude" required >
49
< label for = " aendpoint" > Endpoint</ label > < input type = " text" id = " aendpoint " name = " endpoint" placeholder = " https://api.anthropic.com/v1/messages" required autocomplete = " off" >
50
< label for = " aapi" > API</ label >
51
< select id = " aapi " name = " api" > {% for api in a.apis %}< option value = " {{ api }}" > {{ api }}{% if *api == "chat-completions" %} (OpenAI, DeepSeek, Ollama, most others){% else %} (Anthropic){% endif %}</ option > {% endfor %}</ select >
52
< label for = " amodel" > Model</ label > < input type = " text" id = " amodel " name = " model" placeholder = " claude-opus-5-5" required >
53
< label for = " atoken" > Token</ label > < input type = " password" id = " atoken " name = " token" autocomplete = " new-password" >
54
< p class = " small mute " > Sent as a bearer token, or as the API key for Anthropic; kept sealed on the server and never shown again. Leave it empty for an endpoint that needs none.</ p >
55
< label for = " aheaders" > Extra headers</ label > < textarea id = " aheaders " name = " headers" rows = " 2" placeholder = " Name: value" > </ textarea >
56
< label for = " abudget" > Context budget (characters)</ label > < input type = " text" id = " abudget " name = " budget" value = " {{ a.default_budget }}" >
57
< div class = " choice " > < label > < input type = " checkbox" name = " enabled" value = " 1" checked > on</ label > </ div >
58
< button type = " submit" > ADD</ button >
59
</ form >
60
< form class = " card " method = " post" action = " {{ base }}/assistants" >
61
< input type = " hidden" name = " _csrf" value = " {{ csrf }}" > < input type = " hidden" name = " action" value = " prompt" >
62
< h3 > Prompt</ h3 >
63
{% for (from, text) in a.inherited_prompts %}< details > < summary class = " small mute " > From {{ from }}</ summary > < pre class = " snippet " > {{ text }}</ pre > </ details > {% endfor %}
64
< label for = " aprompt" > What every assistant is told here{% if !a.inherited_prompts.is_empty() %}, after the prompts above{% endif %}</ label >
65
< textarea id = " aprompt " name = " prompt" rows = " 6" placeholder = " Review for correctness first. This project is written in Rust; the style guide is in docs/style.md." > {{ a.prompt }}</ textarea >
66
< button type = " submit" > SAVE PROMPT</ button >
67
</ form >
68
</ section >
69
{% endmacro %}