Tau RPC: resolve on agent_end
This commit is contained in:
@@ -4,11 +4,12 @@
|
||||
|
||||
### Highlights
|
||||
- **Thinking directives & state:** `/t|/think|/thinking <level>` (aliases off|minimal|low|medium|high|max/highest). Inline applies to that message; directive-only message pins the level for the session; `/think:off` clears. Resolution: inline > session override > `inbound.reply.thinkingDefault` > off. Pi/Tau get `--thinking <level>` (except off); other agents append cue words (`think` → `think hard` → `think harder` → `ultrathink`). Heartbeat probe uses `HEARTBEAT /think:high`.
|
||||
- **Verbose directives + session hints:** `/v|/verbose on|full|off` mirrors thinking: inline > session > config default. Directive-only replies with an acknowledgement; invalid levels return a hint. When enabled, tool results from JSON-emitting agents (Pi/Tau, etc.) are forwarded as `🛠️ …` messages (now streamed as they happen), and new sessions surface a `🧭 New session: <id>` hint.
|
||||
- **Verbose directives + session hints:** `/v|/verbose on|full|off` mirrors thinking: inline > session > config default. Directive-only replies with an acknowledgement; invalid levels return a hint. When enabled, tool results from JSON-emitting agents (Pi/Tau, etc.) are forwarded as `[🛠️ <tool-name>] …` messages (now streamed as they happen), and new sessions surface a `🧭 New session: <id>` hint.
|
||||
- **Directive confirmations:** Directive-only messages now reply with an acknowledgement (`Thinking level set to high.` / `Thinking disabled.`) and reject unknown levels with a helpful hint (state is unchanged).
|
||||
- **Pi/Tau stability:** RPC replies buffered until the assistant turn finishes; parsers return consistent `texts[]`; web auto-replies keep a warm Tau RPC process to avoid cold starts.
|
||||
- **Claude prompt flow:** One-time `sessionIntro` with per-message `/think:high` bodyPrefix; system prompt always sent on first turn even with `sendSystemOnce`.
|
||||
- **Heartbeat UX:** Backpressure skips reply heartbeats while other commands run; skips don’t refresh session `updatedAt`; web/Twilio heartbeats normalize array payloads and optional `heartbeatCommand`.
|
||||
- **Tau completion signal:** RPC now resolves on Tau’s `agent_end` event so late assistant messages (e.g., camera snap + weather) aren’t truncated.
|
||||
|
||||
### Reliability & UX
|
||||
- Outbound chunking prefers newlines/word boundaries and enforces caps (1600 WhatsApp/Twilio, 4000 web).
|
||||
|
||||
@@ -67,6 +67,25 @@ class TauRpcClient {
|
||||
if (!this.pending) return;
|
||||
this.buffer.push(line);
|
||||
this.pending?.onEvent?.(line);
|
||||
|
||||
// If Tau signals the full prompt/response cycle is finished, resolve immediately.
|
||||
try {
|
||||
const evt = JSON.parse(line) as { type?: string };
|
||||
if (evt?.type === "agent_end") {
|
||||
if (this.idleTimer) clearTimeout(this.idleTimer);
|
||||
const pending = this.pending;
|
||||
this.pending = undefined;
|
||||
const out = this.buffer.join("\n");
|
||||
this.buffer = [];
|
||||
this.seenAssistantEnd = false;
|
||||
clearTimeout(pending.timer);
|
||||
pending.resolve({ stdout: out, stderr: this.stderr, code: 0 });
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// ignore malformed/non-JSON lines
|
||||
}
|
||||
|
||||
// Streamed JSON arrives line-by-line; mark when an assistant message finishes
|
||||
// and resolve after a short idle to capture any follow-up events (e.g. tools)
|
||||
// that belong to the same turn.
|
||||
|
||||
Reference in New Issue
Block a user