Improve search

This commit is contained in:
2026-03-02 02:26:25 +00:00
parent a9f5f3f75d
commit b94219fc5b
20 changed files with 1626 additions and 314 deletions

View File

@@ -8,59 +8,84 @@
<article class="box">
<h2 class="title is-6">Create Command Profile</h2>
<form method="post">
<p class="help">Create reusable command behavior. Example: <code>#bp#</code> reply command for business-plan extraction.</p>
<form method="post" aria-label="Create command profile">
{% csrf_token %}
<input type="hidden" name="action" value="profile_create">
<div class="columns">
<div class="column">
<input class="input is-small" name="slug" placeholder="slug (bp)" value="bp">
<label class="label is-size-7" for="create_slug">Slug</label>
<input id="create_slug" class="input is-small" name="slug" placeholder="slug (bp)" value="bp" aria-describedby="create_slug_help">
<p id="create_slug_help" class="help">Stable command id, e.g. <code>bp</code>.</p>
</div>
<div class="column">
<input class="input is-small" name="name" placeholder="name" value="Business Plan">
<label class="label is-size-7" for="create_name">Name</label>
<input id="create_name" class="input is-small" name="name" placeholder="name" value="Business Plan">
</div>
<div class="column">
<input class="input is-small" name="trigger_token" placeholder="trigger token" value="#bp#">
<label class="label is-size-7" for="create_trigger_token">Trigger Token</label>
<input id="create_trigger_token" class="input is-small" name="trigger_token" placeholder="trigger token" value="#bp#">
</div>
</div>
<textarea class="textarea is-small" name="template_text" rows="4" placeholder="Business plan template"></textarea>
<button class="button is-link is-small" type="submit">Create Profile</button>
<label class="label is-size-7" for="create_template_text">Template Text</label>
<textarea id="create_template_text" class="textarea is-small" name="template_text" rows="4" placeholder="Business plan template"></textarea>
<button class="button is-link is-small" style="margin-top: 0.75rem;" type="submit">Create Profile</button>
</form>
</article>
{% for profile in profiles %}
<article class="box">
<h2 class="title is-6">{{ profile.name }} ({{ profile.slug }})</h2>
<form method="post" style="margin-bottom: 0.75rem;">
<div class="content is-size-7" style="margin-bottom: 0.6rem;">
<p><strong>Flag Definitions</strong></p>
<ul>
<li><strong>enabled</strong>: master on/off switch for this command profile.</li>
<li><strong>reply required</strong>: command only runs when the trigger message is sent as a reply to another message.</li>
<li><strong>exact match</strong>: message text must be exactly the trigger token (for example <code>#bp#</code>) with no extra text.</li>
<li><strong>visibility = status_in_source</strong>: post command status updates back into the source channel.</li>
<li><strong>visibility = silent</strong>: do not post status updates in the source channel.</li>
<li><strong>binding direction ingress</strong>: channels where trigger messages are accepted.</li>
<li><strong>binding direction egress</strong>: channels where command outputs are posted.</li>
<li><strong>binding direction scratchpad_mirror</strong>: scratchpad/mirror channel used for relay-only behavior.</li>
<li><strong>action extract_bp</strong>: run AI extraction to produce business plan content.</li>
<li><strong>action save_document</strong>: save/editable document and revision history.</li>
<li><strong>action post_result</strong>: fan out generated result to enabled egress bindings.</li>
<li><strong>position</strong>: execution order (lower runs first).</li>
</ul>
</div>
<form method="post" style="margin-bottom: 0.75rem;" aria-label="Update command profile {{ profile.name }}">
{% csrf_token %}
<input type="hidden" name="action" value="profile_update">
<input type="hidden" name="profile_id" value="{{ profile.id }}">
<div class="columns is-multiline">
<div class="column is-3">
<label class="label is-size-7">Name</label>
<input class="input is-small" name="name" value="{{ profile.name }}">
<label class="label is-size-7" for="profile_name_{{ profile.id }}">Name</label>
<input id="profile_name_{{ profile.id }}" class="input is-small" name="name" value="{{ profile.name }}">
</div>
<div class="column is-2">
<label class="label is-size-7">Trigger</label>
<input class="input is-small" name="trigger_token" value="{{ profile.trigger_token }}">
<label class="label is-size-7" for="trigger_token_{{ profile.id }}">Trigger</label>
<input id="trigger_token_{{ profile.id }}" class="input is-small" name="trigger_token" value="{{ profile.trigger_token }}">
</div>
<div class="column is-2">
<label class="label is-size-7">Visibility</label>
<label class="label is-size-7" for="visibility_mode_{{ profile.id }}">Visibility</label>
<div class="select is-small is-fullwidth">
<select name="visibility_mode">
<option value="status_in_source" {% if profile.visibility_mode == 'status_in_source' %}selected{% endif %}>status_in_source</option>
<option value="silent" {% if profile.visibility_mode == 'silent' %}selected{% endif %}>silent</option>
<select id="visibility_mode_{{ profile.id }}" name="visibility_mode">
<option value="status_in_source" {% if profile.visibility_mode == 'status_in_source' %}selected{% endif %}>Show Status In Source Chat</option>
<option value="silent" {% if profile.visibility_mode == 'silent' %}selected{% endif %}>Silent (No Status Message)</option>
</select>
</div>
</div>
<div class="column is-5">
<label class="label is-size-7">Flags</label>
<label class="checkbox is-size-7"><input type="checkbox" name="enabled" value="1" {% if profile.enabled %}checked{% endif %}> enabled</label>
<label class="checkbox is-size-7" style="margin-left: 0.6rem;"><input type="checkbox" name="reply_required" value="1" {% if profile.reply_required %}checked{% endif %}> reply required</label>
<label class="checkbox is-size-7" style="margin-left: 0.6rem;"><input type="checkbox" name="exact_match_only" value="1" {% if profile.exact_match_only %}checked{% endif %}> exact match</label>
<fieldset>
<legend class="label is-size-7">Flags</legend>
<label class="checkbox is-size-7"><input type="checkbox" name="enabled" value="1" {% if profile.enabled %}checked{% endif %}> enabled</label>
<label class="checkbox is-size-7" style="margin-left: 0.6rem;"><input type="checkbox" name="reply_required" value="1" {% if profile.reply_required %}checked{% endif %}> reply required</label>
<label class="checkbox is-size-7" style="margin-left: 0.6rem;"><input type="checkbox" name="exact_match_only" value="1" {% if profile.exact_match_only %}checked{% endif %}> exact match</label>
</fieldset>
</div>
</div>
<label class="label is-size-7">BP Template</label>
<textarea class="textarea is-small" name="template_text" rows="5">{{ profile.template_text }}</textarea>
<label class="label is-size-7" for="template_text_{{ profile.id }}">BP Template</label>
<textarea id="template_text_{{ profile.id }}" class="textarea is-small" name="template_text" rows="5">{{ profile.template_text }}</textarea>
<div class="buttons" style="margin-top: 0.6rem;">
<button class="button is-link is-small" type="submit">Save Profile</button>
</div>
@@ -69,18 +94,24 @@
<div class="columns">
<div class="column">
<h3 class="title is-7">Channel Bindings</h3>
<p class="help">A command runs only when the source channel is in <code>ingress</code>. Output is sent to all enabled <code>egress</code> bindings.</p>
<table class="table is-fullwidth is-striped is-size-7">
<thead>
<tr><th>Direction</th><th>Service</th><th>Channel</th><th></th></tr>
<tr><th scope="col">Direction</th><th scope="col">Service</th><th scope="col">Channel</th><th scope="col">Actions</th></tr>
</thead>
<tbody>
{% for binding in profile.channel_bindings.all %}
<tr>
<td>{{ binding.direction }}</td>
<td>
{% if binding.direction == "ingress" %}Ingress (Accept Triggers)
{% elif binding.direction == "egress" %}Egress (Post Results)
{% else %}Scratchpad Mirror
{% endif %}
</td>
<td>{{ binding.service }}</td>
<td>{{ binding.channel_identifier }}</td>
<td>
<form method="post">
<form method="post" aria-label="Delete binding {{ binding.direction }} {{ binding.service }} {{ binding.channel_identifier }}">
{% csrf_token %}
<input type="hidden" name="action" value="binding_delete">
<input type="hidden" name="binding_id" value="{{ binding.id }}">
@@ -93,23 +124,30 @@
{% endfor %}
</tbody>
</table>
<form method="post">
<form method="post" aria-label="Add channel binding for {{ profile.name }}">
{% csrf_token %}
<input type="hidden" name="action" value="binding_create">
<input type="hidden" name="profile_id" value="{{ profile.id }}">
<div class="columns">
<div class="column">
<label class="label is-size-7" for="binding_direction_{{ profile.id }}">Direction</label>
<div class="select is-small is-fullwidth">
<select name="direction">
<select id="binding_direction_{{ profile.id }}" name="direction">
{% for value in directions %}
<option value="{{ value }}">{{ value }}</option>
<option value="{{ value }}">
{% if value == "ingress" %}Ingress (Accept Triggers)
{% elif value == "egress" %}Egress (Post Results)
{% else %}Scratchpad Mirror
{% endif %}
</option>
{% endfor %}
</select>
</div>
</div>
<div class="column">
<label class="label is-size-7" for="binding_service_{{ profile.id }}">Service</label>
<div class="select is-small is-fullwidth">
<select name="service">
<select id="binding_service_{{ profile.id }}" name="service">
{% for value in channel_services %}
<option value="{{ value }}">{{ value }}</option>
{% endfor %}
@@ -117,7 +155,8 @@
</div>
</div>
<div class="column">
<input class="input is-small" name="channel_identifier" placeholder="channel identifier">
<label class="label is-size-7" for="binding_channel_identifier_{{ profile.id }}">Channel Identifier</label>
<input id="binding_channel_identifier_{{ profile.id }}" class="input is-small" name="channel_identifier" placeholder="channel identifier">
</div>
<div class="column is-narrow">
<button class="button is-link is-small" type="submit">Add</button>
@@ -128,23 +167,45 @@
<div class="column">
<h3 class="title is-7">Actions</h3>
<p class="help">Enable/disable each step and set execution order with <code>position</code>.</p>
<table class="table is-fullwidth is-striped is-size-7">
<thead>
<tr><th>Type</th><th>Enabled</th><th>Position</th><th></th></tr>
<tr><th scope="col">Type</th><th scope="col">Enabled</th><th scope="col">Order</th><th scope="col">Actions</th></tr>
</thead>
<tbody>
{% for action_row in profile.actions.all %}
<tr>
<td>{{ action_row.action_type }}</td>
<td>{{ action_row.enabled }}</td>
<td>{{ action_row.position }}</td>
<td>
<form method="post">
{% if action_row.action_type == "extract_bp" %}Extract Business Plan
{% elif action_row.action_type == "save_document" %}Save Document
{% elif action_row.action_type == "post_result" %}Post Result
{% else %}{{ action_row.action_type }}
{% endif %}
</td>
<td>{{ action_row.enabled }}</td>
<td>{{ forloop.counter }}</td>
<td>
<div class="buttons are-small" style="margin-bottom: 0.35rem;">
<form method="post" style="display:inline;" aria-label="Move action {{ action_row.action_type }} up for {{ profile.name }}">
{% csrf_token %}
<input type="hidden" name="action" value="action_move">
<input type="hidden" name="command_action_id" value="{{ action_row.id }}">
<input type="hidden" name="direction" value="up">
<button class="button is-light" type="submit" {% if forloop.first %}disabled{% endif %} aria-label="Move up">Up</button>
</form>
<form method="post" style="display:inline;" aria-label="Move action {{ action_row.action_type }} down for {{ profile.name }}">
{% csrf_token %}
<input type="hidden" name="action" value="action_move">
<input type="hidden" name="command_action_id" value="{{ action_row.id }}">
<input type="hidden" name="direction" value="down">
<button class="button is-light" type="submit" {% if forloop.last %}disabled{% endif %} aria-label="Move down">Down</button>
</form>
</div>
<form method="post" aria-label="Update action {{ action_row.action_type }} for {{ profile.name }}">
{% csrf_token %}
<input type="hidden" name="action" value="action_update">
<input type="hidden" name="command_action_id" value="{{ action_row.id }}">
<label class="checkbox is-size-7"><input type="checkbox" name="enabled" value="1" {% if action_row.enabled %}checked{% endif %}> enabled</label>
<input class="input is-small" style="width: 5rem;" name="position" value="{{ action_row.position }}">
<button class="button is-link is-light is-small" type="submit">Save</button>
</form>
</td>
@@ -157,11 +218,11 @@
</div>
</div>
<form method="post" style="margin-top: 0.75rem;">
<form method="post" style="margin-top: 0.75rem;" aria-label="Delete profile {{ profile.name }}">
{% csrf_token %}
<input type="hidden" name="action" value="profile_delete">
<input type="hidden" name="profile_id" value="{{ profile.id }}">
<button class="button is-danger is-light is-small" type="submit">Delete Profile</button>
<button class="button is-danger is-light is-small" type="submit" aria-label="Delete profile {{ profile.name }}">Delete Profile</button>
</form>
</article>
{% empty %}
@@ -172,7 +233,7 @@
<h2 class="title is-6">Business Plan Documents</h2>
<table class="table is-fullwidth is-striped is-size-7">
<thead>
<tr><th>Title</th><th>Status</th><th>Source</th><th>Updated</th><th></th></tr>
<tr><th scope="col">Title</th><th scope="col">Status</th><th scope="col">Source</th><th scope="col">Updated</th><th scope="col">Actions</th></tr>
</thead>
<tbody>
{% for doc in documents %}
@@ -181,7 +242,7 @@
<td>{{ doc.status }}</td>
<td>{{ doc.source_service }} · {{ doc.source_channel_identifier }}</td>
<td>{{ doc.updated_at }}</td>
<td><a class="button is-small is-link is-light" href="{% url 'business_plan_editor' doc_id=doc.id %}">Open</a></td>
<td><a class="button is-small is-link is-light" href="{% url 'business_plan_editor' doc_id=doc.id %}" aria-label="Open business plan document {{ doc.title }}">Open</a></td>
</tr>
{% empty %}
<tr><td colspan="5">No business plan documents yet.</td></tr>
@@ -190,78 +251,6 @@
</table>
</article>
<article class="box">
<h2 class="title is-6">Translation Bridges</h2>
<form method="post" style="margin-bottom: 0.75rem;">
{% csrf_token %}
<input type="hidden" name="action" value="bridge_create">
<div class="columns is-multiline">
<div class="column is-2"><input class="input is-small" name="name" placeholder="name"></div>
<div class="column is-2"><input class="input is-small" name="quick_mode_title" placeholder="quick mode: en|es"></div>
<div class="column is-2">
<div class="select is-small is-fullwidth"><select name="a_service">{% for value in channel_services %}<option value="{{ value }}">{{ value }}</option>{% endfor %}</select></div>
</div>
<div class="column is-2"><input class="input is-small" name="a_channel_identifier" placeholder="A channel"></div>
<div class="column is-1"><input class="input is-small" name="a_language" value="en"></div>
<div class="column is-2">
<div class="select is-small is-fullwidth"><select name="b_service">{% for value in channel_services %}<option value="{{ value }}">{{ value }}</option>{% endfor %}</select></div>
</div>
<div class="column is-2"><input class="input is-small" name="b_channel_identifier" placeholder="B channel"></div>
<div class="column is-1"><input class="input is-small" name="b_language" value="es"></div>
<div class="column is-2">
<div class="select is-small is-fullwidth"><select name="direction">{% for value in bridge_directions %}<option value="{{ value }}">{{ value }}</option>{% endfor %}</select></div>
</div>
<div class="column is-1"><button class="button is-link is-small" type="submit">Add</button></div>
</div>
</form>
<table class="table is-fullwidth is-striped is-size-7">
<thead>
<tr><th>Name</th><th>A</th><th>B</th><th>Direction</th><th></th></tr>
</thead>
<tbody>
{% for bridge in bridges %}
<tr>
<td>{{ bridge.name }}</td>
<td>{{ bridge.a_service }} · {{ bridge.a_channel_identifier }} · {{ bridge.a_language }}</td>
<td>{{ bridge.b_service }} · {{ bridge.b_channel_identifier }} · {{ bridge.b_language }}</td>
<td>{{ bridge.direction }}</td>
<td>
<form method="post">
{% csrf_token %}
<input type="hidden" name="action" value="bridge_delete">
<input type="hidden" name="bridge_id" value="{{ bridge.id }}">
<button class="button is-danger is-light is-small" type="submit">Delete</button>
</form>
</td>
</tr>
{% empty %}
<tr><td colspan="5">No translation bridges configured.</td></tr>
{% endfor %}
</tbody>
</table>
</article>
<article class="box">
<h2 class="title is-6">Translation Event Log</h2>
<table class="table is-fullwidth is-striped is-size-7">
<thead>
<tr><th>Bridge</th><th>Status</th><th>Target</th><th>Error</th><th>At</th></tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td>{{ event.bridge.name }}</td>
<td>{{ event.status }}</td>
<td>{{ event.target_service }} · {{ event.target_channel }}</td>
<td>{{ event.error|default:"-" }}</td>
<td>{{ event.created_at }}</td>
</tr>
{% empty %}
<tr><td colspan="5">No events yet.</td></tr>
{% endfor %}
</tbody>
</table>
</article>
</div>
</section>
{% endblock %}