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;
|
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 =
|
export type WsProtocolCommand =
|
||||||
| InputCommand
|
| InputCommand
|
||||||
| ChangeDeviceStateCommand
|
| ChangeDeviceStateCommand
|
||||||
| AbortMessageCommand
|
| AbortMessageCommand
|
||||||
| SyncCommand;
|
| SyncCommand
|
||||||
|
| TerminalSpawnCommand
|
||||||
|
| TerminalInputCommand
|
||||||
|
| TerminalResizeCommand
|
||||||
|
| TerminalKillCommand;
|
||||||
|
|
||||||
export type WsProtocolMessage =
|
export type WsProtocolMessage =
|
||||||
| DeviceStatusUpdateMessage
|
| DeviceStatusUpdateMessage
|
||||||
|
|||||||
@@ -17,7 +17,13 @@ import { settingsManager } from "../../settings-manager";
|
|||||||
import { loadTools } from "../../tools/manager";
|
import { loadTools } from "../../tools/manager";
|
||||||
import type { ApprovalResponseBody } from "../../types/protocol_v2";
|
import type { ApprovalResponseBody } from "../../types/protocol_v2";
|
||||||
import { isDebugEnabled } from "../../utils/debug";
|
import { isDebugEnabled } from "../../utils/debug";
|
||||||
import { killAllTerminals } from "../terminalHandler";
|
import {
|
||||||
|
handleTerminalInput,
|
||||||
|
handleTerminalKill,
|
||||||
|
handleTerminalResize,
|
||||||
|
handleTerminalSpawn,
|
||||||
|
killAllTerminals,
|
||||||
|
} from "../terminalHandler";
|
||||||
import {
|
import {
|
||||||
clearPendingApprovalBatchIds,
|
clearPendingApprovalBatchIds,
|
||||||
rejectPendingApprovalResolvers,
|
rejectPendingApprovalResolvers,
|
||||||
@@ -917,6 +923,27 @@ async function connectWithRetry(
|
|||||||
scheduleQueuePump(scopedRuntime, socket, opts, processQueuedTurn);
|
scheduleQueuePump(scopedRuntime, socket, opts, processQueuedTurn);
|
||||||
return;
|
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) => {
|
socket.on("close", (code: number, reason: Buffer) => {
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import type {
|
|||||||
InputCommand,
|
InputCommand,
|
||||||
RuntimeScope,
|
RuntimeScope,
|
||||||
SyncCommand,
|
SyncCommand,
|
||||||
|
TerminalInputCommand,
|
||||||
|
TerminalKillCommand,
|
||||||
|
TerminalResizeCommand,
|
||||||
|
TerminalSpawnCommand,
|
||||||
WsProtocolCommand,
|
WsProtocolCommand,
|
||||||
} from "../../types/protocol_v2";
|
} from "../../types/protocol_v2";
|
||||||
import { isValidApprovalResponseBody } from "./approval";
|
import { isValidApprovalResponseBody } from "./approval";
|
||||||
@@ -186,6 +190,56 @@ function isSyncCommand(value: unknown): value is SyncCommand {
|
|||||||
return candidate.type === "sync" && isRuntimeScope(candidate.runtime);
|
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(
|
export function parseServerMessage(
|
||||||
data: WebSocket.RawData,
|
data: WebSocket.RawData,
|
||||||
): ParsedServerMessage | null {
|
): ParsedServerMessage | null {
|
||||||
@@ -196,7 +250,11 @@ export function parseServerMessage(
|
|||||||
isInputCommand(parsed) ||
|
isInputCommand(parsed) ||
|
||||||
isChangeDeviceStateCommand(parsed) ||
|
isChangeDeviceStateCommand(parsed) ||
|
||||||
isAbortMessageCommand(parsed) ||
|
isAbortMessageCommand(parsed) ||
|
||||||
isSyncCommand(parsed)
|
isSyncCommand(parsed) ||
|
||||||
|
isTerminalSpawnCommand(parsed) ||
|
||||||
|
isTerminalInputCommand(parsed) ||
|
||||||
|
isTerminalResizeCommand(parsed) ||
|
||||||
|
isTerminalKillCommand(parsed)
|
||||||
) {
|
) {
|
||||||
return parsed as WsProtocolCommand;
|
return parsed as WsProtocolCommand;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user