diff --git a/gui/main.qml b/gui/main.qml index 31515d8..6dc1984 100644 --- a/gui/main.qml +++ b/gui/main.qml @@ -193,10 +193,12 @@ ApplicationWindow { } Component.onCompleted: { - var log = ollie.readLogForSession(ollie.activeSessionId, ollie.activeAgentId) - if (log) { - chatModel.appendData(log) - chatModel.trimFront(20) + if (ollie.activeAgentId) { + var log = ollie.readLogForSession(ollie.activeSessionId, ollie.activeAgentId) + if (log) { + chatModel.appendData(log) + chatModel.trimFront(20) + } } scrollTimer.start() buildSessionTree() @@ -206,10 +208,12 @@ ApplicationWindow { target: ollie function onActiveSessionIdChanged() { chatModel.reset() - var log = ollie.readLogForSession(ollie.activeSessionId, ollie.activeAgentId) - if (log) { - chatModel.appendData(log) - chatModel.trimFront(20) + if (ollie.activeAgentId) { + var log = ollie.readLogForSession(ollie.activeSessionId, ollie.activeAgentId) + if (log) { + chatModel.appendData(log) + chatModel.trimFront(20) + } } scrollTimer.start() // Expand the active session in the tree @@ -886,8 +890,8 @@ property bool blockExpanded: { TextArea { id: promptInput Layout.fillWidth: true - placeholderText: ollie.activeSessionId ? "Message..." : "No session" - enabled: ollie.activeSessionId !== "" + placeholderText: !ollie.activeSessionId ? "No session" : !ollie.activeAgentId ? "No agent" : "Message..." + enabled: ollie.activeSessionId !== "" && ollie.activeAgentId !== "" wrapMode: TextEdit.Wrap property string _lastText: "" diff --git a/gui/ollie9pclient.cpp b/gui/ollie9pclient.cpp index 24bc0a0..7f98688 100644 --- a/gui/ollie9pclient.cpp +++ b/gui/ollie9pclient.cpp @@ -62,25 +62,26 @@ void Ollie9pClient::setActiveSessionId(const QString &id) } // Discover agent ID BEFORE emitting signals - QByteArray out = run9p({"ls", "session/" + id + "/agent"}); - QString agents = QString::fromUtf8(out).trimmed(); + QStringList agents = getAgents(id); if (!agents.isEmpty()) { - m_agentId = agents.split('\n').first().trimmed(); + m_agentId = agents.first(); + + // Read initial state immediately (state, not statewait) + QByteArray stateOut = run9p({"read", agentPath() + "/state"}); + QString stateStr = QString::fromUtf8(stateOut).trimmed(); + if (!stateStr.isEmpty()) + m_activeState = stateStr; + + emit activeSessionIdChanged(); + emit activeStateChanged(); + + startChatStream(); + startStateStream(); } else { - m_agentId = "0"; + // Empty session — no agent yet + emit activeSessionIdChanged(); + emit activeStateChanged(); } - - // Read initial state immediately (state, not statewait) - QByteArray stateOut = run9p({"read", agentPath() + "/state"}); - QString stateStr = QString::fromUtf8(stateOut).trimmed(); - if (!stateStr.isEmpty()) - m_activeState = stateStr; - - emit activeSessionIdChanged(); - emit activeStateChanged(); - - startChatStream(); - startStateStream(); } void Ollie9pClient::refreshSessions() @@ -126,7 +127,7 @@ QString Ollie9pClient::readLogForSession(const QString &sessionId, const QString bool Ollie9pClient::submit(const QString &prompt) { - if (m_activeSessionId.isEmpty() || prompt.trimmed().isEmpty()) return false; + if (m_activeSessionId.isEmpty() || m_agentId.isEmpty() || prompt.trimmed().isEmpty()) return false; QProcess proc; proc.start(ninepBin(), {"-a", serverAddr(), "write", agentPath() + "/prompt"}); proc.waitForStarted(3000); @@ -138,7 +139,7 @@ bool Ollie9pClient::submit(const QString &prompt) bool Ollie9pClient::interrupt() { - if (m_activeSessionId.isEmpty()) return false; + if (m_activeSessionId.isEmpty() || m_agentId.isEmpty()) return false; QProcess proc; proc.start(ninepBin(), {"-a", serverAddr(), "write", agentPath() + "/ctl"}); proc.waitForStarted(3000); @@ -150,7 +151,7 @@ bool Ollie9pClient::interrupt() bool Ollie9pClient::kill() { - if (m_activeSessionId.isEmpty()) return false; + if (m_activeSessionId.isEmpty() || m_agentId.isEmpty()) return false; QProcess proc; proc.start(ninepBin(), {"-a", serverAddr(), "write", agentPath() + "/ctl"}); proc.waitForStarted(3000); @@ -191,10 +192,15 @@ QStringList Ollie9pClient::getAgents(const QString &sessionId) if (sessionId.isEmpty()) return {}; QByteArray out = run9p({"ls", "session/" + sessionId + "/agent"}); QString raw = QString::fromUtf8(out).trimmed(); - if (raw.isEmpty()) return {"0"}; // default fallback - QStringList agents = raw.split('\n', Qt::SkipEmptyParts); - for (int i = 0; i < agents.size(); ++i) - agents[i] = agents[i].trimmed(); + if (raw.isEmpty()) return {}; + QStringList all = raw.split('\n', Qt::SkipEmptyParts); + QStringList agents; + for (const QString &a : all) { + QString name = a.trimmed(); + // "new" is the agent creation file, not an actual agent + if (name != "new") + agents.append(name); + } return agents; } @@ -425,6 +431,7 @@ void Ollie9pClient::ensureRootDataLoaded() void Ollie9pClient::startChatStream() { if (m_chatProc) return; + if (m_activeSessionId.isEmpty() || m_agentId.isEmpty()) return; m_chatProc = new QProcess(this); connect(m_chatProc, &QProcess::readyReadStandardOutput, this, &Ollie9pClient::onChatReadyRead); connect(m_chatProc, QOverload::of(&QProcess::finished), @@ -437,16 +444,15 @@ void Ollie9pClient::startStateStream() if (m_stateProc) return; // Check if session still exists before starting - if (m_activeSessionId.isEmpty()) return; + if (m_activeSessionId.isEmpty() || m_agentId.isEmpty()) return; // Re-discover agent ID — directory may have been renamed - QByteArray out = run9p({"ls", "session/" + m_activeSessionId + "/agent"}); - QString agents = QString::fromUtf8(out).trimmed(); + QStringList agents = getAgents(m_activeSessionId); if (agents.isEmpty()) { // Session or agent directory gone — don't start return; } - QString newId = agents.split('\n').first().trimmed(); + QString newId = agents.first(); if (newId != m_agentId) { m_agentId = newId; emit activeAgentIdChanged();