quickshell: resume agent conversations from server
This commit is contained in:
parent
a2731b418e
commit
6e21c50dcc
9 changed files with 338 additions and 127 deletions
|
|
@ -84,13 +84,21 @@ Singleton {
|
|||
});
|
||||
root.models = map;
|
||||
root.modelList = Object.keys(map);
|
||||
// Restore persisted agent choice if it exists server-side
|
||||
// Restore the selected agent, then derive its latest conversation
|
||||
// from the server. No per-agent conversation map lives in the UI.
|
||||
const persisted = Persistent.states?.ai?.model ?? "";
|
||||
if (persisted.length > 0 && Souveraine.agents[persisted]) {
|
||||
Souveraine.selectAgent(persisted);
|
||||
} else if (Souveraine.currentAgentId.length > 0) {
|
||||
Souveraine.selectAgent(Souveraine.currentAgentId);
|
||||
}
|
||||
}
|
||||
|
||||
function onConversationResumed(agentId, conversationId, messages) {
|
||||
if (agentId !== Souveraine.currentAgentId) return;
|
||||
root.restoreServerConversation(messages);
|
||||
}
|
||||
|
||||
function onServerUnreachable() {
|
||||
root.addMessage(
|
||||
Translation.tr("Souveraine server unreachable at %1\n\nStart it with:\n```bash\nsouveraine server\n```").arg(Souveraine.serverBase),
|
||||
|
|
@ -261,6 +269,38 @@ Singleton {
|
|||
Souveraine.newConversation();
|
||||
}
|
||||
|
||||
// Render the server's canonical transcript after /agent or /resume.
|
||||
// This replaces ii's old local snapshot behaviour: the next send remains
|
||||
// on the same live Souveraine conversation rather than silently forking.
|
||||
function restoreServerConversation(messages) {
|
||||
root.messageIDs = [];
|
||||
root.messageByID = ({});
|
||||
root.streamingMessage = null;
|
||||
root.inThinkBlock = false;
|
||||
root.subconsciousBuffer = "";
|
||||
root.tokenCount.input = -1;
|
||||
root.tokenCount.output = -1;
|
||||
root.tokenCount.total = -1;
|
||||
|
||||
messages.forEach(message => {
|
||||
const content = (message.blocks ?? []).map(block => {
|
||||
switch (block.type) {
|
||||
case "text": return block.text ?? "";
|
||||
case "reasoning": return `<think>\n${block.reasoning ?? ""}\n</think>`;
|
||||
case "tool_use": return `sensor: ${block.name ?? "?"}(${block.input ?? ""})`;
|
||||
case "tool_result": return `[${block.tool_name ?? "tool"}] ${block.output ?? ""}`;
|
||||
case "image": return "[image]";
|
||||
default: return "";
|
||||
}
|
||||
}).filter(Boolean).join("\n");
|
||||
if (content.length === 0) return;
|
||||
const role = message.role === "user"
|
||||
? "user"
|
||||
: message.role === "assistant" ? "assistant" : root.interfaceRole;
|
||||
root.addMessage(content, role);
|
||||
});
|
||||
}
|
||||
|
||||
function sendUserMessage(message) {
|
||||
if (message.length === 0) return;
|
||||
root.addMessage(message, "user");
|
||||
|
|
@ -301,9 +341,18 @@ Singleton {
|
|||
modelId = match;
|
||||
}
|
||||
if (setPersistentState) Persistent.states.ai.model = modelId;
|
||||
Souveraine.selectAgent(modelId);
|
||||
if (!Souveraine.selectAgent(modelId)) {
|
||||
if (feedback) root.addMessage(Translation.tr("Finish or cancel the current turn before switching agents."), root.interfaceRole);
|
||||
return;
|
||||
}
|
||||
root.currentModel = models[modelId];
|
||||
if (feedback) root.addMessage(Translation.tr("Agent set to %1").arg(models[modelId].name), root.interfaceRole);
|
||||
if (feedback) root.addMessage(Translation.tr("Switched to %1 — resuming her latest conversation.").arg(models[modelId].name), root.interfaceRole);
|
||||
}
|
||||
|
||||
function resumeConversation() {
|
||||
if (!Souveraine.resumeLatestConversation()) {
|
||||
root.addMessage(Translation.tr("Finish or cancel the current turn before resuming."), root.interfaceRole);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Souveraine-owned settings: advice instead of local state ────────
|
||||
|
|
|
|||
Loading…
Reference in a new issue