Compare commits
1 Commits
fc7efd0227
...
892db9f9be
| Author | SHA1 | Date | |
|---|---|---|---|
| 892db9f9be |
38
dist/fabric/src/inbound.js
vendored
38
dist/fabric/src/inbound.js
vendored
@@ -162,12 +162,6 @@ export class FabricInbound {
|
||||
return out;
|
||||
}
|
||||
async dispatch(agentId, guild, channelId, m, session) {
|
||||
// wakeup === false -> drop (Fabric already decided this agent is silent)
|
||||
if (m.wakeup !== true) {
|
||||
this.log.info(`fabric: drop (no wakeup) agent=${agentId} channel=${channelId}`);
|
||||
return;
|
||||
}
|
||||
this.log.info(`fabric: dispatch agent=${agentId} channel=${channelId}`);
|
||||
const core = this.core;
|
||||
const cfg = this.cfg;
|
||||
try {
|
||||
@@ -180,11 +174,7 @@ export class FabricInbound {
|
||||
const storePath = core.channel.session.resolveStorePath(cfg.session?.store, {
|
||||
agentId: route.agentId,
|
||||
});
|
||||
const gt = await this.freshGuildToken(agentId, guild.nodeId, session);
|
||||
// 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({
|
||||
const baseCtx = {
|
||||
Body: m.content,
|
||||
BodyForAgent: m.content,
|
||||
RawBody: m.content,
|
||||
@@ -202,6 +192,32 @@ export class FabricInbound {
|
||||
Timestamp: m.createdAt ? Date.parse(m.createdAt) : Date.now(),
|
||||
OriginatingChannel: 'fabric',
|
||||
OriginatingTo: `fabric:${channelId}`,
|
||||
};
|
||||
// Non-wakeup: Fabric has already decided this agent is NOT the speaker
|
||||
// this round. Do NOT run the model and do NOT send anything back — the
|
||||
// discuss/work turn engine expects silence from non-woken agents (only
|
||||
// the woken speaker emits a normal message or /no-reply). We still
|
||||
// record the message into the agent's session so it has the full
|
||||
// channel conversation as context whenever it IS later woken.
|
||||
if (m.wakeup !== true) {
|
||||
const ctxPayload = core.channel.reply.finalizeInboundContext(baseCtx);
|
||||
await core.channel.session.recordInboundSession({
|
||||
storePath,
|
||||
sessionKey: route.sessionKey,
|
||||
ctx: ctxPayload,
|
||||
createIfMissing: true,
|
||||
onRecordError: (err) => this.log.warn(`fabric: history record failed agent=${agentId}: ${String(err)}`),
|
||||
});
|
||||
this.log.info(`fabric: recorded (no wakeup, history only) agent=${agentId} channel=${channelId}`);
|
||||
return;
|
||||
}
|
||||
this.log.info(`fabric: dispatch agent=${agentId} channel=${channelId}`);
|
||||
const gt = await this.freshGuildToken(agentId, guild.nodeId, session);
|
||||
// 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({
|
||||
...baseCtx,
|
||||
// Provide ONLY local paths. The guild file URL is on a private host
|
||||
// (e.g. localhost); openclaw's SSRF guard blocks re-fetching it, so
|
||||
// passing MediaUrls is both redundant (we already downloaded the
|
||||
|
||||
@@ -16,7 +16,16 @@ import type { IdentityRegistry } from './identity.js';
|
||||
type Core = {
|
||||
channel: {
|
||||
routing: { resolveAgentRoute: (p: unknown) => { agentId: string; sessionKey: string; accountId?: string } };
|
||||
session: { resolveStorePath: (store: unknown, o: { agentId: string }) => string };
|
||||
session: {
|
||||
resolveStorePath: (store: unknown, o: { agentId: string }) => string;
|
||||
recordInboundSession: (p: {
|
||||
storePath: string;
|
||||
sessionKey: string;
|
||||
ctx: unknown;
|
||||
createIfMissing?: boolean;
|
||||
onRecordError: (e: unknown) => void;
|
||||
}) => Promise<unknown>;
|
||||
};
|
||||
reply: { finalizeInboundContext: (p: Record<string, unknown>) => unknown };
|
||||
};
|
||||
};
|
||||
@@ -202,13 +211,6 @@ export class FabricInbound {
|
||||
m: FabricMessage,
|
||||
session: FabricSession,
|
||||
): Promise<void> {
|
||||
// wakeup === false -> drop (Fabric already decided this agent is silent)
|
||||
if (m.wakeup !== true) {
|
||||
this.log.info(`fabric: drop (no wakeup) agent=${agentId} channel=${channelId}`);
|
||||
return;
|
||||
}
|
||||
this.log.info(`fabric: dispatch agent=${agentId} channel=${channelId}`);
|
||||
|
||||
const core = this.core as Core & Record<string, unknown>;
|
||||
const cfg = this.cfg as { session?: { store?: unknown } };
|
||||
try {
|
||||
@@ -222,13 +224,7 @@ export class FabricInbound {
|
||||
agentId: route.agentId,
|
||||
});
|
||||
|
||||
const gt = await this.freshGuildToken(agentId, guild.nodeId, session);
|
||||
|
||||
// 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({
|
||||
const baseCtx: Record<string, unknown> = {
|
||||
Body: m.content,
|
||||
BodyForAgent: m.content,
|
||||
RawBody: m.content,
|
||||
@@ -246,6 +242,39 @@ export class FabricInbound {
|
||||
Timestamp: m.createdAt ? Date.parse(m.createdAt) : Date.now(),
|
||||
OriginatingChannel: 'fabric',
|
||||
OriginatingTo: `fabric:${channelId}`,
|
||||
};
|
||||
|
||||
// Non-wakeup: Fabric has already decided this agent is NOT the speaker
|
||||
// this round. Do NOT run the model and do NOT send anything back — the
|
||||
// discuss/work turn engine expects silence from non-woken agents (only
|
||||
// the woken speaker emits a normal message or /no-reply). We still
|
||||
// record the message into the agent's session so it has the full
|
||||
// channel conversation as context whenever it IS later woken.
|
||||
if (m.wakeup !== true) {
|
||||
const ctxPayload = core.channel.reply.finalizeInboundContext(baseCtx);
|
||||
await core.channel.session.recordInboundSession({
|
||||
storePath,
|
||||
sessionKey: route.sessionKey,
|
||||
ctx: ctxPayload,
|
||||
createIfMissing: true,
|
||||
onRecordError: (err: unknown) =>
|
||||
this.log.warn(`fabric: history record failed agent=${agentId}: ${String(err)}`),
|
||||
});
|
||||
this.log.info(
|
||||
`fabric: recorded (no wakeup, history only) agent=${agentId} channel=${channelId}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.log.info(`fabric: dispatch agent=${agentId} channel=${channelId}`);
|
||||
const gt = await this.freshGuildToken(agentId, guild.nodeId, session);
|
||||
|
||||
// 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({
|
||||
...baseCtx,
|
||||
// Provide ONLY local paths. The guild file URL is on a private host
|
||||
// (e.g. localhost); openclaw's SSRF guard blocks re-fetching it, so
|
||||
// passing MediaUrls is both redundant (we already downloaded the
|
||||
|
||||
Reference in New Issue
Block a user