fix: the window's approval switch never reached the engine
needs_confirm() (src/agent_loop.c) decides whether a tool asks by reading cfg->confirm_shell / confirm_write / confirm_net; the approval mode only relaxes those. The CLI fills them in (main.c: parse_confirm), the TUI and the WebUI do too -- the Qt window never did: AgentCore::open() memset the whole config and cst_agent_create() keeps what it is given, so every tool ran without asking while the sidebar said "ask". That is why nothing was ever asked on the phone (or on a desktop). - AgentCore: one mapping, applyApproval(), used by open() and setApproval(); the mode is remembered like the TUI's /approval and read back on start (else "ask", the only mode where the window's consent dialog is reached). - --uitest: two checks that the mode reaches the engine as those flags. Version 0.9.7 (local).
This commit is contained in:
@@ -45,6 +45,24 @@ class Turn : public QThread {
|
||||
QByteArray m_prompt;
|
||||
};
|
||||
|
||||
/* The engine asks for a tool only when its own confirm_shell / confirm_write /
|
||||
* confirm_net flag says so (`needs_confirm()`, src/agent_loop.c) -- the
|
||||
* approval mode on top of that only *relaxes* them (AUTO writes a file
|
||||
* without asking, YOLO everything). The CLI fills those three in
|
||||
* (src/main.c: parse_confirm), the TUI and the WebUI do too; the window never
|
||||
* did: AgentCore::open() zeroed the whole config and cst_agent_create() keeps
|
||||
* what it is given, so every tool ran without asking while the sidebar said
|
||||
* "ask". One mapping, used by both open() and setApproval(). */
|
||||
namespace {
|
||||
void applyApproval(cst_agent_config_t *cfg, int approval) {
|
||||
const int ask = (approval == CST_APPROVAL_ASK);
|
||||
cfg->approval = approval;
|
||||
cfg->confirm_shell = ask;
|
||||
cfg->confirm_write = ask;
|
||||
cfg->confirm_net = ask;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/* --- lifetime ------------------------------------------------------------ */
|
||||
|
||||
AgentCore::AgentCore(QObject *parent) : QObject(parent) {
|
||||
@@ -141,6 +159,14 @@ bool AgentCore::open(const QString &workspace, const QString &provider,
|
||||
/* The GUI answers itself: never let the engine decide behind its back. */
|
||||
m_cfg.auto_approve = 0;
|
||||
m_cfg.headless = 0;
|
||||
/* What the person chose last -- the CLI and the TUI remember it the same
|
||||
* way and the TUI writes the same file -- else "ask", which is what the
|
||||
* window's default label promises and the only mode where its consent
|
||||
* dialog is ever reached. */
|
||||
int approval = CST_APPROVAL_ASK;
|
||||
if (have_settings && st.approval[0])
|
||||
cst_approval_parse(st.approval, &approval);
|
||||
applyApproval(&m_cfg, approval);
|
||||
if (!m_cfg.mode[0])
|
||||
snprintf(m_cfg.mode, sizeof(m_cfg.mode), "%s", CST_DEFAULT_MODE);
|
||||
m_agent = cst_agent_create(&m_cfg);
|
||||
@@ -395,9 +421,12 @@ void AgentCore::setMode(const QString &mode) {
|
||||
}
|
||||
|
||||
void AgentCore::setApproval(int approval) {
|
||||
m_cfg.approval = approval;
|
||||
applyApproval(&m_cfg, approval);
|
||||
if (m_agent)
|
||||
cst_agent_config_mut(m_agent)->approval = approval;
|
||||
applyApproval(cst_agent_config_mut(m_agent), approval);
|
||||
/* Remembered like the TUI's /approval: the next start of the window (or of
|
||||
* the CLI) comes up the way it was left. */
|
||||
cst_settings_remember_approval(approval);
|
||||
emit approvalChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -416,6 +416,25 @@ int runUiTest(AgentCore &core, const QString &size) {
|
||||
QStringLiteral("and the line is where the card is"));
|
||||
}
|
||||
|
||||
/* The approval switch is not decoration: the engine asks for a tool only
|
||||
* when its own confirm_* flags say so (needs_confirm() in agent_loop.c),
|
||||
* and every front end that has a consent dialog has to set them -- the
|
||||
* window used to leave all three at zero, which is why "ask" never asked. */
|
||||
{
|
||||
const int was = core.approval();
|
||||
core.setApproval(CST_APPROVAL_ASK);
|
||||
const cst_agent_config_t *live = cst_agent_config(core.agent());
|
||||
check(live && live->approval == CST_APPROVAL_ASK && live->confirm_shell &&
|
||||
live->confirm_write && live->confirm_net,
|
||||
QStringLiteral("'ask' reaches the engine as the three confirm flags"));
|
||||
core.setApproval(CST_APPROVAL_YOLO);
|
||||
live = cst_agent_config(core.agent());
|
||||
check(live && live->approval == CST_APPROVAL_YOLO && !live->confirm_shell &&
|
||||
!live->confirm_write && !live->confirm_net,
|
||||
QStringLiteral("and 'yolo' takes them all away"));
|
||||
core.setApproval(was); /* leave the machine as it was found */
|
||||
}
|
||||
|
||||
/* --- md_to_pdf: the front end's own document writer ------------------- */
|
||||
{
|
||||
const cst_tool_def_t *def = cst_tool_find("md_to_pdf");
|
||||
|
||||
Reference in New Issue
Block a user