fix: wire terminal events through V2 listener [LET-7999] (#1430)
Co-authored-by: Letta Code <noreply@letta.com>
This commit is contained in:
@@ -357,11 +357,40 @@ export interface SyncCommand {
|
||||
runtime: RuntimeScope;
|
||||
}
|
||||
|
||||
export interface TerminalSpawnCommand {
|
||||
type: "terminal_spawn";
|
||||
terminal_id: string;
|
||||
cols: number;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
export interface TerminalInputCommand {
|
||||
type: "terminal_input";
|
||||
terminal_id: string;
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface TerminalResizeCommand {
|
||||
type: "terminal_resize";
|
||||
terminal_id: string;
|
||||
cols: number;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
export interface TerminalKillCommand {
|
||||
type: "terminal_kill";
|
||||
terminal_id: string;
|
||||
}
|
||||
|
||||
export type WsProtocolCommand =
|
||||
| InputCommand
|
||||
| ChangeDeviceStateCommand
|
||||
| AbortMessageCommand
|
||||
| SyncCommand;
|
||||
| SyncCommand
|
||||
| TerminalSpawnCommand
|
||||
| TerminalInputCommand
|
||||
| TerminalResizeCommand
|
||||
| TerminalKillCommand;
|
||||
|
||||
export type WsProtocolMessage =
|
||||
| DeviceStatusUpdateMessage
|
||||
|
||||
@@ -17,7 +17,13 @@ import { settingsManager } from "../../settings-manager";
|
||||
import { loadTools } from "../../tools/manager";
|
||||
import type { ApprovalResponseBody } from "../../types/protocol_v2";
|
||||
import { isDebugEnabled } from "../../utils/debug";
|
||||
import { killAllTerminals } from "../terminalHandler";
|
||||
import {
|
||||
handleTerminalInput,
|
||||
handleTerminalKill,
|
||||
handleTerminalResize,
|
||||
handleTerminalSpawn,
|
||||
killAllTerminals,
|
||||
} from "../terminalHandler";
|
||||
import {
|
||||
clearPendingApprovalBatchIds,
|
||||
rejectPendingApprovalResolvers,
|
||||
@@ -917,6 +923,27 @@ async function connectWithRetry(
|
||||
scheduleQueuePump(scopedRuntime, socket, opts, processQueuedTurn);
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Terminal commands (no runtime scope required) ──────────────────
|
||||
if (parsed.type === "terminal_spawn") {
|
||||
handleTerminalSpawn(parsed, socket, runtime.bootWorkingDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parsed.type === "terminal_input") {
|
||||
handleTerminalInput(parsed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parsed.type === "terminal_resize") {
|
||||
handleTerminalResize(parsed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parsed.type === "terminal_kill") {
|
||||
handleTerminalKill(parsed);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("close", (code: number, reason: Buffer) => {
|
||||
|
||||
@@ -5,6 +5,10 @@ import type {
|
||||
InputCommand,
|
||||
RuntimeScope,
|
||||
SyncCommand,
|
||||
TerminalInputCommand,
|
||||
TerminalKillCommand,
|
||||
TerminalResizeCommand,
|
||||
TerminalSpawnCommand,
|
||||
WsProtocolCommand,
|
||||
} from "../../types/protocol_v2";
|
||||
import { isValidApprovalResponseBody } from "./approval";
|
||||
@@ -186,6 +190,56 @@ function isSyncCommand(value: unknown): value is SyncCommand {
|
||||
return candidate.type === "sync" && isRuntimeScope(candidate.runtime);
|
||||
}
|
||||
|
||||
function isTerminalSpawnCommand(value: unknown): value is TerminalSpawnCommand {
|
||||
if (!value || typeof value !== "object") return false;
|
||||
const c = value as {
|
||||
type?: unknown;
|
||||
terminal_id?: unknown;
|
||||
cols?: unknown;
|
||||
rows?: unknown;
|
||||
};
|
||||
return (
|
||||
c.type === "terminal_spawn" &&
|
||||
typeof c.terminal_id === "string" &&
|
||||
typeof c.cols === "number" &&
|
||||
typeof c.rows === "number"
|
||||
);
|
||||
}
|
||||
|
||||
function isTerminalInputCommand(value: unknown): value is TerminalInputCommand {
|
||||
if (!value || typeof value !== "object") return false;
|
||||
const c = value as { type?: unknown; terminal_id?: unknown; data?: unknown };
|
||||
return (
|
||||
c.type === "terminal_input" &&
|
||||
typeof c.terminal_id === "string" &&
|
||||
typeof c.data === "string"
|
||||
);
|
||||
}
|
||||
|
||||
function isTerminalResizeCommand(
|
||||
value: unknown,
|
||||
): value is TerminalResizeCommand {
|
||||
if (!value || typeof value !== "object") return false;
|
||||
const c = value as {
|
||||
type?: unknown;
|
||||
terminal_id?: unknown;
|
||||
cols?: unknown;
|
||||
rows?: unknown;
|
||||
};
|
||||
return (
|
||||
c.type === "terminal_resize" &&
|
||||
typeof c.terminal_id === "string" &&
|
||||
typeof c.cols === "number" &&
|
||||
typeof c.rows === "number"
|
||||
);
|
||||
}
|
||||
|
||||
function isTerminalKillCommand(value: unknown): value is TerminalKillCommand {
|
||||
if (!value || typeof value !== "object") return false;
|
||||
const c = value as { type?: unknown; terminal_id?: unknown };
|
||||
return c.type === "terminal_kill" && typeof c.terminal_id === "string";
|
||||
}
|
||||
|
||||
export function parseServerMessage(
|
||||
data: WebSocket.RawData,
|
||||
): ParsedServerMessage | null {
|
||||
@@ -196,7 +250,11 @@ export function parseServerMessage(
|
||||
isInputCommand(parsed) ||
|
||||
isChangeDeviceStateCommand(parsed) ||
|
||||
isAbortMessageCommand(parsed) ||
|
||||
isSyncCommand(parsed)
|
||||
isSyncCommand(parsed) ||
|
||||
isTerminalSpawnCommand(parsed) ||
|
||||
isTerminalInputCommand(parsed) ||
|
||||
isTerminalResizeCommand(parsed) ||
|
||||
isTerminalKillCommand(parsed)
|
||||
) {
|
||||
return parsed as WsProtocolCommand;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user