@rethinkingstudio/clawpilot 1.1.15-beta.1 → 1.1.15-internal.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,7 +25,7 @@ import { configExists, readConfig, writeConfig } from "../config/config.js";
25
25
  import { installCommand } from "./install.js";
26
26
  import qrcodeTerminal from "qrcode-terminal";
27
27
  import { t } from "../i18n/index.js";
28
- const DEFAULT_RELAY_SERVER = "https://clawpilot.codeaddict.cn";
28
+ import { DEFAULT_RELAY_SERVER } from "../generated/build-config.js";
29
29
  export async function pairCommand(opts) {
30
30
  const relayServerUrl = opts.server ?? DEFAULT_RELAY_SERVER;
31
31
  const httpBase = relayServerUrl.replace(/^wss?/, "http");
@@ -1 +1 @@
1
- {"version":3,"file":"pair.js","sourceRoot":"","sources":["../../src/commands/pair.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pair.js","sourceRoot":"","sources":["../../src/commands/pair.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_RELAY_SERVER = "https://clawpilot.codeaddict.cn";
@@ -0,0 +1,2 @@
1
+ export const DEFAULT_RELAY_SERVER = "https://clawpilot.codeaddict.cn";
2
+ //# sourceMappingURL=build-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-config.js","sourceRoot":"","sources":["../../src/generated/build-config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,iCAAiC,CAAC"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { runCommand } from "./commands/run.js";
6
6
  import { installCommand, uninstallCommand, stopCommand, restartCommand, resetCommand } from "./commands/install.js";
7
7
  import { statusCommand } from "./commands/status.js";
8
8
  import { setTokenCommand } from "./commands/set-token.js";
9
+ import { DEFAULT_RELAY_SERVER } from "./generated/build-config.js";
9
10
  const require = createRequire(import.meta.url);
10
11
  const { version } = require("../package.json");
11
12
  const program = new Command();
@@ -16,7 +17,7 @@ program
16
17
  program
17
18
  .command("pair")
18
19
  .description("Register with relay server and display QR code for iOS pairing")
19
- .option("-s, --server <url>", "Relay server URL", "https://clawpilot.codeaddict.cn")
20
+ .option("-s, --server <url>", "Relay server URL", DEFAULT_RELAY_SERVER)
20
21
  .option("-n, --name <name>", "Display name for this host")
21
22
  .option("--code-only", "Print only the access code and skip QR code output", false)
22
23
  .action(async (opts) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { type UploadResult } from "./oss-uploader.js";
2
+ export interface MediaBlock {
3
+ mimeType: string;
4
+ /** Buffer content (decoded from base64 or read from local path) */
5
+ data: Buffer;
6
+ }
7
+ export interface AssistantAttachment extends UploadResult {
8
+ width?: number;
9
+ height?: number;
10
+ durationMs?: number;
11
+ }
12
+ type ContentBlock = {
13
+ type: string;
14
+ text?: string;
15
+ source?: {
16
+ type?: string;
17
+ media_type?: string;
18
+ data?: string;
19
+ url?: string;
20
+ path?: string;
21
+ };
22
+ media_type?: string;
23
+ data?: string;
24
+ };
25
+ type HistoryMessage = {
26
+ role: string;
27
+ content?: ContentBlock[] | string;
28
+ };
29
+ export declare function extractMediaBlocks(history: {
30
+ messages?: HistoryMessage[];
31
+ }): MediaBlock[];
32
+ export declare function uploadAssistantAttachments(history: {
33
+ messages?: HistoryMessage[];
34
+ }, relayServerUrl: string, gatewayId: string, relaySecret: string): Promise<AssistantAttachment[]>;
35
+ export {};
@@ -0,0 +1,144 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Extract media (image / video) blocks from an OpenClaw gateway chat history
3
+ // response, and upload them to OSS via STS credentials from the relay server.
4
+ // ---------------------------------------------------------------------------
5
+ import { uploadMedia } from "./oss-uploader.js";
6
+ import { readFile } from "fs/promises";
7
+ // Max video size accepted for upload (200 MB)
8
+ const MAX_VIDEO_BYTES = 200 * 1024 * 1024;
9
+ export function extractMediaBlocks(history) {
10
+ const msgs = history.messages ?? [];
11
+ const last = [...msgs].reverse().find((m) => m.role === "assistant");
12
+ if (!last || !last.content)
13
+ return [];
14
+ const content = typeof last.content === "string" ? [] : last.content;
15
+ const blocks = [];
16
+ for (const block of content) {
17
+ if (block.type !== "image" && block.type !== "video")
18
+ continue;
19
+ const source = block.source;
20
+ const mimeType = source?.media_type ?? block.media_type ?? "image/jpeg";
21
+ // Only handle base64 and local file paths in Phase 1
22
+ if (source?.type === "base64" || (!source?.type && source?.data)) {
23
+ const raw = source?.data ?? block.data ?? "";
24
+ if (!raw)
25
+ continue;
26
+ try {
27
+ const buf = Buffer.from(raw.replace(/^data:[^;]+;base64,/, ""), "base64");
28
+ blocks.push({ mimeType, data: buf });
29
+ }
30
+ catch {
31
+ console.warn("[media] failed to decode base64 block, skipping");
32
+ }
33
+ }
34
+ else if (source?.type === "file" && source.path) {
35
+ // Local file reference — will be read asynchronously below
36
+ blocks.push({ mimeType, data: Buffer.alloc(0), _localPath: source.path });
37
+ }
38
+ // URL type is not handled in Phase 1
39
+ }
40
+ return blocks;
41
+ }
42
+ // ---------------------------------------------------------------------------
43
+ // Load local-path blocks and filter oversized videos
44
+ // ---------------------------------------------------------------------------
45
+ async function resolveLocalPaths(blocks) {
46
+ const resolved = [];
47
+ for (const b of blocks) {
48
+ if (b._localPath) {
49
+ try {
50
+ const buf = await readFile(b._localPath);
51
+ resolved.push({ mimeType: b.mimeType, data: buf });
52
+ }
53
+ catch (err) {
54
+ console.warn(`[media] failed to read local file ${b._localPath}: ${err}`);
55
+ }
56
+ }
57
+ else {
58
+ resolved.push(b);
59
+ }
60
+ }
61
+ return resolved.filter((b) => {
62
+ if (b.mimeType.startsWith("video/") && b.data.length > MAX_VIDEO_BYTES) {
63
+ console.warn(`[media] video too large (${b.data.length} bytes), skipping`);
64
+ return false;
65
+ }
66
+ return b.data.length > 0;
67
+ });
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Fetch STS credentials from the relay server
71
+ // ---------------------------------------------------------------------------
72
+ async function fetchSts(relayServerUrl, gatewayId, relaySecret, mimeTypes, hasVideo) {
73
+ const url = `${relayServerUrl.replace(/\/$/, "")}/api/media/sts`;
74
+ const res = await fetch(url, {
75
+ method: "POST",
76
+ headers: { "Content-Type": "application/json" },
77
+ body: JSON.stringify({
78
+ gatewayId,
79
+ relaySecret,
80
+ count: mimeTypes.length,
81
+ mimeTypes,
82
+ durationSeconds: hasVideo ? 1800 : 600,
83
+ }),
84
+ });
85
+ if (!res.ok) {
86
+ const text = await res.text().catch(() => "");
87
+ throw new Error(`STS fetch failed: ${res.status} ${text}`);
88
+ }
89
+ return res.json();
90
+ }
91
+ // ---------------------------------------------------------------------------
92
+ // Main: extract + upload → return attachments[]
93
+ // ---------------------------------------------------------------------------
94
+ export async function uploadAssistantAttachments(history, relayServerUrl, gatewayId, relaySecret) {
95
+ const rawBlocks = extractMediaBlocks(history);
96
+ if (rawBlocks.length === 0)
97
+ return [];
98
+ const blocks = await resolveLocalPaths(rawBlocks);
99
+ if (blocks.length === 0)
100
+ return [];
101
+ const mimeTypes = blocks.map((b) => b.mimeType);
102
+ const hasVideo = mimeTypes.some((m) => m.startsWith("video/"));
103
+ let sts;
104
+ try {
105
+ sts = await fetchSts(relayServerUrl, gatewayId, relaySecret, mimeTypes, hasVideo);
106
+ }
107
+ catch (err) {
108
+ console.error("[media] failed to fetch STS:", err);
109
+ return [];
110
+ }
111
+ const results = [];
112
+ // Upload images concurrently (max 3), videos serially
113
+ const imageBlocks = blocks.filter((b) => !b.mimeType.startsWith("video/"));
114
+ const videoBlocks = blocks.filter((b) => b.mimeType.startsWith("video/"));
115
+ // Images: up to 3 concurrent
116
+ const imageBatches = [];
117
+ for (let i = 0; i < imageBlocks.length; i += 3) {
118
+ imageBatches.push(imageBlocks.slice(i, i + 3));
119
+ }
120
+ for (const batch of imageBatches) {
121
+ const settled = await Promise.allSettled(batch.map((b) => uploadMedia(sts, b.data, b.mimeType)));
122
+ for (const r of settled) {
123
+ if (r.status === "fulfilled") {
124
+ results.push(r.value);
125
+ }
126
+ else {
127
+ console.warn("[media] image upload failed:", r.reason);
128
+ }
129
+ }
130
+ }
131
+ // Videos: serial
132
+ for (const b of videoBlocks) {
133
+ try {
134
+ const r = await uploadMedia(sts, b.data, b.mimeType);
135
+ results.push(r);
136
+ }
137
+ catch (err) {
138
+ console.warn("[media] video upload failed:", err);
139
+ }
140
+ }
141
+ console.log(`[media] uploaded ${results.length}/${blocks.length} attachments`);
142
+ return results;
143
+ }
144
+ //# sourceMappingURL=assistant-attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-attachments.js","sourceRoot":"","sources":["../../src/media/assistant-attachments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface StsCredentials {
2
+ bucket: string;
3
+ region: string;
4
+ endpoint: string;
5
+ baseUrl: string;
6
+ dirPrefix: string;
7
+ expiresAt: number;
8
+ credentials: {
9
+ accessKeyId: string;
10
+ accessKeySecret: string;
11
+ securityToken: string;
12
+ };
13
+ }
14
+ export interface UploadResult {
15
+ url: string;
16
+ thumbnailUrl?: string;
17
+ mimeType: string;
18
+ size: number;
19
+ }
20
+ export declare function putObject(sts: StsCredentials, data: Buffer, ext: string, mimeType: string): Promise<UploadResult>;
21
+ export declare function multipartUpload(sts: StsCredentials, data: Buffer, ext: string, mimeType: string): Promise<UploadResult>;
22
+ export declare function uploadMedia(sts: StsCredentials, data: Buffer, mimeType: string): Promise<UploadResult>;
@@ -0,0 +1,180 @@
1
+ import { createHmac } from "crypto";
2
+ import { randomUUID } from "crypto";
3
+ // ---------------------------------------------------------------------------
4
+ // OSS HMAC-SHA1 request signing (with STS security token)
5
+ // ---------------------------------------------------------------------------
6
+ function ossSign(method, contentMd5, contentType, date, canonicalizedHeaders, canonicalizedResource, secretKey) {
7
+ const stringToSign = [
8
+ method,
9
+ contentMd5,
10
+ contentType,
11
+ date,
12
+ canonicalizedHeaders + canonicalizedResource,
13
+ ].join("\n");
14
+ return createHmac("sha1", secretKey).update(stringToSign).digest("base64");
15
+ }
16
+ // ---------------------------------------------------------------------------
17
+ // Simple PutObject upload (images / small files)
18
+ // ---------------------------------------------------------------------------
19
+ export async function putObject(sts, data, ext, mimeType) {
20
+ const { bucket, endpoint, baseUrl, dirPrefix, credentials } = sts;
21
+ const objectKey = `${dirPrefix}/${randomUUID()}${ext}`;
22
+ const date = new Date().toUTCString();
23
+ const canonicalizedResource = `/${bucket}/${objectKey}`;
24
+ const canonicalizedHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
25
+ const sig = ossSign("PUT", "", mimeType, date, canonicalizedHeaders, canonicalizedResource, credentials.accessKeySecret);
26
+ const url = `${endpoint.replace(/\/$/, "")}/${objectKey}`;
27
+ const res = await fetch(url, {
28
+ method: "PUT",
29
+ headers: {
30
+ "Content-Type": mimeType,
31
+ "Date": date,
32
+ "x-oss-security-token": credentials.securityToken,
33
+ "Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
34
+ },
35
+ body: data,
36
+ });
37
+ if (!res.ok) {
38
+ const text = await res.text().catch(() => "");
39
+ throw new Error(`OSS PutObject failed: ${res.status} ${text}`);
40
+ }
41
+ const publicUrl = `${baseUrl.replace(/\/$/, "")}/${objectKey}`;
42
+ return { url: publicUrl, mimeType, size: data.length };
43
+ }
44
+ // ---------------------------------------------------------------------------
45
+ // Multipart upload (videos > 10 MB)
46
+ // ---------------------------------------------------------------------------
47
+ const PART_SIZE = 5 * 1024 * 1024; // 5 MB per part
48
+ export async function multipartUpload(sts, data, ext, mimeType) {
49
+ const { bucket, endpoint, baseUrl, dirPrefix, credentials } = sts;
50
+ const objectKey = `${dirPrefix}/${randomUUID()}${ext}`;
51
+ const baseOssUrl = `${endpoint.replace(/\/$/, "")}/${objectKey}`;
52
+ function makeHeaders(method, contentType, extraHeaders, resource) {
53
+ const date = new Date().toUTCString();
54
+ const canonicalizedHeaders = [
55
+ "x-oss-security-token:" + credentials.securityToken,
56
+ ...Object.entries(extraHeaders)
57
+ .filter(([k]) => k.startsWith("x-oss-"))
58
+ .sort()
59
+ .map(([k, v]) => `${k}:${v}`),
60
+ ]
61
+ .sort()
62
+ .join("\n") + "\n";
63
+ const sig = ossSign(method, "", contentType, date, canonicalizedHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret);
64
+ const headers = new Headers({
65
+ "Date": date,
66
+ "x-oss-security-token": credentials.securityToken,
67
+ "Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
68
+ ...extraHeaders,
69
+ });
70
+ if (contentType)
71
+ headers.set("Content-Type", contentType);
72
+ return headers;
73
+ }
74
+ // 1. Initiate
75
+ const initRes = await fetch(`${baseOssUrl}?uploads`, {
76
+ method: "POST",
77
+ headers: makeHeaders("POST", mimeType, {}, `/${bucket}/${objectKey}`),
78
+ });
79
+ if (!initRes.ok)
80
+ throw new Error(`OSS InitiateMultipartUpload failed: ${initRes.status}`);
81
+ const initText = await initRes.text();
82
+ const uploadIdMatch = initText.match(/<UploadId>([^<]+)<\/UploadId>/);
83
+ if (!uploadIdMatch)
84
+ throw new Error("OSS: could not parse UploadId");
85
+ const uploadId = uploadIdMatch[1];
86
+ // 2. Upload parts
87
+ const parts = [];
88
+ let partNumber = 1;
89
+ let offset = 0;
90
+ try {
91
+ while (offset < data.length) {
92
+ const chunk = data.slice(offset, offset + PART_SIZE);
93
+ const partDate = new Date().toUTCString();
94
+ const canonicalizedHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
95
+ const sig = ossSign("PUT", "", "application/octet-stream", partDate, canonicalizedHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret);
96
+ const partRes = await fetch(`${baseOssUrl}?partNumber=${partNumber}&uploadId=${uploadId}`, {
97
+ method: "PUT",
98
+ headers: {
99
+ "Content-Type": "application/octet-stream",
100
+ "Date": partDate,
101
+ "x-oss-security-token": credentials.securityToken,
102
+ "Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
103
+ },
104
+ body: chunk,
105
+ });
106
+ if (!partRes.ok)
107
+ throw new Error(`OSS UploadPart ${partNumber} failed: ${partRes.status}`);
108
+ const etag = partRes.headers.get("etag") ?? "";
109
+ parts.push({ partNumber, etag });
110
+ partNumber++;
111
+ offset += PART_SIZE;
112
+ }
113
+ // 3. Complete
114
+ const completeBody = [
115
+ "<CompleteMultipartUpload>",
116
+ ...parts.map((p) => `<Part><PartNumber>${p.partNumber}</PartNumber><ETag>${p.etag}</ETag></Part>`),
117
+ "</CompleteMultipartUpload>",
118
+ ].join("");
119
+ const completeDate = new Date().toUTCString();
120
+ const cHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
121
+ const cSig = ossSign("POST", "", "application/xml", completeDate, cHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret);
122
+ const completeRes = await fetch(`${baseOssUrl}?uploadId=${uploadId}`, {
123
+ method: "POST",
124
+ headers: {
125
+ "Content-Type": "application/xml",
126
+ "Date": completeDate,
127
+ "x-oss-security-token": credentials.securityToken,
128
+ "Authorization": `OSS ${credentials.accessKeyId}:${cSig}`,
129
+ },
130
+ body: completeBody,
131
+ });
132
+ if (!completeRes.ok)
133
+ throw new Error(`OSS CompleteMultipartUpload failed: ${completeRes.status}`);
134
+ }
135
+ catch (err) {
136
+ // Best-effort abort to avoid billing for incomplete upload
137
+ try {
138
+ const abortDate = new Date().toUTCString();
139
+ const aHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
140
+ const aSig = ossSign("DELETE", "", "", abortDate, aHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret);
141
+ await fetch(`${baseOssUrl}?uploadId=${uploadId}`, {
142
+ method: "DELETE",
143
+ headers: {
144
+ "Date": abortDate,
145
+ "x-oss-security-token": credentials.securityToken,
146
+ "Authorization": `OSS ${credentials.accessKeyId}:${aSig}`,
147
+ },
148
+ });
149
+ }
150
+ catch { /* ignore abort errors */ }
151
+ throw err;
152
+ }
153
+ const publicUrl = `${baseUrl.replace(/\/$/, "")}/${objectKey}`;
154
+ // OSS video snapshot thumbnail URL
155
+ const thumbnailUrl = `${publicUrl}?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast`;
156
+ return { url: publicUrl, thumbnailUrl, mimeType, size: data.length };
157
+ }
158
+ // ---------------------------------------------------------------------------
159
+ // Convenience: auto-select PutObject vs multipart based on size
160
+ // ---------------------------------------------------------------------------
161
+ const MULTIPART_THRESHOLD = 10 * 1024 * 1024; // 10 MB
162
+ export async function uploadMedia(sts, data, mimeType) {
163
+ const ext = mimeTypeToExt(mimeType);
164
+ if (data.length >= MULTIPART_THRESHOLD) {
165
+ return multipartUpload(sts, data, ext, mimeType);
166
+ }
167
+ return putObject(sts, data, ext, mimeType);
168
+ }
169
+ function mimeTypeToExt(mimeType) {
170
+ const map = {
171
+ "image/jpeg": ".jpg",
172
+ "image/png": ".png",
173
+ "image/gif": ".gif",
174
+ "image/webp": ".webp",
175
+ "video/mp4": ".mp4",
176
+ "video/quicktime": ".mov",
177
+ };
178
+ return map[mimeType] ?? ".bin";
179
+ }
180
+ //# sourceMappingURL=oss-uploader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oss-uploader.js","sourceRoot":"","sources":["../../src/media/oss-uploader.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { OpenClawGatewayClient } from "./gateway-client.js";
3
3
  import { handleLocalCommand } from "../commands/local-handlers.js";
4
4
  import { handleProviderCommand } from "../commands/provider-handlers.js";
5
5
  import { getServicePlatform } from "../platform/service-manager.js";
6
+ import { uploadAssistantAttachments } from "../media/assistant-attachments.js";
6
7
  import { homedir } from "os";
7
8
  import { join } from "path";
8
9
  import { mkdir, writeFile } from "fs/promises";
@@ -59,9 +60,8 @@ export async function runRelayManager(opts) {
59
60
  send({ type: "gateway_disconnected", reason });
60
61
  },
61
62
  onEvent: (event, payload) => {
62
- // On chat final, fetch history to get actual content (OpenClaw 2026.3.2+
63
- // no longer includes message content in the chat final event payload).
64
- // This mirrors what the macOS 2026.3.2 client does.
63
+ // On chat final, fetch history to get actual content + extract media attachments.
64
+ // OpenClaw 2026.3.2+ no longer includes message content in chat final payload.
65
65
  if (event === "chat") {
66
66
  const p = payload;
67
67
  if (p?.state === "final" && p?.sessionKey) {
@@ -81,10 +81,22 @@ export async function runRelayManager(opts) {
81
81
  await new Promise((resolve) => setTimeout(resolve, 600));
82
82
  const retryHistory = await fetchHistory();
83
83
  text = extractText(retryHistory);
84
+ history = retryHistory;
84
85
  }
85
86
  if (text) {
86
87
  p.message = { content: [{ type: "text", text }] };
87
88
  }
89
+ // Upload any media blocks found in the history
90
+ try {
91
+ const attachments = await uploadAssistantAttachments(history ?? {}, opts.relayServerUrl, opts.gatewayId, opts.relaySecret);
92
+ if (attachments.length > 0) {
93
+ p.attachments = attachments;
94
+ console.log(`[relay] chat final: injected ${attachments.length} attachment(s) runId=${runId}`);
95
+ }
96
+ }
97
+ catch (mediaErr) {
98
+ console.error(`[relay] media upload error (non-fatal): ${mediaErr}`);
99
+ }
88
100
  console.log(`[relay] chat final (history fetched): runId=${runId} textLength=${text?.length ?? 0}`);
89
101
  send({ type: "event", event, payload });
90
102
  })
@@ -92,7 +104,7 @@ export async function runRelayManager(opts) {
92
104
  console.error(`[relay] chat.history fetch failed: ${err}`);
93
105
  send({ type: "event", event, payload });
94
106
  });
95
- return; // will send after history fetch
107
+ return; // will send after history fetch + media upload
96
108
  }
97
109
  }
98
110
  send({ type: "event", event, payload });
@@ -1 +1 @@
1
- {"version":3,"file":"relay-manager.js","sourceRoot":"","sources":["../../src/relay/relay-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relay-manager.js","sourceRoot":"","sources":["../../src/relay/relay-manager.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@rethinkingstudio/clawpilot",
3
- "version": "1.1.15-beta.1",
3
+ "version": "1.1.15-internal.0",
4
4
  "description": "ClawAI relay client for Mac mini",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "clawpilot": "dist/index.js"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsc",
10
+ "build:config": "node ./scripts/write-build-config.mjs",
11
+ "build": "npm run build:config && tsc",
12
+ "build:prod": "npm run build",
13
+ "build:internal": "CLAWPILOT_DEFAULT_RELAY_SERVER=http://clawpilot-pre.codeaddict.cn npm run build",
11
14
  "dev": "tsx src/index.ts",
12
15
  "start": "node dist/index.js"
13
16
  },
@@ -0,0 +1,17 @@
1
+ import { mkdirSync, writeFileSync } from "fs";
2
+ import { dirname, resolve } from "path";
3
+
4
+ const target = resolve(process.cwd(), "src/generated/build-config.ts");
5
+ const relayServer =
6
+ process.env.CLAWPILOT_DEFAULT_RELAY_SERVER?.trim()
7
+ || "https://clawpilot.codeaddict.cn";
8
+
9
+ mkdirSync(dirname(target), { recursive: true });
10
+
11
+ writeFileSync(
12
+ target,
13
+ `export const DEFAULT_RELAY_SERVER = ${JSON.stringify(relayServer)};\n`,
14
+ "utf8"
15
+ );
16
+
17
+ console.log(`[build-config] DEFAULT_RELAY_SERVER=${relayServer}`);
@@ -26,8 +26,7 @@ import { configExists, readConfig, writeConfig } from "../config/config.js";
26
26
  import { installCommand } from "./install.js";
27
27
  import qrcodeTerminal from "qrcode-terminal";
28
28
  import { t } from "../i18n/index.js";
29
-
30
- const DEFAULT_RELAY_SERVER = "https://clawpilot.codeaddict.cn";
29
+ import { DEFAULT_RELAY_SERVER } from "../generated/build-config.js";
31
30
 
32
31
  interface PairOptions {
33
32
  server?: string;
@@ -0,0 +1 @@
1
+ export const DEFAULT_RELAY_SERVER = "http://clawpilot-pre.codeaddict.cn";
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import { runCommand } from "./commands/run.js";
6
6
  import { installCommand, uninstallCommand, stopCommand, restartCommand, resetCommand } from "./commands/install.js";
7
7
  import { statusCommand } from "./commands/status.js";
8
8
  import { setTokenCommand } from "./commands/set-token.js";
9
+ import { DEFAULT_RELAY_SERVER } from "./generated/build-config.js";
9
10
 
10
11
  const require = createRequire(import.meta.url);
11
12
  const { version } = require("../package.json") as { version: string };
@@ -20,7 +21,7 @@ program
20
21
  program
21
22
  .command("pair")
22
23
  .description("Register with relay server and display QR code for iOS pairing")
23
- .option("-s, --server <url>", "Relay server URL", "https://clawpilot.codeaddict.cn")
24
+ .option("-s, --server <url>", "Relay server URL", DEFAULT_RELAY_SERVER)
24
25
  .option("-n, --name <name>", "Display name for this host")
25
26
  .option("--code-only", "Print only the access code and skip QR code output", false)
26
27
  .action(async (opts: { server: string; name: string; codeOnly?: boolean }) => {
@@ -0,0 +1,205 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Extract media (image / video) blocks from an OpenClaw gateway chat history
3
+ // response, and upload them to OSS via STS credentials from the relay server.
4
+ // ---------------------------------------------------------------------------
5
+
6
+ import { uploadMedia, type StsCredentials, type UploadResult } from "./oss-uploader.js";
7
+ import { readFile } from "fs/promises";
8
+
9
+ // Max video size accepted for upload (200 MB)
10
+ const MAX_VIDEO_BYTES = 200 * 1024 * 1024;
11
+
12
+ export interface MediaBlock {
13
+ mimeType: string;
14
+ /** Buffer content (decoded from base64 or read from local path) */
15
+ data: Buffer;
16
+ }
17
+
18
+ export interface AssistantAttachment extends UploadResult {
19
+ width?: number;
20
+ height?: number;
21
+ durationMs?: number;
22
+ }
23
+
24
+ // ---------------------------------------------------------------------------
25
+ // Extract media blocks from the last assistant message in a history response
26
+ // ---------------------------------------------------------------------------
27
+
28
+ type ContentBlock = {
29
+ type: string;
30
+ text?: string;
31
+ source?: {
32
+ type?: string; // "base64" | "url" | "file" | null
33
+ media_type?: string; // "image/png" etc.
34
+ data?: string; // base64 payload
35
+ url?: string; // external URL (not handled in Phase 1)
36
+ path?: string; // local file path
37
+ };
38
+ // Some gateways embed media_type / data directly on the block
39
+ media_type?: string;
40
+ data?: string;
41
+ };
42
+
43
+ type HistoryMessage = {
44
+ role: string;
45
+ content?: ContentBlock[] | string;
46
+ };
47
+
48
+ export function extractMediaBlocks(history: { messages?: HistoryMessage[] }): MediaBlock[] {
49
+ const msgs = history.messages ?? [];
50
+ const last = [...msgs].reverse().find((m) => m.role === "assistant");
51
+ if (!last || !last.content) return [];
52
+
53
+ const content: ContentBlock[] =
54
+ typeof last.content === "string" ? [] : last.content;
55
+
56
+ const blocks: MediaBlock[] = [];
57
+
58
+ for (const block of content) {
59
+ if (block.type !== "image" && block.type !== "video") continue;
60
+
61
+ const source = block.source;
62
+ const mimeType =
63
+ source?.media_type ?? block.media_type ?? "image/jpeg";
64
+
65
+ // Only handle base64 and local file paths in Phase 1
66
+ if (source?.type === "base64" || (!source?.type && source?.data)) {
67
+ const raw = source?.data ?? block.data ?? "";
68
+ if (!raw) continue;
69
+ try {
70
+ const buf = Buffer.from(raw.replace(/^data:[^;]+;base64,/, ""), "base64");
71
+ blocks.push({ mimeType, data: buf });
72
+ } catch {
73
+ console.warn("[media] failed to decode base64 block, skipping");
74
+ }
75
+ } else if (source?.type === "file" && source.path) {
76
+ // Local file reference — will be read asynchronously below
77
+ blocks.push({ mimeType, data: Buffer.alloc(0), _localPath: source.path } as MediaBlock & { _localPath: string });
78
+ }
79
+ // URL type is not handled in Phase 1
80
+ }
81
+
82
+ return blocks;
83
+ }
84
+
85
+ // ---------------------------------------------------------------------------
86
+ // Load local-path blocks and filter oversized videos
87
+ // ---------------------------------------------------------------------------
88
+
89
+ async function resolveLocalPaths(blocks: (MediaBlock & { _localPath?: string })[]): Promise<MediaBlock[]> {
90
+ const resolved: MediaBlock[] = [];
91
+ for (const b of blocks) {
92
+ if ((b as any)._localPath) {
93
+ try {
94
+ const buf = await readFile((b as any)._localPath as string);
95
+ resolved.push({ mimeType: b.mimeType, data: buf });
96
+ } catch (err) {
97
+ console.warn(`[media] failed to read local file ${(b as any)._localPath}: ${err}`);
98
+ }
99
+ } else {
100
+ resolved.push(b);
101
+ }
102
+ }
103
+ return resolved.filter((b) => {
104
+ if (b.mimeType.startsWith("video/") && b.data.length > MAX_VIDEO_BYTES) {
105
+ console.warn(`[media] video too large (${b.data.length} bytes), skipping`);
106
+ return false;
107
+ }
108
+ return b.data.length > 0;
109
+ });
110
+ }
111
+
112
+ // ---------------------------------------------------------------------------
113
+ // Fetch STS credentials from the relay server
114
+ // ---------------------------------------------------------------------------
115
+
116
+ async function fetchSts(
117
+ relayServerUrl: string,
118
+ gatewayId: string,
119
+ relaySecret: string,
120
+ mimeTypes: string[],
121
+ hasVideo: boolean
122
+ ): Promise<StsCredentials> {
123
+ const url = `${relayServerUrl.replace(/\/$/, "")}/api/media/sts`;
124
+ const res = await fetch(url, {
125
+ method: "POST",
126
+ headers: { "Content-Type": "application/json" },
127
+ body: JSON.stringify({
128
+ gatewayId,
129
+ relaySecret,
130
+ count: mimeTypes.length,
131
+ mimeTypes,
132
+ durationSeconds: hasVideo ? 1800 : 600,
133
+ }),
134
+ });
135
+ if (!res.ok) {
136
+ const text = await res.text().catch(() => "");
137
+ throw new Error(`STS fetch failed: ${res.status} ${text}`);
138
+ }
139
+ return res.json() as Promise<StsCredentials>;
140
+ }
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // Main: extract + upload → return attachments[]
144
+ // ---------------------------------------------------------------------------
145
+
146
+ export async function uploadAssistantAttachments(
147
+ history: { messages?: HistoryMessage[] },
148
+ relayServerUrl: string,
149
+ gatewayId: string,
150
+ relaySecret: string
151
+ ): Promise<AssistantAttachment[]> {
152
+ const rawBlocks = extractMediaBlocks(history);
153
+ if (rawBlocks.length === 0) return [];
154
+
155
+ const blocks = await resolveLocalPaths(rawBlocks as (MediaBlock & { _localPath?: string })[]);
156
+ if (blocks.length === 0) return [];
157
+
158
+ const mimeTypes = blocks.map((b) => b.mimeType);
159
+ const hasVideo = mimeTypes.some((m) => m.startsWith("video/"));
160
+
161
+ let sts: StsCredentials;
162
+ try {
163
+ sts = await fetchSts(relayServerUrl, gatewayId, relaySecret, mimeTypes, hasVideo);
164
+ } catch (err) {
165
+ console.error("[media] failed to fetch STS:", err);
166
+ return [];
167
+ }
168
+
169
+ const results: AssistantAttachment[] = [];
170
+
171
+ // Upload images concurrently (max 3), videos serially
172
+ const imageBlocks = blocks.filter((b) => !b.mimeType.startsWith("video/"));
173
+ const videoBlocks = blocks.filter((b) => b.mimeType.startsWith("video/"));
174
+
175
+ // Images: up to 3 concurrent
176
+ const imageBatches: MediaBlock[][] = [];
177
+ for (let i = 0; i < imageBlocks.length; i += 3) {
178
+ imageBatches.push(imageBlocks.slice(i, i + 3));
179
+ }
180
+ for (const batch of imageBatches) {
181
+ const settled = await Promise.allSettled(
182
+ batch.map((b) => uploadMedia(sts, b.data, b.mimeType))
183
+ );
184
+ for (const r of settled) {
185
+ if (r.status === "fulfilled") {
186
+ results.push(r.value);
187
+ } else {
188
+ console.warn("[media] image upload failed:", r.reason);
189
+ }
190
+ }
191
+ }
192
+
193
+ // Videos: serial
194
+ for (const b of videoBlocks) {
195
+ try {
196
+ const r = await uploadMedia(sts, b.data, b.mimeType);
197
+ results.push(r);
198
+ } catch (err) {
199
+ console.warn("[media] video upload failed:", err);
200
+ }
201
+ }
202
+
203
+ console.log(`[media] uploaded ${results.length}/${blocks.length} attachments`);
204
+ return results;
205
+ }
@@ -0,0 +1,280 @@
1
+ import { createHmac } from "crypto";
2
+ import { randomUUID } from "crypto";
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Types
6
+ // ---------------------------------------------------------------------------
7
+
8
+ export interface StsCredentials {
9
+ bucket: string;
10
+ region: string;
11
+ endpoint: string;
12
+ baseUrl: string;
13
+ dirPrefix: string;
14
+ expiresAt: number;
15
+ credentials: {
16
+ accessKeyId: string;
17
+ accessKeySecret: string;
18
+ securityToken: string;
19
+ };
20
+ }
21
+
22
+ export interface UploadResult {
23
+ url: string; // public CDN URL
24
+ thumbnailUrl?: string; // OSS snapshot URL (video only)
25
+ mimeType: string;
26
+ size: number;
27
+ }
28
+
29
+ // ---------------------------------------------------------------------------
30
+ // OSS HMAC-SHA1 request signing (with STS security token)
31
+ // ---------------------------------------------------------------------------
32
+
33
+ function ossSign(
34
+ method: string,
35
+ contentMd5: string,
36
+ contentType: string,
37
+ date: string,
38
+ canonicalizedHeaders: string,
39
+ canonicalizedResource: string,
40
+ secretKey: string
41
+ ): string {
42
+ const stringToSign = [
43
+ method,
44
+ contentMd5,
45
+ contentType,
46
+ date,
47
+ canonicalizedHeaders + canonicalizedResource,
48
+ ].join("\n");
49
+ return createHmac("sha1", secretKey).update(stringToSign).digest("base64");
50
+ }
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Simple PutObject upload (images / small files)
54
+ // ---------------------------------------------------------------------------
55
+
56
+ export async function putObject(
57
+ sts: StsCredentials,
58
+ data: Buffer,
59
+ ext: string,
60
+ mimeType: string
61
+ ): Promise<UploadResult> {
62
+ const { bucket, endpoint, baseUrl, dirPrefix, credentials } = sts;
63
+ const objectKey = `${dirPrefix}/${randomUUID()}${ext}`;
64
+ const date = new Date().toUTCString();
65
+ const canonicalizedResource = `/${bucket}/${objectKey}`;
66
+ const canonicalizedHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
67
+
68
+ const sig = ossSign(
69
+ "PUT",
70
+ "",
71
+ mimeType,
72
+ date,
73
+ canonicalizedHeaders,
74
+ canonicalizedResource,
75
+ credentials.accessKeySecret
76
+ );
77
+
78
+ const url = `${endpoint.replace(/\/$/, "")}/${objectKey}`;
79
+ const res = await fetch(url, {
80
+ method: "PUT",
81
+ headers: {
82
+ "Content-Type": mimeType,
83
+ "Date": date,
84
+ "x-oss-security-token": credentials.securityToken,
85
+ "Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
86
+ },
87
+ body: data as unknown as BodyInit,
88
+ });
89
+
90
+ if (!res.ok) {
91
+ const text = await res.text().catch(() => "");
92
+ throw new Error(`OSS PutObject failed: ${res.status} ${text}`);
93
+ }
94
+
95
+ const publicUrl = `${baseUrl.replace(/\/$/, "")}/${objectKey}`;
96
+ return { url: publicUrl, mimeType, size: data.length };
97
+ }
98
+
99
+ // ---------------------------------------------------------------------------
100
+ // Multipart upload (videos > 10 MB)
101
+ // ---------------------------------------------------------------------------
102
+
103
+ const PART_SIZE = 5 * 1024 * 1024; // 5 MB per part
104
+
105
+ export async function multipartUpload(
106
+ sts: StsCredentials,
107
+ data: Buffer,
108
+ ext: string,
109
+ mimeType: string
110
+ ): Promise<UploadResult> {
111
+ const { bucket, endpoint, baseUrl, dirPrefix, credentials } = sts;
112
+ const objectKey = `${dirPrefix}/${randomUUID()}${ext}`;
113
+ const baseOssUrl = `${endpoint.replace(/\/$/, "")}/${objectKey}`;
114
+
115
+ function makeHeaders(
116
+ method: string,
117
+ contentType: string,
118
+ extraHeaders: Record<string, string>,
119
+ resource: string
120
+ ): Headers {
121
+ const date = new Date().toUTCString();
122
+ const canonicalizedHeaders = [
123
+ "x-oss-security-token:" + credentials.securityToken,
124
+ ...Object.entries(extraHeaders)
125
+ .filter(([k]) => k.startsWith("x-oss-"))
126
+ .sort()
127
+ .map(([k, v]) => `${k}:${v}`),
128
+ ]
129
+ .sort()
130
+ .join("\n") + "\n";
131
+
132
+ const sig = ossSign(
133
+ method,
134
+ "",
135
+ contentType,
136
+ date,
137
+ canonicalizedHeaders,
138
+ `/${bucket}/${objectKey}`,
139
+ credentials.accessKeySecret
140
+ );
141
+
142
+ const headers = new Headers({
143
+ "Date": date,
144
+ "x-oss-security-token": credentials.securityToken,
145
+ "Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
146
+ ...extraHeaders,
147
+ });
148
+ if (contentType) headers.set("Content-Type", contentType);
149
+ return headers;
150
+ }
151
+
152
+ // 1. Initiate
153
+ const initRes = await fetch(`${baseOssUrl}?uploads`, {
154
+ method: "POST",
155
+ headers: makeHeaders("POST", mimeType, {}, `/${bucket}/${objectKey}`),
156
+ });
157
+ if (!initRes.ok) throw new Error(`OSS InitiateMultipartUpload failed: ${initRes.status}`);
158
+ const initText = await initRes.text();
159
+ const uploadIdMatch = initText.match(/<UploadId>([^<]+)<\/UploadId>/);
160
+ if (!uploadIdMatch) throw new Error("OSS: could not parse UploadId");
161
+ const uploadId = uploadIdMatch[1];
162
+
163
+ // 2. Upload parts
164
+ const parts: Array<{ partNumber: number; etag: string }> = [];
165
+ let partNumber = 1;
166
+ let offset = 0;
167
+
168
+ try {
169
+ while (offset < data.length) {
170
+ const chunk = data.slice(offset, offset + PART_SIZE);
171
+ const partDate = new Date().toUTCString();
172
+ const canonicalizedHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
173
+ const sig = ossSign(
174
+ "PUT", "", "application/octet-stream", partDate,
175
+ canonicalizedHeaders, `/${bucket}/${objectKey}`,
176
+ credentials.accessKeySecret
177
+ );
178
+ const partRes = await fetch(
179
+ `${baseOssUrl}?partNumber=${partNumber}&uploadId=${uploadId}`,
180
+ {
181
+ method: "PUT",
182
+ headers: {
183
+ "Content-Type": "application/octet-stream",
184
+ "Date": partDate,
185
+ "x-oss-security-token": credentials.securityToken,
186
+ "Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
187
+ },
188
+ body: chunk as unknown as BodyInit,
189
+ }
190
+ );
191
+ if (!partRes.ok) throw new Error(`OSS UploadPart ${partNumber} failed: ${partRes.status}`);
192
+ const etag = partRes.headers.get("etag") ?? "";
193
+ parts.push({ partNumber, etag });
194
+ partNumber++;
195
+ offset += PART_SIZE;
196
+ }
197
+
198
+ // 3. Complete
199
+ const completeBody = [
200
+ "<CompleteMultipartUpload>",
201
+ ...parts.map(
202
+ (p) => `<Part><PartNumber>${p.partNumber}</PartNumber><ETag>${p.etag}</ETag></Part>`
203
+ ),
204
+ "</CompleteMultipartUpload>",
205
+ ].join("");
206
+
207
+ const completeDate = new Date().toUTCString();
208
+ const cHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
209
+ const cSig = ossSign(
210
+ "POST", "", "application/xml", completeDate,
211
+ cHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret
212
+ );
213
+ const completeRes = await fetch(`${baseOssUrl}?uploadId=${uploadId}`, {
214
+ method: "POST",
215
+ headers: {
216
+ "Content-Type": "application/xml",
217
+ "Date": completeDate,
218
+ "x-oss-security-token": credentials.securityToken,
219
+ "Authorization": `OSS ${credentials.accessKeyId}:${cSig}`,
220
+ },
221
+ body: completeBody,
222
+ });
223
+ if (!completeRes.ok) throw new Error(`OSS CompleteMultipartUpload failed: ${completeRes.status}`);
224
+
225
+ } catch (err) {
226
+ // Best-effort abort to avoid billing for incomplete upload
227
+ try {
228
+ const abortDate = new Date().toUTCString();
229
+ const aHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
230
+ const aSig = ossSign(
231
+ "DELETE", "", "", abortDate,
232
+ aHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret
233
+ );
234
+ await fetch(`${baseOssUrl}?uploadId=${uploadId}`, {
235
+ method: "DELETE",
236
+ headers: {
237
+ "Date": abortDate,
238
+ "x-oss-security-token": credentials.securityToken,
239
+ "Authorization": `OSS ${credentials.accessKeyId}:${aSig}`,
240
+ },
241
+ });
242
+ } catch { /* ignore abort errors */ }
243
+ throw err;
244
+ }
245
+
246
+ const publicUrl = `${baseUrl.replace(/\/$/, "")}/${objectKey}`;
247
+ // OSS video snapshot thumbnail URL
248
+ const thumbnailUrl = `${publicUrl}?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast`;
249
+ return { url: publicUrl, thumbnailUrl, mimeType, size: data.length };
250
+ }
251
+
252
+ // ---------------------------------------------------------------------------
253
+ // Convenience: auto-select PutObject vs multipart based on size
254
+ // ---------------------------------------------------------------------------
255
+
256
+ const MULTIPART_THRESHOLD = 10 * 1024 * 1024; // 10 MB
257
+
258
+ export async function uploadMedia(
259
+ sts: StsCredentials,
260
+ data: Buffer,
261
+ mimeType: string
262
+ ): Promise<UploadResult> {
263
+ const ext = mimeTypeToExt(mimeType);
264
+ if (data.length >= MULTIPART_THRESHOLD) {
265
+ return multipartUpload(sts, data, ext, mimeType);
266
+ }
267
+ return putObject(sts, data, ext, mimeType);
268
+ }
269
+
270
+ function mimeTypeToExt(mimeType: string): string {
271
+ const map: Record<string, string> = {
272
+ "image/jpeg": ".jpg",
273
+ "image/png": ".png",
274
+ "image/gif": ".gif",
275
+ "image/webp": ".webp",
276
+ "video/mp4": ".mp4",
277
+ "video/quicktime": ".mov",
278
+ };
279
+ return map[mimeType] ?? ".bin";
280
+ }
@@ -3,6 +3,7 @@ import { OpenClawGatewayClient } from "./gateway-client.js";
3
3
  import { handleLocalCommand } from "../commands/local-handlers.js";
4
4
  import { handleProviderCommand } from "../commands/provider-handlers.js";
5
5
  import { getServicePlatform } from "../platform/service-manager.js";
6
+ import { uploadAssistantAttachments } from "../media/assistant-attachments.js";
6
7
  import { homedir } from "os";
7
8
  import { join } from "path";
8
9
  import { mkdir, writeFile } from "fs/promises";
@@ -105,15 +106,15 @@ export async function runRelayManager(opts: RelayManagerOptions): Promise<boolea
105
106
  },
106
107
 
107
108
  onEvent: (event, payload) => {
108
- // On chat final, fetch history to get actual content (OpenClaw 2026.3.2+
109
- // no longer includes message content in the chat final event payload).
110
- // This mirrors what the macOS 2026.3.2 client does.
109
+ // On chat final, fetch history to get actual content + extract media attachments.
110
+ // OpenClaw 2026.3.2+ no longer includes message content in chat final payload.
111
111
  if (event === "chat") {
112
112
  const p = payload as { state?: string; sessionKey?: string; runId?: string; message?: unknown };
113
113
  if (p?.state === "final" && p?.sessionKey) {
114
114
  const sessionKey = p.sessionKey;
115
115
  const runId = p.runId;
116
- type HistoryResponse = { messages?: Array<{ role: string; content?: Array<{ type: string; text?: string }> }> };
116
+ type ContentBlock = { type: string; text?: string; source?: { type?: string; media_type?: string; data?: string; path?: string } };
117
+ type HistoryResponse = { messages?: Array<{ role: string; content?: ContentBlock[] }> };
117
118
  const fetchHistory = () =>
118
119
  gatewayClient!.request<HistoryResponse>("chat.history", { sessionKey, limit: 10 });
119
120
  const extractText = (h: HistoryResponse | undefined) => {
@@ -129,10 +130,28 @@ export async function runRelayManager(opts: RelayManagerOptions): Promise<boolea
129
130
  await new Promise((resolve) => setTimeout(resolve, 600));
130
131
  const retryHistory = await fetchHistory();
131
132
  text = extractText(retryHistory);
133
+ history = retryHistory;
132
134
  }
133
135
  if (text) {
134
136
  (p as Record<string, unknown>).message = { content: [{ type: "text", text }] };
135
137
  }
138
+
139
+ // Upload any media blocks found in the history
140
+ try {
141
+ const attachments = await uploadAssistantAttachments(
142
+ history ?? {},
143
+ opts.relayServerUrl,
144
+ opts.gatewayId,
145
+ opts.relaySecret
146
+ );
147
+ if (attachments.length > 0) {
148
+ (p as Record<string, unknown>).attachments = attachments;
149
+ console.log(`[relay] chat final: injected ${attachments.length} attachment(s) runId=${runId}`);
150
+ }
151
+ } catch (mediaErr) {
152
+ console.error(`[relay] media upload error (non-fatal): ${mediaErr}`);
153
+ }
154
+
136
155
  console.log(`[relay] chat final (history fetched): runId=${runId} textLength=${text?.length ?? 0}`);
137
156
  send({ type: "event", event, payload });
138
157
  })
@@ -140,7 +159,7 @@ export async function runRelayManager(opts: RelayManagerOptions): Promise<boolea
140
159
  console.error(`[relay] chat.history fetch failed: ${err}`);
141
160
  send({ type: "event", event, payload });
142
161
  });
143
- return; // will send after history fetch
162
+ return; // will send after history fetch + media upload
144
163
  }
145
164
  }
146
165
  send({ type: "event", event, payload });