feat(gui): handle empty sessions in ollie-gui
- getAgents(): filter out 'new' (agent creation file), return empty list - setActiveSessionId(): skip agent init when no agents exist - submit/interrupt/kill/streams: guard against empty m_agentId - prompt input: disable when no agent, show 'No agent' placeholder
This commit is contained in:
parent
c4d6f2a1b9
commit
6fcef9f60c
24
gui/main.qml
24
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: ""
|
||||
|
|
|
|||
|
|
@ -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<int, QProcess::ExitStatus>::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();
|
||||
|
|
|
|||
Reference in New Issue