File size: 2,390 Bytes
253e783
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import type { NodeInvokeRequestPayload } from "./invoke-types.js";

const MAX_INVOKE_INPUT_BYTES = 16 * 1024;

export function coerceNodeInvokePayload(payload: unknown): NodeInvokeRequestPayload | null {
  if (!payload || typeof payload !== "object") {
    return null;
  }
  const obj = payload as Record<string, unknown>;
  const id = typeof obj.id === "string" ? obj.id.trim() : "";
  const nodeId = typeof obj.nodeId === "string" ? obj.nodeId.trim() : "";
  const command = typeof obj.command === "string" ? obj.command.trim() : "";
  if (!id || !nodeId || !command) {
    return null;
  }
  const paramsJSON =
    typeof obj.paramsJSON === "string"
      ? obj.paramsJSON
      : obj.params !== undefined
        ? JSON.stringify(obj.params)
        : null;
  const timeoutMs = typeof obj.timeoutMs === "number" ? obj.timeoutMs : null;
  const idempotencyKey = typeof obj.idempotencyKey === "string" ? obj.idempotencyKey : null;
  const sessionKey = normalizeOptionalString(obj.sessionKey);
  return {
    id,
    nodeId,
    command,
    paramsJSON,
    timeoutMs,
    idempotencyKey,
    ...(sessionKey ? { sessionKey } : {}),
  };
}

export function coerceNodeInvokeCancelPayload(
  payload: unknown,
): { invokeId: string; nodeId: string } | null {
  const value =
    payload && typeof payload === "object" && !Array.isArray(payload)
      ? (payload as Record<string, unknown>)
      : null;
  return value && typeof value.invokeId === "string" && typeof value.nodeId === "string"
    ? { invokeId: value.invokeId, nodeId: value.nodeId }
    : null;
}

export function coerceNodeInvokeInputPayload(
  payload: unknown,
): { invokeId: string; nodeId: string; seq: number; payloadJSON: string } | null {
  const value =
    payload && typeof payload === "object" && !Array.isArray(payload)
      ? (payload as Record<string, unknown>)
      : null;
  if (
    !value ||
    typeof value.id !== "string" ||
    typeof value.nodeId !== "string" ||
    !Number.isInteger(value.seq) ||
    (value.seq as number) < 0 ||
    typeof value.payloadJSON !== "string" ||
    Buffer.byteLength(value.payloadJSON, "utf8") > MAX_INVOKE_INPUT_BYTES
  ) {
    return null;
  }
  return {
    invokeId: value.id,
    nodeId: value.nodeId,
    seq: value.seq as number,
    payloadJSON: value.payloadJSON,
  };
}