Tools

Widget anzeigen

show_widget ist ein Kernwerkzeug, das ein eigenständiges HTML-Widget auf der aktuellen Oberfläche des Benutzers anzeigt. OpenClaw rendert es inline in der Control UI sowie in Quick-Chat-Transkripten unter iOS, Android, macOS und Linux; das Linux-Dashboard verwendet die browserbasierte Control UI. In einer Discord-Sitzung mit aktivierten Activities veröffentlicht das Discord-Plugin eine Schaltfläche Open widget, die es als Activity startet.

Funktionsweise von Widgets

Wenn der Agent show_widget aufruft, umschließt der OpenClaw-Kern widget_code mit einem minimalen HTML-Dokument, speichert es als Canvas-Dokument und gibt ein Vorschau-Handle zurück. Die Control UI rendert dieses Handle in einem Sandbox-iframe, während der Quick Chat unter iOS, Android, macOS und Linux isolierte WebViews verwendet. Vollständige Chat-Clients stellen das Widget nach dem erneuten Laden des Verlaufs wieder her; Quick Chat behält das Widget für seine aktive Antwort bei.

In Control-UI-Sitzungen kann ein Canvas-Widget auch an das Sitzungs-Dashboard angeheftet werden. Legen Sie im Werkzeugaufruf pin: true fest oder verwenden Sie An Dashboard anheften bei einem vorhandenen Transkript-Widget. Angeheftetes HTML wird hinter demselben Sandbox-Host mit dediziertem Ursprung und doppeltem iframe ausgeführt, der auch von MCP Apps verwendet wird; der Browser löst niemals eine Widget-Datenbindung innerhalb des nicht vertrauenswürdigen Frames auf.

Für die Einbettung im Browser fügt das Wrapper-Dokument vier kleine Host-Bridges rund um den Widget-Code ein:

  • Ein Größenmelder übermittelt die Höhe des gerenderten Inhalts an den einbettenden Chat, der sie begrenzt und den iframe anpasst (160 bis 1200 Pixel).
  • Eine Host-Bridge definiert den veralteten sendPrompt(text)-Helper sowie die strukturierten APIs openclaw.prompt, openclaw.state, openclaw.data und openclaw.cron. Inline-Chat-Prompts behalten ihren privaten Nachrichtenkanal; Dashboard-APIs verwenden einen an ein Ansichtsticket gebundenen Anfragekanal. Siehe Interaktive Widgets und Dashboard-Funktionen.
  • Eine Theme-Bridge überwacht die aktuellen Design-Tokens der Control UI und wendet sie beim Laden sowie erneut bei jeder Theme-Änderung als CSS-Variablen an.
  • Eine Snapshot-Bridge rendert das aktuelle Widget-Dokument als PNG, wenn der einbettende Chat einen Export anfordert.

Alles andere verbleibt innerhalb des Frames: Das Dokument wird unter einem undurchsichtigen Ursprung mit einer strikten Content Security Policy ausgeführt, sodass Widget-Skripte weder auf die Control UI noch auf den Gateway oder das Netzwerk zugreifen können.

Die Kernimplementierung ist nur verfügbar, wenn der ursprüngliche Gateway-Client die Fähigkeit inline-widgets deklariert. Die Control UI und unterstützte native Apps deklarieren diese Fähigkeit automatisch. Linux Quick Chat bleibt bei Gateway-Verbindungen, die eine benutzerdefinierte TLS-Leaf-Pinbindung erfordern, auf Text beschränkt, da die WebView der Plattform diesen Pin nicht binden kann. Die Discord-Implementierung ist nur in Discord-Sitzungen mit konfigurierten Activities verfügbar. Andere Kanalausführungen erhalten show_widget nicht.

Der Fähigkeitstransport deckt eingebettete, Codex-App-Server- und CLI-gestützte Modell-Backends ab. Durch Grants authentifizierte MCP-Aufrufer und direkte HTTP-Werkzeugaufrufer bleiben standardmäßig gesperrt, da sie keine Client-Fähigkeiten deklarieren.

Designsystem

Jedes Canvas-Widget enthält ein klassenloses Basis-Stylesheet und einen kleinen Satz von Tokens:

Token Zweck
--surface Oberflächenfarbe auf Seitenebene
--card Hintergrund für Karten, Schaltflächen und Code
--elevated Hervorgehobener Hintergrund für Formularelemente
--text Standardtext für Inhalt und Steuerelemente
--text-strong Überschriften und hervorgehobene Werte
--muted Sekundärtext und dezente Rahmen
--border Standardtrennlinien und Kartenrahmen
--border-strong Kräftige Rahmen für Steuerelemente
--accent Links und Fokusringe
--accent-fill Füllfarbe für primäre Aktionen
--accent-fg Text auf einer primären Aktion
--ok Erfolgsstatus
--warn Warnstatus
--danger Fehler- oder destruktiver Status
--info Informationsstatus
--radius Gemeinsamer Eckenradius für Steuerelemente und Karten
--font-body Schriftartenfolge des Hosts für Fließtext
--font-mono Monospace-Schriftartenfolge des Hosts
--accent-subtle, --ok-subtle, --warn-subtle, --danger-subtle, --info-subtle Abgeleitete durchscheinende Statushintergründe

Unformatierte Überschriften, Absätze, Links, Schaltflächen, Eingabefelder, Auswahllisten, Textbereiche, Tabellen und Codeblöcke erhalten Basisstile. Hilfsklassen stellen gängige Muster bereit:

  • .card für eine umrahmte Inhaltsfläche
  • .badge sowie .ok, .warn, .danger oder .info für kompakte Statusbeschriftungen
  • .metric für einen hervorgehobenen numerischen Wert
  • .muted für Sekundärtext
  • .row für ein umbrechendes horizontales Layout
  • button.primary für die primäre Aktion

Die Control UI sendet beim Laden eines Widgets und bei jeder Theme-Änderung eine openclaw:widget-theme-Nachricht mit den aktiven Theme-Werten. Widgets übernehmen daher ohne erneutes Laden jede Theme-Familie, einschließlich Claw, Knot, Dash und benutzerdefinierter Themes. Außerhalb der Control UI, einschließlich nativer Apps und direkter Aufrufe, verwenden Widgets die durch prefers-color-scheme ausgewählte integrierte helle oder dunkle Palette.

Erstellen Sie Widgets nach drei Regeln:

  1. Verwenden Sie die Designvariablen für jede Farbe und jeden Hintergrund. Codieren Sie keine Farbwerte fest.
  2. Halten Sie den Seitenhintergrund transparent, damit das Widget zu seiner Host-Oberfläche gehört.
  3. Reservieren Sie --accent-fill für höchstens eine primäre Aktion.

Export: Öffnen Sie im Webchat das Menü der Widget-Karte, um das gerenderte Widget in die Zwischenablage zu kopieren oder als PNG herunterzuladen. Bei älteren Widget-Dokumenten ohne Snapshot-Bridge wird stattdessen eine HTML-Datei heruntergeladen.

Werkzeug verwenden

Beide Implementierungen verwenden dieselben Pflichtfelder:

titlestringrequired

Kurzer Titel, der mit der Inline-Vorschau und als Titel des gehosteten Dokuments angezeigt wird.

widget_codestringrequired

Eigenständiges HTML oder SVG. Bei Inline-Widget-Clients werden Eingaben, die nach dem Entfernen von Leerraum mit <svg beginnen, im SVG-Modus gerendert; die maximale Länge beträgt 262.144 Zeichen. Discord akzeptiert ein vollständiges HTML-Dokument oder ein Body-Fragment mit bis zu 48 KiB.

Discord akzeptiert außerdem optionalen button_label-Text für die Startschaltfläche der Activity. Das Canvas-Schema lässt dieses ausschließlich für Discord vorgesehene Feld absichtlich aus.

Das Canvas-Kernwerkzeug akzeptiert diese optionalen Felder für die Dashboard-Platzierung:

  • pin: Platziert das Widget zusätzlich auf dem Sitzungs-Dashboard.
  • name: Stabiler Widget-Name; standardmäßig ein Slug von title.
  • tab: Slug des Ziel-Tabs.
  • size: Einer der Werte sm, md, lg, xl oder full.
  • after: Name des gleichgeordneten Widgets, hinter dem das Widget platziert werden soll.
  • capabilities: Von einem angehefteten Widget angeforderter Zugriff. netOrigins enthält exakte HTTPS-Ursprünge; tools enthält prompt, eine auf der Positivliste stehende Lesebindung oder eine exakte cron.trigger:<jobId>-Aktion.

Das Kernergebnis enthält ein Canvas-Vorschau-Handle, sodass die Control UI und unterstützte native Apps das Widget direkt aus dem Werkzeugaufruf rendern und nach dem erneuten Laden des Verlaufs wiederherstellen. Angeheftete Ergebnisse behalten außerdem den Namen des Board-Widgets bei, sodass die Control UI nach dem erneuten Laden des Transkripts keine doppelte Anheftung anbietet. Discord gibt die Kennungen des gespeicherten Widgets und der veröffentlichten Nachricht zurück.

discord_widget bleibt für eine Version als veralteter Alias registriert. Neue Agentenaufrufe sollten show_widget verwenden.

Interaktive Widgets

In der Control UI können Widget-Skripte die Konversation steuern. Das Wrapper-Dokument definiert eine globale Funktion sendPrompt(text); ihr Aufruf sendet text an den Chat, als hätte der Benutzer die Nachricht eingegeben und gesendet. Verknüpfen Sie sie mit Schaltflächen oder anderen Steuerelementen, um interaktive Abläufe wie Auswahldialoge, Quizze oder Drill-down-Dashboards zu erstellen. Native Apps rendern interaktiven Widget-Code, stellen diese Chat-Prompt-Bridge jedoch nicht bereit.

html
<button onclick="sendPrompt('Fehlgeschlagene Tests im Detail anzeigen')">Fehlgeschlagene Tests</button>

Jeder Prompt wird auf beiden Seiten der Frame-Grenze validiert:

  • sendPrompt erfordert eine vorübergehende Benutzeraktivierung innerhalb des Widgets: Die Funktion arbeitet nur wenige Sekunden, nachdem der Benutzer im Widget geklickt oder eine Taste gedrückt hat. Verknüpfen Sie sie daher mit Schaltflächen und anderen Klickzielen — ein automatischer Aufruf beim Laden bleibt wirkungslos. Die Bridge hält den sendenden Endpunkt für sich privat und sperrt standardmäßig Browser, die keine Benutzeraktivierung bereitstellen, sodass Widget-Code die Prüfung nicht umgehen kann.
  • Die Prompt-Berechtigung gehört ausschließlich dem ursprünglichen Widget-Dokument. Die vertrauenswürdige Bridge bietet dem Chat ihren Kanalendpunkt an, bevor Widget-Code ausgeführt oder der Frame navigiert werden kann. Der Chat übernimmt nur dieses erste Angebot, und der Kanal endet bei einer Navigation zusammen mit dem Dokument. Extern zugelassene Einbettungs-URLs werden niemals übernommen.
  • Der Widget-Frame muss im Chat-Transkript sichtbar sein und den Fokus besitzen — ein zusätzliches vom Host beobachtetes Signal dafür, dass der Benutzer tatsächlich mit diesem Widget interagiert.
  • Der Text darf nach dem Entfernen von Leerraum nicht leer sein und höchstens 4.000 Zeichen enthalten.
  • Prompts, die mit / beginnen, werden abgelehnt, sodass Widget-Code keine Chatbefehle wie /approve oder /stop auslösen kann.
  • Jedes Widget-Dokument darf innerhalb eines gleitenden Zeitfensters von einer Minute höchstens 10 Prompts senden; darüber hinausgehende Prompts werden stillschweigend verworfen.

Akzeptierte Prompts erscheinen im Transkript als reguläre Benutzernachrichten und starten einen normalen Agentendurchlauf in der Sitzung, zu der das Widget gehört. Es gibt keinen Rückkanal zum Widget: Ein verworfener Prompt schlägt ohne Meldung fehl, und das Widget kann die Antwort des Agenten nicht lesen.

Dashboard-Funktionen

Angeheftete Widgets können eine an ein Ticket gebundene Host-API verwenden, nachdem der Betreiber die auf der ausstehenden Karte angezeigte Deklaration geprüft hat:

  • openclaw.prompt.send(text) erfordert eine vorübergehende Benutzeraktivierung und veröffentlicht eine sichtbare Nachricht im Eingabefeld. Durch das Deklarieren und Empfangen der Tool-Berechtigung prompt entfällt die zusätzliche Bestätigung bei jedem Klick; Validierung, Fokusprüfungen und Ratenbegrenzungen gelten weiterhin.
  • openclaw.state.emit(payload) fügt einen Sitzungshinweis hinzu. Nutzdaten sind auf 8 KiB begrenzt, und identische Client-Übertragungen innerhalb von fünf Sekunden werden zusammengeführt.
  • openclaw.data.read(bindingId, params?) wird nur am Gateway aufgelöst. Erteilbare Bindungen sind sessions.list, usage.status, usage.cost, cron.list, cron.status, agents.list und health.
  • openclaw.cron.trigger(jobId) führt einen vorhandenen Auftrag nur dann sofort aus, wenn exakt die Fähigkeit cron.trigger:<jobId> erteilt wurde.

Der Netzwerkzugriff ist von Host-Tools getrennt. Tragen Sie exakte HTTPS-Ursprünge in capabilities.netOrigins ein; nach der Genehmigung werden nur diese Ursprünge in connect-src des Widgets aufgenommen. Platzhalter, Anmeldedaten, Pfade, Abfragezeichenfolgen und nicht deklarierte Ursprünge bleiben blockiert. Ein wörtlich angegebener Port ist nur zulässig, wenn er Teil des deklarierten Ursprungs ist.

Sicherheit und Speicherung

Widget-Dokumente verwenden restriktive Content-Security-Policies. Inline-Stile und -Skripte sind zulässig, während das Laden externer Ressourcen blockiert bleibt. Inline-Transkript-Widgets können nicht auf das Netzwerk zugreifen. Ein angeheftetes Dashboard-Widget kann nur exakte HTTPS-Ursprünge abrufen, die der Agent deklariert und der Betreiber genehmigt hat.

Beim Control-UI-iframe wird allow-same-origin immer ausgelassen, selbst wenn der globale Einbettungsmodus trusted ist, sodass Widget-Skripte den Ursprung der übergeordneten Anwendung nicht lesen können. Native Clients verwenden isolierte, nicht persistente Webansichten und blockieren die Navigation weg vom gehosteten Widget. Der Host des Kerndokuments stellt Widgets außerdem mit einem Content-Security-Policy: sandbox allow-scripts-Antwortheader bereit, sodass das Widget auch bei direkter Darstellung in einem undurchsichtigen Ursprung statt in einem Anwendungsursprung ausgeführt wird. Stellen Sie nur Widget-Code dar, den Sie in diesem isolierten Frame auszuführen bereit sind.

Der iframe folgt außerdem gateway.controlUi.embedSandbox. Die standardmäßige Stufe scripts unterstützt interaktive Widgets und bewahrt zugleich die Ursprungsisolation.

Das akzeptierte Restrisiko für ausgehenden Datenverkehr über WebRTC-Datenkanäle ist unter Dashboard-Architektur dokumentiert.

Canvas behält höchstens 32 Widgets pro Sitzung bei (oder pro Agent, wenn keine Sitzung verfügbar ist). Beim Erstellen eines weiteren Widgets wird das älteste Dokument in diesem Geltungsbereich entfernt.

Verwandte Themen

Was this useful?
On this page

On this page