diff --git a/kde/gui/ChatPane.qml b/kde/gui/ChatPane.qml index 87c6332..6f5e413 100644 --- a/kde/gui/ChatPane.qml +++ b/kde/gui/ChatPane.qml @@ -7,12 +7,27 @@ Item { id: chatPane property bool sidebarVisible: true property int maxVisibleBlocks: 80 - property var pendingBypass: null // {sessionId, id, cmd, cwd} - property bool hasPendingBypass: false + // Map of pending bypass requests: id -> {sessionId, agentId, id, cmd, cwd} + property var pendingBypasses: ({}) + property var currentBypass: null // The one currently shown in the banner signal toggleSidebar() // Do not opt the chat pane into focus navigation. activeFocusOnTab: false + // Helper to get the first pending bypass for the active agent + function updateCurrentBypass() { + var activeKey = ollie.activeSessionId + ":" + ollie.activeAgentId + for (var id in pendingBypasses) { + var req = pendingBypasses[id] + var key = req.sessionId + ":" + req.agentId + if (key === activeKey) { + currentBypass = req + return + } + } + currentBypass = null + } + // Expose method to set prompt text (for Edit & Resend) function setPromptText(text) { promptInput.text = text @@ -175,7 +190,7 @@ Item { color: "#fff3e0" // amber light border.color: "#ff9800" border.width: 1 - visible: chatPane.hasPendingBypass + visible: chatPane.currentBypass !== null z: 100 ColumnLayout { @@ -192,7 +207,7 @@ Item { } Label { - text: chatPane.pendingBypass ? chatPane.pendingBypass.cmd : "" + text: chatPane.currentBypass ? chatPane.currentBypass.cmd : "" font.family: "monospace" font.pixelSize: theme.fontSize > 0 ? theme.fontSize : 12 wrapMode: Text.WrapAnywhere @@ -201,10 +216,10 @@ Item { } Label { - text: chatPane.pendingBypass ? "cwd: " + chatPane.pendingBypass.cwd : "" + text: chatPane.currentBypass ? "cwd: " + chatPane.currentBypass.cwd : "" font.pixelSize: theme.fontSize > 0 ? theme.fontSize - 1 : 10 color: "#666" - visible: chatPane.pendingBypass && chatPane.pendingBypass.cwd !== "" + visible: chatPane.currentBypass && chatPane.currentBypass.cwd !== "" } RowLayout { @@ -215,10 +230,8 @@ Item { text: "Approve" highlighted: true onClicked: { - if (chatPane.pendingBypass) { - ollie.resolveBypass(chatPane.pendingBypass.sessionId, chatPane.pendingBypass.agentId, chatPane.pendingBypass.id, true) - chatPane.pendingBypass = null - chatPane.hasPendingBypass = false + if (chatPane.currentBypass) { + ollie.resolveBypass(chatPane.currentBypass.sessionId, chatPane.currentBypass.agentId, chatPane.currentBypass.id, true) } } } @@ -226,10 +239,8 @@ Item { Button { text: "Deny" onClicked: { - if (chatPane.pendingBypass) { - ollie.resolveBypass(chatPane.pendingBypass.sessionId, chatPane.pendingBypass.agentId, chatPane.pendingBypass.id, false) - chatPane.pendingBypass = null - chatPane.hasPendingBypass = false + if (chatPane.currentBypass) { + ollie.resolveBypass(chatPane.currentBypass.sessionId, chatPane.currentBypass.agentId, chatPane.currentBypass.id, false) } } } @@ -580,56 +591,46 @@ Connections { target: ollie function onActiveSessionIdChanged() { if (!ollie.activeAgentId) chatPane.loadChat() - // Hide bypass banner if it's not for the now-active session - if (chatPane.pendingBypass && chatPane.pendingBypass.sessionId !== ollie.activeSessionId) { - chatPane.hasPendingBypass = false - } + // Update current bypass for the new active agent + chatPane.updateCurrentBypass() } function onActiveAgentIdChanged() { if (ollie.activeAgentId) chatPane.loadChat() - // Hide bypass banner if it's not for the now-active agent - if (chatPane.pendingBypass && - (chatPane.pendingBypass.sessionId !== ollie.activeSessionId || - chatPane.pendingBypass.agentId !== ollie.activeAgentId)) { - chatPane.hasPendingBypass = false - } + // Update current bypass for the new active agent + chatPane.updateCurrentBypass() } function onBypassRequested(sessionId, agentId, id, cmd, cwd) { - // Show bypass request only for the currently active agent - if (sessionId === ollie.activeSessionId && agentId === ollie.activeAgentId) { - chatPane.pendingBypass = { - sessionId: sessionId, - agentId: agentId, - id: id, - cmd: cmd, - cwd: cwd - } - chatPane.hasPendingBypass = true + // Add to pending bypasses map + var newMap = chatPane.pendingBypasses + newMap[id] = { + sessionId: sessionId, + agentId: agentId, + id: id, + cmd: cmd, + cwd: cwd } + chatPane.pendingBypasses = newMap + chatPane.updateCurrentBypass() } - function onBypassResolved(sessionId, agentId) { - // Clear bypass banner if it was for this agent (resolved by CLI or another client) - if (chatPane.pendingBypass && - chatPane.pendingBypass.sessionId === sessionId && - chatPane.pendingBypass.agentId === agentId) { - chatPane.pendingBypass = null - chatPane.hasPendingBypass = false + function onBypassResolved(sessionId, agentId, requestId) { + // Remove the specific resolved request from the map + if (chatPane.pendingBypasses[requestId]) { + var newMap = chatPane.pendingBypasses + delete newMap[requestId] + chatPane.pendingBypasses = newMap + chatPane.updateCurrentBypass() } } // Public functions for keyboard shortcuts function approveBypass() { - if (chatPane.pendingBypass) { - ollie.resolveBypass(chatPane.pendingBypass.sessionId, chatPane.pendingBypass.agentId, chatPane.pendingBypass.id, true) - chatPane.pendingBypass = null - chatPane.hasPendingBypass = false + if (chatPane.currentBypass) { + ollie.resolveBypass(chatPane.currentBypass.sessionId, chatPane.currentBypass.agentId, chatPane.currentBypass.id, true) } } function denyBypass() { - if (chatPane.pendingBypass) { - ollie.resolveBypass(chatPane.pendingBypass.sessionId, chatPane.pendingBypass.agentId, chatPane.pendingBypass.id, false) - chatPane.pendingBypass = null - chatPane.hasPendingBypass = false + if (chatPane.currentBypass) { + ollie.resolveBypass(chatPane.currentBypass.sessionId, chatPane.currentBypass.agentId, chatPane.currentBypass.id, false) } } } diff --git a/kde/gui/ollie9pclient.cpp b/kde/gui/ollie9pclient.cpp index ac2e622..6558347 100644 --- a/kde/gui/ollie9pclient.cpp +++ b/kde/gui/ollie9pclient.cpp @@ -280,7 +280,7 @@ void Ollie9pClient::handleEvent(const QString &eventLine) } emit pendingBypassCountChanged(sidStr, aidStr); } - emit bypassResolved(sidStr, aidStr); + emit bypassResolved(sidStr, aidStr, id); } } } else { @@ -895,7 +895,7 @@ bool Ollie9pClient::resolveBypass(const QString &sessionId, const QString &agent m_pendingBypasses.remove(key); } emit pendingBypassCountChanged(sessionId, agentId); - emit bypassResolved(sessionId, agentId); + emit bypassResolved(sessionId, agentId, id); } return true; } diff --git a/kde/gui/ollie9pclient.h b/kde/gui/ollie9pclient.h index 2ad1590..88021cb 100644 --- a/kde/gui/ollie9pclient.h +++ b/kde/gui/ollie9pclient.h @@ -112,7 +112,7 @@ signals: void agentStateChanged(const QString &sessionId, const QString &agentId, const QString &state); void chatReceived(const QString &text); void bypassRequested(const QString &sessionId, const QString &agentId, const QString &id, const QString &cmd, const QString &cwd); - void bypassResolved(const QString &sessionId, const QString &agentId); + void bypassResolved(const QString &sessionId, const QString &agentId, const QString &requestId); void pendingBypassCountChanged(const QString &sessionId, const QString &agentId); void procStarted(const QString &sessionId, const QString &agentId, const QString &payload); void rootBackendsLoadedChanged();