Release v0.7.28

- Add message queuing with configurable modes (one-at-a-time/all) (#15)
- Add /queue command to select queue mode
- Add TruncatedText component for proper viewport-aware text truncation
- Queue mode setting persists in ~/.pi/agent/settings.json
- Visual feedback for queued messages with proper ANSI handling
- Press Escape to abort and restore queued messages to editor
This commit is contained in:
Mario Zechner 2025-11-20 20:39:43 +01:00
parent e694d435fd
commit d44073b140
18 changed files with 477 additions and 108 deletions

View file

@ -55,6 +55,8 @@ export interface AgentOptions {
transport: AgentTransport;
// Transform app messages to LLM-compatible messages before sending to transport
messageTransformer?: (messages: AppMessage[]) => Message[] | Promise<Message[]>;
// Queue mode: "all" = send all queued messages at once, "one-at-a-time" = send one queued message per turn
queueMode?: "all" | "one-at-a-time";
}
export class Agent {
@ -74,11 +76,13 @@ export class Agent {
private transport: AgentTransport;
private messageTransformer: (messages: AppMessage[]) => Message[] | Promise<Message[]>;
private messageQueue: Array<QueuedMessage<AppMessage>> = [];
private queueMode: "all" | "one-at-a-time";
constructor(opts: AgentOptions) {
this._state = { ...this._state, ...opts.initialState };
this.transport = opts.transport;
this.messageTransformer = opts.messageTransformer || defaultMessageTransformer;
this.queueMode = opts.queueMode || "one-at-a-time";
}
get state(): AgentState {
@ -103,6 +107,14 @@ export class Agent {
this._state.thinkingLevel = l;
}
setQueueMode(mode: "all" | "one-at-a-time") {
this.queueMode = mode;
}
getQueueMode(): "all" | "one-at-a-time" {
return this.queueMode;
}
setTools(t: typeof this._state.tools) {
this._state.tools = t;
}
@ -124,6 +136,10 @@ export class Agent {
});
}
clearMessageQueue() {
this.messageQueue = [];
}
clearMessages() {
this._state.messages = [];
}
@ -179,10 +195,21 @@ export class Agent {
model,
reasoning,
getQueuedMessages: async <T>() => {
// Return queued messages (they'll be added to state via message_end event)
const queued = this.messageQueue.slice();
this.messageQueue = [];
return queued as QueuedMessage<T>[];
// Return queued messages based on queue mode
if (this.queueMode === "one-at-a-time") {
// Return only first message
if (this.messageQueue.length > 0) {
const first = this.messageQueue[0];
this.messageQueue = this.messageQueue.slice(1);
return [first] as QueuedMessage<T>[];
}
return [];
} else {
// Return all queued messages at once
const queued = this.messageQueue.slice();
this.messageQueue = [];
return queued as QueuedMessage<T>[];
}
},
};