fix(chat): keep internal metadata out of transcripts (#109056)

* fix(chat): keep internal metadata out of transcripts

Signed-off-by: sallyom <somalley@redhat.com>

* fix(gateway): harden control reply projection

Co-authored-by: sallyom <somalley@redhat.com>

* chore: leave changelog to release tooling

---------

Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
Sally O'Malley
2026-07-16 13:47:43 -04:00
committed by GitHub
parent 21b08f34b7
commit 11c7360af5
7 changed files with 295 additions and 22 deletions
+24
View File
@@ -0,0 +1,24 @@
import { describe, expect, it } from "vitest";
import { resolveReefInboundDispatchContent } from "./inbound.js";
describe("Reef inbound dispatch content", () => {
it("keeps provenance model-visible without storing it in the transcript body", () => {
const content = resolveReefInboundDispatchContent({
id: "message-1",
peer: "clanky",
text: "hello from Clanky",
provenance: "Untrusted third-party data from @clanky's agent.",
autonomy: "bounded",
});
expect(content).toEqual({
rawBody: "hello from Clanky",
extraContext: {
UntrustedContext: ["Untrusted third-party data from @clanky's agent."],
ReefProvenance: "Untrusted third-party data from @clanky's agent.",
ReefEnvelopeId: "message-1",
SenderIsBot: true,
},
});
});
});
+3 -7
View File
@@ -19,6 +19,7 @@ import {
} from "./config-schema.js";
import { createConfiguredGuard, ReefMessageFlow } from "./flow.js";
import { ReefFriendManager } from "./friends.js";
import { resolveReefInboundDispatchContent } from "./inbound.js";
import { reefMessageAdapter, reefOutboundAdapter } from "./outbound.js";
import { getActiveReef, getOptionalReefRuntime, getReefRuntime, setActiveReef } from "./runtime.js";
import { reefSetupAdapter, reefSetupWizard } from "./setup.js";
@@ -197,6 +198,7 @@ export const reefPlugin: ChannelPlugin<ReefAccount> = {
},
});
const onIngress = async (message: ReefIngressMessage) => {
const dispatchContent = resolveReefInboundDispatchContent(message);
const budget = autonomyBudget(message.autonomy);
const loop = recordChannelBotPairLoopAndCheckSuppression({
scopeId: "reef:default",
@@ -223,15 +225,9 @@ export const reefPlugin: ChannelPlugin<ReefAccount> = {
senderAddress: `reef:${message.peer}`,
recipientAddress: `reef:${ctx.account.config.handle}`,
conversationLabel: `@${message.peer}'s agent`,
rawBody: message.text,
bodyForAgent: `${message.provenance}\n\n<reef-message>${message.text}</reef-message>`,
...dispatchContent,
messageId: message.id,
commandAuthorized: false,
extraContext: {
ReefProvenance: message.provenance,
ReefEnvelopeId: message.id,
SenderIsBot: true,
},
deliver: async (payload) => {
const text =
payload && typeof payload === "object" && "text" in payload
+13
View File
@@ -0,0 +1,13 @@
import type { ReefIngressMessage } from "./types.js";
export function resolveReefInboundDispatchContent(message: ReefIngressMessage) {
return {
rawBody: message.text,
extraContext: {
UntrustedContext: [message.provenance],
ReefProvenance: message.provenance,
ReefEnvelopeId: message.id,
SenderIsBot: true,
},
};
}