INTEGRITY Dokumentace

Integrace prohlížeče

Použijte @cloudflare/codemode/browser když nástroje vlastní váš prohlížeč a model je musí jen orchestrovat. Tyto nástroje mohou například číst stav stránky, přistupovat k rozhraním API prohlížeče nebo aktualizovat data uložená ve vaší aplikaci.

Code Mode se hodí, když model musí volat několik klientských nástrojů s cykly, podmínkami nebo mezivýsledky. Pro jedinou akci v prohlížeči místo toho použijte standardní nástroj na straně klienta.

Code Mode prezentuje tyto nástroje modelu jako typované funkce. Model napíše jednu asynchronní arrow funkci JavaScriptu, která může volat několik nástrojů, kombinovat jejich výsledky a uplatňovat řídicí strukturu. IframeSandboxExecutor spouští tento vygenerovaný kód v sandboxovaném iframe na stránce.

Tato integrace neposkytuje agentovi kontrolu nad vzdáleným prohlížečem. Pro prohlížení webových stránek, pořizování snímků obrazovky nebo automatizaci stránek pomocí Chrome DevTools Protocol (CDP) si přečtěte Nástroje prohlížeče.

Instalace Code Mode

Nainstalujte balíček do své klientské aplikace:

npm i @cloudflare/codemode

@cloudflare/codemode/browser vstupní bod používá JSON Schema a rozhraní API prohlížeče. Nevyžaduje peer závislosti AI SDK ani Zod, které používá @cloudflare/codemode/ai.

Přidání Code Mode do chatovacího UI Agenta

Prohlížeč vytvoří nástroj Code Mode a zaregistruje ho jako dynamický klientský nástroj. Agent obdrží schéma nástroje, ale implementace nástroje zůstává v prohlížeči.

  1. Definujte nástroje vlastněné prohlížečem pomocí JSON Schema a execute .

    src/browser-tools.js
    export const browserTools = {
    	getPageInfo: {
    		description: "Get information about the current browser page",
    		inputSchema: {
    			type: "object",
    			properties: {},
    			required: [],
    		},
    		execute: async () => ({
    			title: document.title,
    			url: window.location.href,
    		}),
    	},
    	getSelectionText: {
    		description: "Get the user's current text selection",
    		inputSchema: {
    			type: "object",
    			properties: {},
    			required: [],
    		},
    		execute: async () => ({
    			text: window.getSelection()?.toString() ?? "",
    		}),
    	},
    };
    src/browser-tools.ts
    import type { JsonSchemaExecutableToolDescriptors } from "@cloudflare/codemode/browser";
    
    export const browserTools: JsonSchemaExecutableToolDescriptors = {
      getPageInfo: {
        description: "Get information about the current browser page",
        inputSchema: {
          type: "object",
          properties: {},
          required: []
        },
        execute: async () => ({
          title: document.title,
          url: window.location.href
        })
      },
      getSelectionText: {
        description: "Get the user's current text selection",
        inputSchema: {
          type: "object",
          properties: {},
          required: []
        },
        execute: async () => ({
          text: window.getSelection()?.toString() ?? ""
        })
      }
    };

    JSON Schema poskytuje typy zobrazené modelu. createBrowserCodeTool() nepoužívá schéma k ověřování argumentů za běhu. Neověřené vstupy validujte uvnitř každé execute funkci, když je to potřeba.

  2. Vytvořte deskriptor Code Mode s executorem iframe.

    src/codemode-tool.js
    import {
    	IframeSandboxExecutor,
    	createBrowserCodeTool,
    } from "@cloudflare/codemode/browser";
    import { browserTools } from "./browser-tools";
    
    export const codemodeTool = createBrowserCodeTool({
    	tools: browserTools,
    	executor: new IframeSandboxExecutor(),
    });
    src/codemode-tool.ts
    import {
      IframeSandboxExecutor,
      createBrowserCodeTool
    } from "@cloudflare/codemode/browser";
    import { browserTools } from "./browser-tools";
    
    export const codemodeTool = createBrowserCodeTool({
      tools: browserTools,
      executor: new IframeSandboxExecutor()
    });

    createBrowserCodeTool() vrátí obyčejný deskriptor s názvem codemode. Jeho popis obsahuje vygenerované definice TypeScript pro nástroje prohlížeče. Jeho vstup obsahuje JavaScript vygenerovaný modelem v code vlastnost.

    executor možnost je volitelná. Pokud je vynechána, createBrowserCodeTool() vytvoří IframeSandboxExecutor s výchozím nastavením.

  3. Zaregistrujte deskriptor pomocí useAgentChat() a provádět volání nástrojů na straně klienta.

    src/client.jsx
    import { useAgentChat } from "@cloudflare/ai-chat/react";
    import { useAgent } from "agents/react";
    import { useMemo } from "react";
    import { codemodeTool } from "./codemode-tool";
    
    function BrowserCodeModeChat() {
    	const agent = useAgent({ agent: "browser-codemode" });
    
    	const tools = useMemo(
    		() => ({
    			codemode: {
    				description: codemodeTool.description,
    				parameters: codemodeTool.inputSchema,
    				execute: (input) => codemodeTool.execute(input),
    			},
    		}),
    		[],
    	);
    
    	const { messages, sendMessage } = useAgentChat({
    		agent,
    		tools,
    		onToolCall: async ({ toolCall, addToolOutput }) => {
    			const tool = tools[toolCall.toolName];
    			if (!tool?.execute) return;
    
    			try {
    				const output = await tool.execute(toolCall.input);
    				addToolOutput({
    					toolCallId: toolCall.toolCallId,
    					output,
    				});
    			} catch (error) {
    				addToolOutput({
    					toolCallId: toolCall.toolCallId,
    					state: "output-error",
    					errorText: error instanceof Error ? error.message : String(error),
    				});
    			}
    		},
    	});
    
    	// Render messages and call sendMessage() from your chat UI.
    }
    src/client.tsx
    import { useAgentChat, type AITool } from "@cloudflare/ai-chat/react";
    import { useAgent } from "agents/react";
    import { useMemo } from "react";
    import { codemodeTool } from "./codemode-tool";
    
    function BrowserCodeModeChat() {
      const agent = useAgent({ agent: "browser-codemode" });
    
      const tools = useMemo<Record<string, AITool>>(
        () => ({
          codemode: {
            description: codemodeTool.description,
            parameters: codemodeTool.inputSchema,
            execute: (input) =>
              codemodeTool.execute(input as { code: string })
          }
        }),
        []
      );
    
      const { messages, sendMessage } = useAgentChat({
        agent,
        tools,
        onToolCall: async ({ toolCall, addToolOutput }) => {
          const tool = tools[toolCall.toolName];
          if (!tool?.execute) return;
    
          try {
            const output = await tool.execute(toolCall.input);
            addToolOutput({
              toolCallId: toolCall.toolCallId,
              output
            });
          } catch (error) {
            addToolOutput({
              toolCallId: toolCall.toolCallId,
              state: "output-error",
              errorText: error instanceof Error ? error.message : String(error)
            });
          }
        }
      });
    
      // Render messages and call sendMessage() from your chat UI.
    }

    useAgentChat() odešle Agentovi registrované schéma nástroje na straně klienta. Když model zavolá codemode, onToolCall provede deskriptor v prohlížeči a přidá jeho výstup do konverzace.

  4. Na straně Agenta převeďte klientská schémata na nástroje modelu.

    src/server.js
    import { AIChatAgent, createToolsFromClientSchemas } from "@cloudflare/ai-chat";
    import { convertToModelMessages, stepCountIs, streamText } from "ai";
    import { createWorkersAI } from "workers-ai-provider";
    
    export class BrowserCodemode extends AIChatAgent {
    	async onChatMessage(_onFinish, options) {
    		const workersai = createWorkersAI({ binding: this.env.AI });
    
    		const result = streamText({
    			model: workersai("@cf/moonshotai/kimi-k2.7-code"),
    			system:
    				"Use the codemode tool to write JavaScript that calls browser-provided tools.",
    			messages: await convertToModelMessages(this.messages),
    			tools: createToolsFromClientSchemas(options?.clientTools),
    			stopWhen: stepCountIs(10),
    		});
    
    		return result.toUIMessageStreamResponse();
    	}
    }
    src/server.ts
    import { AIChatAgent, createToolsFromClientSchemas } from "@cloudflare/ai-chat";
    import { convertToModelMessages, stepCountIs, streamText } from "ai";
    import { createWorkersAI } from "workers-ai-provider";
    
    export class BrowserCodemode extends AIChatAgent<Env> {
      async onChatMessage(
        _onFinish?: unknown,
        options?: {
          clientTools?: Parameters<typeof createToolsFromClientSchemas>[0];
        }
      ) {
        const workersai = createWorkersAI({ binding: this.env.AI });
    
        const result = streamText({
          model: workersai("@cf/moonshotai/kimi-k2.7-code"),
          system:
            "Use the codemode tool to write JavaScript that calls browser-provided tools.",
          messages: await convertToModelMessages(this.messages),
          tools: createToolsFromClientSchemas(options?.clientTools),
          stopWhen: stepCountIs(10)
        });
    
        return result.toUIMessageStreamResponse();
      }
    }

    Agent oznámí modelu schéma poskytnuté klientem. Nespouští vygenerovaný kód ani implementace nástroje prohlížeče.

Pokud se sada nástrojů prohlížeče za běhu změní, vytvořte nový deskriptor Code Mode a zaregistrujte aktualizovaný deskriptor ve vrstvě nástrojů klienta.

Spouštění a zabezpečení iframe

IframeSandboxExecutor vytvoří pro každé spuštění skrytý iframe. Tento iframe používá sandbox="allow-scripts" a přijímá vygenerovaný kód prostřednictvím postMessage. Volání nástrojů se vracejí na rodičovskou stránku, která spustí odpovídající nástroj vlastněný prohlížečem execute .

Zprávy jsou omezeny na aktuální iframe a spouštěcí nonce. Executor po dokončení, selhání nebo vypršení časového limitu odstraní iframe i posluchač zpráv.

Executor přijímá tyto možnosti:

Možnost Typ Výchozí Chování
timeout number 30000 Ukončí provedení po uplynutí zadaného počtu milisekund.
csp string default-src 'none'; script-src 'unsafe-inline' 'unsafe-eval'; Nastavuje zásady zabezpečení obsahu (CSP) pro dokument iframe.

Výchozí CSP blokuje všechny zdroje kromě vložených a vyhodnocovaných skriptů potřebných ke spuštění vygenerovaného kódu. Vlastní zásadu předejte pouze tehdy, pokud váš vygenerovaný kód potřebuje další možnosti iframe.

Uvolňování direktiv, jako jsou connect-src, img-src, nebo form-action může umožnit, aby vygenerovaný kód iframe komunikoval s externími systémy. Tento kód by mohl vystavit hodnoty vracené nástroji prohlížeče. Omezte cílové adresy odchozí komunikace na nezbytné minimum a nedávejte tajné údaje do výsledků nástrojů. Nástroje vlastněné prohlížečem se spouštějí odděleně na rodičovské stránce s možnostmi, které poskytuje jejich implementace.

Omezení schvalování

createBrowserCodeTool() vyloučí libovolný nástroj, jehož needsApproval hodnota je true nebo funkci. Code Mode nepozastavuje běh iframe kvůli žádosti o schválení těchto nástrojů.

Akce podléhající schválení ponechte mimo deskriptor Code Mode. Zaregistrujte je jako standardní nástroje a použijte useAgentChat() postup schvalování místo toho.