gui: show bypass banner per-agent, not globally

- Changed event topic: session.{sid}.agent.{aid}.bypass.request
- Added agentId parameter to bypassRequested signal
- Filter bypass events to show only for the active agent
This commit is contained in:
Levi Neely 2026-10-06 14:32:30 +02:00
parent 59d07d3b4a
commit 6dc9ffe3b1
4 changed files with 29 additions and 21 deletions

View File

@ -262,7 +262,12 @@ func (s *Session) SetBypassPending(req *protocol.BypassRequest, dialFn func() *t
// Publish event for GUI listeners (escape newlines in cmd for single-line event format)
cmd := strings.ReplaceAll(req.Cmd, "\n", "\\n")
PublishEvent("session."+s.ID+".bypass.request", req.ID+"\t"+cmd+"\t"+req.Cwd)
agentID := req.Env["OLLIE_UNAME"]
if agentID == "" {
agentID = "unknown"
}
// Event topic: session.{sid}.agent.{aid}.bypass.request
PublishEvent("session."+s.ID+".agent."+agentID+".bypass.request", req.ID+"\t"+cmd+"\t"+req.Cwd)
}
// BypassPending returns the current pending bypass request, or nil if none.

View File

@ -588,15 +588,18 @@ Connections {
function onActiveAgentIdChanged() {
if (ollie.activeAgentId) chatPane.loadChat()
}
function onBypassRequested(sessionId, id, cmd, cwd) {
// Show bypass request immediately (no session filter - GUI is global)
chatPane.pendingBypass = {
sessionId: sessionId,
id: id,
cmd: cmd,
cwd: cwd
function onBypassRequested(sessionId, agentId, id, cmd, cwd) {
// Show bypass request only for the currently active agent
if (sessionId === ollie.activeSessionId && agentId === ollie.agentId) {
chatPane.pendingBypass = {
sessionId: sessionId,
agentId: agentId,
id: id,
cmd: cmd,
cwd: cwd
}
chatPane.hasPendingBypass = true
}
chatPane.hasPendingBypass = true
}
}

View File

@ -231,15 +231,8 @@ void Ollie9pClient::handleEvent(const QString &eventLine)
}
} else if (agentAction == QLatin1String("new") || agentAction == QLatin1String("kill")) {
refreshSessions();
}
} else {
// Session-level event
if (rest == QLatin1String("pause") || rest == QLatin1String("resume") ||
rest == QLatin1String("new") || rest == QLatin1String("kill") ||
rest == QLatin1String("rename")) {
refreshSessions();
} else if (rest.startsWith(QLatin1String("bypass."))) {
// Bypass event: payload is "id\tcmd\tcwd" (cmd has \n escaped as \\n)
} else if (agentAction.startsWith(QLatin1String("bypass."))) {
// Bypass event from specific agent: payload is "id\tcmd\tcwd" (cmd has \n escaped as \\n)
if (payload.isEmpty()) return;
const int tab1 = payload.indexOf(QLatin1Char('\t'));
if (tab1 < 0) return;
@ -250,7 +243,14 @@ void Ollie9pClient::handleEvent(const QString &eventLine)
QString cmd = payload.mid(tab1 + 1, tab2 - tab1 - 1).toString();
cmd.replace(QLatin1String("\\n"), QLatin1String("\n")); // unescape newlines
const QString cwd = payload.mid(tab2 + 1).toString();
emit bypassRequested(sessionId.toString(), id, cmd, cwd);
emit bypassRequested(sessionId.toString(), agentId.toString(), id, cmd, cwd);
}
} else {
// Session-level event
if (rest == QLatin1String("pause") || rest == QLatin1String("resume") ||
rest == QLatin1String("new") || rest == QLatin1String("kill") ||
rest == QLatin1String("rename")) {
refreshSessions();
}
}
}
@ -842,7 +842,7 @@ void Ollie9pClient::checkPendingBypass()
QString cwd = obj["cwd"].toString();
if (!id.isEmpty() && !cmd.isEmpty()) {
emit bypassRequested(m_activeSessionId, id, cmd, cwd);
emit bypassRequested(m_activeSessionId, m_agentId, id, cmd, cwd);
}
}

View File

@ -100,7 +100,7 @@ signals:
void activeStateChanged();
void agentStateChanged(const QString &sessionId, const QString &agentId, const QString &state);
void chatReceived(const QString &text);
void bypassRequested(const QString &sessionId, const QString &id, const QString &cmd, const QString &cwd);
void bypassRequested(const QString &sessionId, const QString &agentId, const QString &id, const QString &cmd, const QString &cwd);
void rootBackendsLoadedChanged();
void availableBackendsChanged();
void rootAgentsLoadedChanged();