fix(gui): improve multi-agent-per-session handling
Session selection now auto-selects first agent: - Clicking a session row selects its first agent (not just the session) - Auto-select at startup now picks first agent of first session - Fixes issue where clicking session would clear agent and show empty chat Improved UI feedback: - Header shows 'Session / Agent' name instead of just state - State indicator gray when no agent selected - Placeholder message when no agent selected: 'Select an agent to view chat' - Chat ListView hidden when no agent (shows placeholder instead) - Input already disabled with 'No agent' placeholder (existing behavior) Cleanup: - Remove dead declaration reconcileAgentConnections(const QVariantList&)
This commit is contained in:
parent
28de16dbf1
commit
414143955f
63
gui/main.qml
63
gui/main.qml
|
|
@ -627,7 +627,22 @@ ApplicationWindow {
|
|||
}
|
||||
if (renamingIndex >= 0) return
|
||||
if (type === "session") {
|
||||
ollie.setActiveSessionId(id)
|
||||
// Find first agent in this session and select it
|
||||
var foundAgent = null
|
||||
for (var i = 0; i < sessionTreeModel.count; ++i) {
|
||||
var item = sessionTreeModel.get(i)
|
||||
if (item.type === "agent" && item.parentId === id) {
|
||||
foundAgent = item
|
||||
break
|
||||
}
|
||||
}
|
||||
if (foundAgent) {
|
||||
// Select the first agent
|
||||
activateAgent(id, foundAgent.agentId)
|
||||
} else {
|
||||
// No agents - just select session (clears agent)
|
||||
ollie.setActiveSessionId(id)
|
||||
}
|
||||
toggleExpand(parent.modelIndex)
|
||||
} else if (type === "agent") {
|
||||
activateAgent(parentId, agentId)
|
||||
|
|
@ -773,15 +788,44 @@ ApplicationWindow {
|
|||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
// Header
|
||||
// Header - shows active session/agent and state
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 6
|
||||
spacing: 8
|
||||
|
||||
// Active session/agent label
|
||||
Label {
|
||||
text: {
|
||||
var sessionName = ""
|
||||
var agentName = ""
|
||||
for (var i = 0; i < sessionTreeModel.count; ++i) {
|
||||
var item = sessionTreeModel.get(i)
|
||||
if (item.type === "session" && item.id === ollie.activeSessionId) {
|
||||
sessionName = item.displayName || item.id
|
||||
}
|
||||
if (item.type === "agent" && item.agentId === ollie.activeAgentId && item.parentId === ollie.activeSessionId) {
|
||||
agentName = item.displayName || item.agentId
|
||||
}
|
||||
}
|
||||
if (sessionName && agentName) {
|
||||
return sessionName + " / " + agentName
|
||||
} else if (sessionName) {
|
||||
return sessionName + " (no agent)"
|
||||
}
|
||||
return "(no session)"
|
||||
}
|
||||
font.bold: true
|
||||
font.pointSize: theme.fontSize > 0 ? theme.fontSize : Qt.application.font.pointSize
|
||||
elide: Text.ElideMiddle
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
// State indicator
|
||||
Rectangle {
|
||||
width: 10; height: 10; radius: 5
|
||||
color: {
|
||||
if (!ollie.activeAgentId) return "#9e9e9e" // gray when no agent
|
||||
if (ollie.activeState === "idle") return "#4caf50"
|
||||
if (ollie.activeState.startsWith("calling")) return "#ff9800"
|
||||
return "#2196f3"
|
||||
|
|
@ -789,12 +833,10 @@ ApplicationWindow {
|
|||
}
|
||||
|
||||
Label {
|
||||
text: ollie.activeState
|
||||
text: ollie.activeAgentId ? ollie.activeState : ""
|
||||
opacity: 0.7
|
||||
font.pointSize: theme.fontSize > 0 ? theme.fontSize * 0.85 : 11
|
||||
}
|
||||
|
||||
Item { Layout.fillWidth: true }
|
||||
}
|
||||
|
||||
Rectangle { Layout.fillWidth: true; height: 1; color: theme.midColor }
|
||||
|
|
@ -805,6 +847,16 @@ ApplicationWindow {
|
|||
Layout.fillHeight: true
|
||||
clip: true
|
||||
|
||||
// Placeholder when no agent selected
|
||||
Label {
|
||||
anchors.centerIn: parent
|
||||
text: ollie.activeSessionId ? "Select an agent to view chat" : "Select a session"
|
||||
color: theme.midColor
|
||||
font.italic: true
|
||||
font.pixelSize: theme.fontSize > 0 ? theme.fontSize : 12
|
||||
visible: !ollie.activeAgentId
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: chatView
|
||||
model: chatModel
|
||||
|
|
@ -812,6 +864,7 @@ ApplicationWindow {
|
|||
anchors.fill: parent
|
||||
anchors.margins: 4
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
visible: ollie.activeAgentId !== ""
|
||||
|
||||
onCountChanged: {
|
||||
if (count > 0)
|
||||
|
|
|
|||
|
|
@ -330,9 +330,19 @@ void Ollie9pClient::refreshSessions()
|
|||
reconcileAgentConnections();
|
||||
emit sessionsChanged();
|
||||
|
||||
// Auto-select first session if none active
|
||||
// Auto-select first session and its first agent if none active
|
||||
if (m_activeSessionId.isEmpty() && !m_sessions.isEmpty()) {
|
||||
setActiveSessionId(m_sessions.first().toMap()["id"].toString());
|
||||
const QVariantMap firstSession = m_sessions.first().toMap();
|
||||
const QString sid = firstSession.value("id").toString();
|
||||
const QVariantList agents = firstSession.value("agents").toList();
|
||||
if (!agents.isEmpty()) {
|
||||
// Select first agent of first session
|
||||
const QString aid = agents.first().toMap().value("id").toString();
|
||||
switchAgent(sid, aid);
|
||||
} else {
|
||||
// No agents - just select the session
|
||||
setActiveSessionId(sid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ public:
|
|||
};
|
||||
|
||||
QList<AgentRecord> readAgentRecords(const QString &sessionId);
|
||||
void reconcileAgentConnections(const QVariantList &sessions);
|
||||
void setAgentConnected(const QString &key, bool connected);
|
||||
QString agentKey(const QString &sessionId, const QString &agentId) const;
|
||||
Q_INVOKABLE void setActiveAgentId(const QString &agentId);
|
||||
|
|
|
|||
Reference in New Issue