Commits merged: - chore(test-isolation): broaden runtime ignore list for live fusion app paths - feat(FN-3573): complete Step 2 — add plugin setup API client helpers - feat(FN-3573): complete Step 1 — backfill plugin setup routes Files changed: plugins/fusion-plugin-agent-browser/README.md | 26 ++++++ plugins/fusion-plugin-agent-browser/manifest.json | 15 ++++ plugins/fusion-plugin-agent-browser/package.json | 25 ++++++ .../src/__tests__/index.test.ts | 66 +++++++++++++++ .../src/__tests__/prompts.test.ts | 21 +++++ .../src/__tests__/setup.test.ts | 39 +++++++++ .../src/__tests__/skills.test.ts | 9 ++ .../src/__tests__/tools.test.ts | 55 ++++++++++++ .../src/__tests__/types.test.ts | 16 ++++ .../src/__tests__/workflow-steps.test.ts | 10 +++ plugins/fusion-plugin-agent-browser/src/index.ts | 67 +++++++++++++++ plugins/fusion-plugin-agent-browser/src/probe.ts | 98 ++++++++++++++++++++++ plugins/fusion-plugin-agent-browser/src/prompts.ts | 23 +++++ plugins/fusion-plugin-agent-browser/src/setup.ts | 31 +++++++ plugins/fusion-plugin-agent-browser/src/skills.ts | 12 +++ plugins/fusion-plugin-agent-browser/src/tools.ts | 34 ++++++++ plugins/fusion-plugin-agent-browser/src/types.ts | 56 +++++++++++++ .../src/workflow-steps.ts | 15 ++++ plugins/fusion-plugin-agent-browser/tsconfig.json | 9 ++ .../fusion-plugin-agent-browser/vitest.config.ts | 22 +++++ pnpm-lock.yaml | 16 ++++ pnpm-workspace.yaml | 1 + 22 files changed, 666 insertions(+) Fusion-Task-Id: FN-3573
35 lines
1.3 KiB
TypeScript
35 lines
1.3 KiB
TypeScript
import type { PluginToolDefinition } from "@fusion/plugin-sdk";
|
|
import { resolveSettings } from "./types.js";
|
|
|
|
export const AGENT_BROWSER_TOOLS: PluginToolDefinition[] = [
|
|
{
|
|
name: "browser_fetch_metadata",
|
|
description: "Validate a URL against plugin allowlist and return safe fetch metadata.",
|
|
parameters: {
|
|
type: "object",
|
|
properties: { url: { type: "string" } },
|
|
required: ["url"],
|
|
},
|
|
execute: async (params, ctx) => {
|
|
const url = typeof params.url === "string" ? params.url : "";
|
|
try {
|
|
const parsed = new URL(url);
|
|
const settings = resolveSettings(ctx.settings);
|
|
const allowed = settings.allowedDomains;
|
|
const isAllowed = allowed.length === 0 || allowed.some((d) => parsed.hostname === d || parsed.hostname.endsWith(`.${d}`));
|
|
|
|
if (!isAllowed) {
|
|
return { content: [{ type: "text", text: `Blocked by allowedDomains: ${parsed.hostname}` }], isError: true };
|
|
}
|
|
|
|
return {
|
|
content: [{ type: "text", text: `Allowed URL ${parsed.toString()} (headless=${String(settings.headlessMode)})` }],
|
|
details: { hostname: parsed.hostname, headlessMode: settings.headlessMode },
|
|
};
|
|
} catch {
|
|
return { content: [{ type: "text", text: "Invalid URL" }], isError: true };
|
|
}
|
|
},
|
|
},
|
|
];
|