forked from WHC/Hermit
v0.8.10: settings dialog (provider, model, key), window starts on a provider
The window could be started, but it could not be pointed anywhere: a provider,
a model and a key only came in on the command line. The gear in the header now
opens a dialog that changes all three on the engine's live config.
AgentCore (app/src/core/AgentCore.*):
- providers(): the engine's preset table (cst_provider_count/at), with base
URL, the remembered or preset model, whether a key exists and where it comes
from (cst_creds_resolve: "saved", or the environment variable), the preset's
key variable and the source ("built-in" / "user"). A key is read into a local
buffer only to answer "is there one"; it never leaves the C++ side.
- modelChoices(provider): the provider's own list (cst_provider_models), the
fetched cache (cst_ps_cached -- which writes through its out-parameters, so
it takes a real int, not NULL: passing one cost a segfault) and the
remembered pick. No network. modelInfo() is cst_model_info + its "200K ·
text only" label; usage() is cst_agent_usage for the session and the turn.
- useProvider(provider, model, key) -> "" or a reason: a different provider
goes through cst_ps_switch_provider() (the key is verified against /models
before it is saved; offline it is kept unverified and the header says so),
a key for the current one through cst_ps_set_key(), and the model is
remembered in settings.json. syncConfig() takes the engine's config back
over the app's copy, so provider/model/approval read correctly afterwards.
The engine's session is never touched by a switch.
- open() no longer starts with an empty provider: it takes the one the engine
used last (settings.json), else the built-in default, plus that provider's
base URL and model. Without this the first turn could not be sent at all and
no entry in the dialog was "in use".
QML (app/qml/SettingsDialog.qml, Main.qml):
- a modal dialog with the themed surface the other dialogs use (the Basic
style's light panel washes out the dark theme), the provider list with its
key state, a model field with the info label and clickable candidates, a
password field for a new key, the session's token counters, and a note that
reports what the last "Use this" answered.
Tests: 8 more checks -- the presets are readable, an unknown provider is
refused, the counters are readable, the gear opens the panel, the rows exist, a
model typed into the field reaches the engine, the note says so, Close puts the
dialog away. 36 checks pass. --uitest also points XDG_CONFIG_HOME at its
scratch directory now, so a run cannot rewrite the user's settings.json or
credentials, and CST_APP_SHOT writes shot.png at the end plus
shot-settings.png while the dialog is open (that is how the dialog above was
reviewed on a machine without a screen).
Verified: 36/36 UI checks, --selftest, ctest cst-app-selftest, make check rc=0,
and a screenshot of the dialog.
Version 0.8.10.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVariantList>
|
||||
#include <QVariantMap>
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "cst_agent.h"
|
||||
@@ -71,6 +72,26 @@ class AgentCore : public QObject {
|
||||
Q_INVOKABLE bool deleteSession(const QString &id);
|
||||
Q_INVOKABLE bool renameSession(const QString &id, const QString &title);
|
||||
|
||||
/* --- provider, model, key (see cst_provider_switch.h) ------------------- */
|
||||
|
||||
/* The presets: name, base, model (remembered, else the preset's), hasKey
|
||||
* and keyFrom ("saved", else the environment variable), keyEnv, source and
|
||||
* current. Never a key: the engine keeps those out of the UI's reach. */
|
||||
Q_INVOKABLE QVariantList providers() const;
|
||||
/* Model candidates for a provider: its own list, what was fetched into the
|
||||
* cache, and the remembered pick. No network. */
|
||||
Q_INVOKABLE QStringList modelChoices(const QString &provider) const;
|
||||
/* "1M · vision" for the model picker, "" when nothing is known. */
|
||||
Q_INVOKABLE QString modelInfo(const QString &model) const;
|
||||
/* Switch provider, model and key in one call. The engine's own config moves
|
||||
* (its session does not), the choice is remembered, and an empty return
|
||||
* means it worked; anything else is a reason to show. A key is verified
|
||||
* against the provider's /models when one is given. */
|
||||
Q_INVOKABLE QString useProvider(const QString &provider, const QString &model,
|
||||
const QString &key);
|
||||
/* Tokens of this session and of the last turn, plus the cost when priced. */
|
||||
Q_INVOKABLE QVariantMap usage() const;
|
||||
|
||||
/* The engine, for the parts that need it (tool registration). */
|
||||
cst_agent_t *agent() const { return m_agent; }
|
||||
const cst_agent_config_t *config() const { return &m_cfg; }
|
||||
@@ -124,6 +145,9 @@ class AgentCore : public QObject {
|
||||
friend class Turn;
|
||||
void finishTurn(int rc, const QString &err);
|
||||
void setRunning(bool on);
|
||||
/* Take the engine's config over m_cfg again (a switch changed it) and say
|
||||
* so. */
|
||||
void syncConfig();
|
||||
/* Re-read what a session switch changed (id, todo) and say so. */
|
||||
void afterSessionChange();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user