chore(plugin): rebuild dist (file delivery)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
h z
2026-05-15 20:17:28 +01:00
parent 2abd0000e6
commit 42228e0a23

View File

@@ -1,3 +1,6 @@
import { promises as fs } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { io } from 'socket.io-client';
import { dispatchInboundReplyWithBase } from 'openclaw/plugin-sdk/inbound-reply-dispatch';
export class FabricInbound {
@@ -87,6 +90,48 @@ export class FabricInbound {
this.sockets.push(socket);
}
}
// Download a message's attachments to a temp dir using the agent's guild
// token; returns local paths/types/urls for the inbound media context.
async fetchAttachments(agentId, endpoint, token, m) {
const out = { paths: [], types: [], urls: [] };
const list = m.attachments ?? [];
if (!list.length || !token)
return out;
const dir = join(tmpdir(), `fabric-media-${agentId}-${m.messageId}`.replace(/[^\w.-]/g, '_'));
try {
await fs.mkdir(dir, { recursive: true });
}
catch {
return out;
}
let i = 0;
for (const a of list) {
try {
const abs = a.url.startsWith('http') ? a.url : `${endpoint}${a.url}`;
const res = await fetch(abs, { headers: { authorization: `Bearer ${token}` } });
if (!res.ok) {
this.log.warn(`fabric: attachment fetch ${res.status} ${abs}`);
continue;
}
const buf = Buffer.from(await res.arrayBuffer());
const safe = (a.name ?? `file-${i}`).replace(/[^\w.-]/g, '_').slice(0, 120) || `file-${i}`;
const p = join(dir, `${i}-${safe}`);
await fs.writeFile(p, buf);
out.paths.push(p);
out.types.push(a.mimeType ||
res.headers.get('content-type')?.split(';')[0] ||
'application/octet-stream');
out.urls.push(abs);
i++;
}
catch (err) {
this.log.warn(`fabric: attachment fetch failed agent=${agentId}: ${String(err)}`);
}
}
if (out.paths.length)
this.log.info(`fabric: fetched ${out.paths.length} attachment(s) agent=${agentId}`);
return out;
}
async dispatch(agentId, guild, channelId, m, session) {
// wakeup === false -> drop (Fabric already decided this agent is silent)
if (m.wakeup !== true) {
@@ -106,6 +151,10 @@ export class FabricInbound {
const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
agentId: route.agentId,
});
const gt = session.guildAccessTokens.find((t) => t.guildNodeId === guild.nodeId)?.token;
// Fetch any uploaded files for the agent: download to a temp dir and
// hand openclaw local MediaPaths (+types) so the model receives them.
const media = await this.fetchAttachments(agentId, guild.endpoint, gt, m);
const ctxPayload = core.channel.reply.finalizeInboundContext({
Body: m.content,
BodyForAgent: m.content,
@@ -124,8 +173,17 @@ export class FabricInbound {
Timestamp: m.createdAt ? Date.parse(m.createdAt) : Date.now(),
OriginatingChannel: 'fabric',
OriginatingTo: `fabric:${channelId}`,
...(media.paths.length
? {
MediaPaths: media.paths,
MediaTypes: media.types,
MediaUrls: media.urls,
MediaPath: media.paths[0],
MediaType: media.types[0],
MediaUrl: media.urls[0],
}
: {}),
});
const gt = session.guildAccessTokens.find((t) => t.guildNodeId === guild.nodeId)?.token;
await dispatchInboundReplyWithBase({
cfg: this.cfg,
channel: 'fabric',