refactor(link-understanding): reuse media scope resolver (#129632)

Amp-Thread-ID: https://ampcode.com/threads/T-01a037b7-785b-75eb-8426-ad67094e61d4

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Peter Steinberger
2026-08-25 15:22:03 -07:00
committed by GitHub
parent 48e7b02caa
commit b036fa9c21
2 changed files with 35 additions and 18 deletions
+33
View File
@@ -72,6 +72,39 @@ describe("runLinkUnderstanding", () => {
mocks.runCommandWithTimeout.mockReset();
});
it("applies shared media scope rules to link message context", async () => {
const result = await runLinkUnderstanding({
cfg: {
tools: {
links: {
enabled: true,
scope: {
default: "allow",
rules: [
{
action: "deny",
match: { channel: "slack", chatType: "channel", keyPrefix: "agent:main:" },
},
],
},
models: [{ type: "cli", command: "summarize" }],
},
},
} as OpenClawConfig,
ctx: {
Body: "see https://example.com/page",
ChatType: "channel",
Provider: "discord",
SessionKey: "agent:main:slack:channel:C123",
Surface: "slack",
} as MsgContext,
});
expect(result).toEqual({ urls: [], outputs: [] });
expect(fetchWithSsrFGuard).not.toHaveBeenCalled();
expect(runCommandWithTimeout).not.toHaveBeenCalled();
});
it("fetches links through the SSRF guard before passing content to CLI stdin", async () => {
const release = mockGuardedFetch("page body", "https://example.com/final");
mockCommand("summarized page");
+2 -18
View File
@@ -7,11 +7,7 @@ import { logVerbose, shouldLogVerbose } from "../globals.js";
import { cancelUnreadResponseBody, readResponseWithLimit } from "../infra/http-body.js";
import { fetchWithSsrFGuard, GUARDED_FETCH_MODE } from "../infra/net/fetch-guard.js";
import { CLI_OUTPUT_MAX_BUFFER } from "../media-understanding/defaults.js";
import { resolveTimeoutMs } from "../media-understanding/resolve.js";
import {
normalizeMediaUnderstandingChatType,
resolveMediaUnderstandingScope,
} from "../media-understanding/scope.js";
import { resolveScopeDecision, resolveTimeoutMs } from "../media-understanding/resolve.js";
import { runCommandWithTimeout } from "../process/exec.js";
import { DEFAULT_LINK_TIMEOUT_SECONDS } from "./defaults.js";
import { extractLinksFromMessage } from "./detect.js";
@@ -21,18 +17,6 @@ type LinkUnderstandingResult = {
outputs: string[];
};
function resolveScopeDecision(params: {
config?: LinkToolsConfig;
ctx: MsgContext;
}): "allow" | "deny" {
return resolveMediaUnderstandingScope({
scope: params.config?.scope,
sessionKey: params.ctx.SessionKey,
channel: params.ctx.Surface ?? params.ctx.Provider,
chatType: normalizeMediaUnderstandingChatType(params.ctx.ChatType),
});
}
function resolveTimeoutMsFromConfig(params: {
config?: LinkToolsConfig;
entry: LinkModelConfig;
@@ -217,7 +201,7 @@ export async function runLinkUnderstanding(params: {
return { urls: [], outputs: [] };
}
const scopeDecision = resolveScopeDecision({ config, ctx: params.ctx });
const scopeDecision = resolveScopeDecision({ scope: config.scope, ctx: params.ctx });
if (scopeDecision === "deny") {
if (shouldLogVerbose()) {
logVerbose("Link understanding disabled by scope policy.");