| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <pstm-uri>/models</pstm-uri>
- <pstm-template>main</pstm-template>
- </head>
- <body>
- <!-- Goal 41 T8: the model page on the Spry form conventions — the
- readiness line as an alert, the two endpoint groups as cards
- with capped-width fields (.form-rows), labelled controls.
- The form itself is unchanged (same stm-action, same
- write-only key handling); it was never an expander, so no
- dialog is needed — the page IS the editor. -->
- <div class="stack">
- <h2>Model</h2>
- <p class="text-muted">The deployment's model configuration: the OpenAI-compatible endpoint
- every saddle assignment is sent to, and the advisor's optional overrides. Stored
- in the database — environment variables no longer configure it (a pre-page
- deployment's SADDLE_LLM_* environment is imported once, on first read).</p>
- <p stm-if="model == null">Loading…</p>
- <div stm-if="model != null" class="stack">
- <p stm-if="!model.dispatch_ready" class="alert alert-warning"><span class="badge badge-offline">paused</span>
- No base URL is configured — task assignment is paused and
- the advisor is disabled until one is saved.</p>
- <p stm-if="model.dispatch_ready" class="alert alert-info"><span class="badge badge-done">ready</span>
- Updated <span stm-text="model.updated_display">when</span>.</p>
- <form stm-action="model.save" class="stack">
- <section class="card">
- <div class="card-header">
- <h3>Main endpoint</h3>
- <p class="text-muted">Used by every saddle assignment (the harness's LLM).</p>
- </div>
- <div class="card-body form-rows">
- <div class="field"><label for="model-base-url">Base URL</label>
- <input type="text" id="model-base-url" name="base_url" placeholder="http://127.0.0.1:9999/v1"
- stm-attribute.value="model.base_url"></div>
- <div class="field"><label for="model-name">Model</label>
- <input type="text" id="model-name" name="model" placeholder="(the provider's default)"
- stm-attribute.value="model.model"></div>
- <div class="field"><label for="model-api-key">API key</label>
- <input type="password" id="model-api-key" name="api_key" autocomplete="off"
- placeholder="Leave empty to keep the stored key">
- <span class="text-muted" stm-if="model.api_key_set">A key is stored
- (<span stm-text="model.api_key_hint">hint</span>)</span>
- <label class="choice"><input type="checkbox" name="clear_api_key" value="1"> Clear the stored key</label></div>
- </div>
- </section>
- <section class="card">
- <div class="card-header">
- <h3>Advisor endpoint <span class="text-muted">(optional)</span></h3>
- <p class="text-muted">Overrides for the AI Chat advisor. Leave the base URL empty to
- use the main endpoint's fields.</p>
- </div>
- <div class="card-body form-rows">
- <div class="field"><label for="advisor-base-url">Base URL</label>
- <input type="text" id="advisor-base-url" name="advisor_base_url" placeholder="(use the main endpoint)"
- stm-attribute.value="model.advisor_base_url"></div>
- <div class="field"><label for="advisor-model">Model</label>
- <input type="text" id="advisor-model" name="advisor_model" placeholder="(use the main endpoint's model)"
- stm-attribute.value="model.advisor_model"></div>
- <div class="field"><label for="advisor-api-key">API key</label>
- <input type="password" id="advisor-api-key" name="advisor_api_key" autocomplete="off"
- placeholder="Leave empty to keep the stored key">
- <span class="text-muted" stm-if="model.advisor_api_key_set">A key is stored
- (<span stm-text="model.advisor_api_key_hint">hint</span>)</span>
- <label class="choice"><input type="checkbox" name="clear_advisor_api_key" value="1"> Clear the stored key</label></div>
- </div>
- </section>
- <div><button type="submit" class="btn-primary">Save configuration</button></div>
- </form>
- </div>
- </div>
- </body>
- </html>
|