UIAP Core
UIAP Core v0.1
Abschnitt betitelt „UIAP Core v0.1“| Feld | Wert |
|---|---|
| Status | Draft |
| Version | 0.1 |
| Datum | 2026-03-27 |
| Abhängigkeiten | — |
| Editoren | Patrick |
1. Zweck und Geltungsbereich
Abschnitt betitelt „1. Zweck und Geltungsbereich“UIAP (UI Control Protocol) ist ein transport-agnostisches Protokoll zwischen einer laufenden Anwendung und einem KI-Agenten oder Agent-Bridge-Layer.
UIAP Core v0.1 definiert:
- die gemeinsame Nachrichtenhülle
- Sitzungsaufbau und Sitzungslebenszyklus
- Fehlerformat und Fehlercodes
- Versionsaushandlung
- Erweiterungsmechanismus
- Capability-Discovery auf hoher Ebene
UIAP Core v0.1 definiert nicht:
- konkrete Web-/DOM-/ARIA-Semantik
- konkrete Browser-Steuerung
- Policy- oder Sicherheitsregeln im Detail
- Workflow-/Skill-Definitionen
- visuelle Präsentation wie Ghost Cursor oder Highlights
Diese Dinge gehören in Profile oder Erweiterungen.
2. Normative Begriffe
Abschnitt betitelt „2. Normative Begriffe“Die Schlüsselwörter MUSS, DARF NICHT, SOLLTE, KANN in diesem Dokument sind normativ gemäss RFC 2119 und BCP 14 zu interpretieren, wenn und nur wenn sie in GROSSBUCHSTABEN erscheinen.
3. Grundprinzipien
Abschnitt betitelt „3. Grundprinzipien“- UIAP ist transport-agnostisch. Es KANN über WebSocket, WebRTC DataChannel,
postMessage, lokale IPC oder andere Bindings transportiert werden. - UIAP-Nachrichten sind UTF-8 kodierte JSON-Objekte.
- Jede UIAP-Nachricht MUSS eine gemeinsame Envelope verwenden.
- UIAP Core ist strict-by-envelope, flexible-by-payload: Pflichtfelder MÜSSEN validiert werden; unbekannte optionale Felder SOLLTEN ignoriert werden.
- UIAP trennt Protokollvertrag von Ausführungsmechanik.
4. Datentypen
Abschnitt betitelt „4. Datentypen“4.1 Primitive Typen
Abschnitt betitelt „4.1 Primitive Typen“type Version = string; // Format: "major.minor", z. B. "0.1"type Timestamp = string; // ISO-8601 UTC, z. B. "2026-03-26T13:12:09.123Z"type MessageId = string; // 1..128 Zeichen, innerhalb einer Session eindeutigtype SessionId = string; // 1..128 Zeichen, vom Session-Owner vergebentype ExtensionId = string; // z. B. "uiap.policy" oder "x.vendor.foo"type MessageType = string; // z. B. "session.initialize"type JsonObject = Record<string, unknown>;4.2 Identifikatoren
Abschnitt betitelt „4.2 Identifikatoren“MessageIdMUSS innerhalb einer Session eindeutig sein.SessionIdMUSS pro aktiver Session eindeutig sein.- Vendor-spezifische Kennungen SOLLTEN stabil und menschenlesbar sein.
- Erweiterungsnamen SOLLTEN kleingeschrieben und punkt-segmentiert sein, z. B.
uiap.policyoderx.acme.billing.
5. Message Envelope
Abschnitt betitelt „5. Message Envelope“Jede Nachricht MUSS diese Hülle verwenden.
interface UIAPEnvelope { uiap: Version; // Protokollversion dieser Nachricht kind: "request" | "response" | "event" | "error"; type: MessageType; // z. B. "session.initialize" id: MessageId; sessionId?: SessionId; // vor Session-Init optional correlationId?: MessageId; // Pflicht für response/error ts: Timestamp; source: EndpointRef; target?: EndpointRef; seq?: number; // optional, für ungeordnete Transporte requires?: string[]; // benötigte Profile/Extensions payload: JsonObject; // NIE null, IMMER Objekt ext?: Record<ExtensionId, unknown>; // optionale Extension-Daten}interface EndpointRef { role: "app" | "agent" | "bridge" | "observer" | string; id: string; instanceId?: string;}5.1 Envelope-Regeln
Abschnitt betitelt „5.1 Envelope-Regeln“uiap,kind,type,id,ts,source,payloadMÜSSEN vorhanden sein.payloadMUSS ein JSON-Objekt sein, auch wenn es leer ist.correlationIdMUSS beiresponseunderrorgesetzt sein.sessionIdDARF beisession.initializefehlen; danach SOLLTE es immer vorhanden sein.extDARF nur Erweiterungsdaten enthalten. Core-Felder DÜRFEN NICHT überextüberschrieben werden.- Unbekannte optionale Felder SOLLTEN ignoriert werden.
- Sender SOLLTEN optionale Felder lieber weglassen als
nullsenden, sofernnullkeine eigene Semantik hat.
5.2 kind-Semantik
Abschnitt betitelt „5.2 kind-Semantik“request: erwartet genau eineresponseodererrorresponse: erfolgreiche Antwort auf einerequestevent: unidirektionale Zustands- oder Statusmeldung, ohne Pflichtantworterror: fehlgeschlagene Bearbeitung einerrequest
5.3 type-Namensraum
Abschnitt betitelt „5.3 type-Namensraum“Core reserviert:
session.*capabilities.*error
Erweiterungen MÜSSEN ihren eigenen Namensraum verwenden, z. B.:
uiap.policy.*uiap.workflow.*x.vendor.feature.*
6. Session Lifecycle
Abschnitt betitelt „6. Session Lifecycle“6.1 Session-Zustände
Abschnitt betitelt „6.1 Session-Zustände“Eine UIAP-Session hat genau einen dieser Zustände:
NEWINITIALIZINGACTIVEINTERRUPTEDTERMINATINGTERMINATED
6.2 Zustandsübergänge
Abschnitt betitelt „6.2 Zustandsübergänge“NEW -> INITIALIZINGdurchsession.initializeINITIALIZING -> ACTIVEdurchsession.initializedACTIVE -> INTERRUPTEDdurchsession.interrupt/session.interruptedINTERRUPTED -> ACTIVEdurchsession.resume/session.resumedACTIVE|INTERRUPTED -> TERMINATINGdurchsession.terminateTERMINATING -> TERMINATEDdurchsession.terminated- Jeder Zustand KANN bei fatalem Transportfehler direkt zu
TERMINATEDwechseln
6.3 Handshake-Regeln
Abschnitt betitelt „6.3 Handshake-Regeln“- Eine Session MUSS mit
session.initializebegonnen werden. - Die Gegenstelle MUSS mit
session.initializedodererrorantworten. - Vor erfolgreichem Handshake DÜRFEN keine nicht-Session-Core-Nachrichten verarbeitet werden.
- Capability-Informationen KÖNNEN inline im Handshake oder nachgelagert geliefert werden.
7. Core Message Types
Abschnitt betitelt „7. Core Message Types“7.1 session.initialize
Abschnitt betitelt „7.1 session.initialize“Startet eine Session und verhandelt Versionen, Profile und Erweiterungen.
Request
Abschnitt betitelt „Request“interface SessionInitializePayload { supportedVersions: Version[]; // non-empty supportedExtensions?: ExtensionOffer[]; capabilityDelivery?: "inline" | "deferred" | "none"; peer: PeerInfo; metadata?: JsonObject;}interface PeerInfo { role: "app" | "agent" | "bridge" | string; name?: string; version?: string; locale?: string; timezone?: string; tenantId?: string; userRole?: string;}interface ExtensionOffer { id: ExtensionId; versions: Version[]; required?: boolean;}Response: session.initialized
Abschnitt betitelt „Response: session.initialized“interface SessionInitializedPayload { sessionId: SessionId; selectedVersion: Version; selectedProfiles?: string[]; selectedExtensions?: SelectedExtension[]; capabilityDelivery: "inline" | "deferred" | "none"; heartbeatMs?: number; resumeToken?: string; capabilities?: CapabilityDocument; // nur bei capabilityDelivery="inline" metadata?: JsonObject;}interface SelectedExtension { id: ExtensionId; version: Version;}supportedVersionsMUSS mindestens einen Eintrag enthalten.- Wenn ein Sender eine Erweiterung als
required=truemarkiert und sie nicht ausgewählt wird, MUSS der Handshake fehlschlagen. selectedVersionMUSS exakt einer vom Initiator angebotenen und vom Empfänger unterstützten Version entsprechen.selectedProfilesDÜRFEN leer sein, wenn nur Core genutzt wird.capabilitiesDARF nur enthalten sein, wenncapabilityDelivery = "inline".
7.2 session.resume
Abschnitt betitelt „7.2 session.resume“Nimmt eine bestehende Session wieder auf.
Request
Abschnitt betitelt „Request“interface SessionResumePayload { sessionId: SessionId; resumeToken: string; metadata?: JsonObject;}Response: session.resumed
Abschnitt betitelt „Response: session.resumed“interface SessionResumedPayload { sessionId: SessionId; selectedVersion: Version; selectedProfiles?: string[]; selectedExtensions?: SelectedExtension[]; heartbeatMs?: number; metadata?: JsonObject;}resumeTokenist opak und wird vom Session-Owner definiert.- Wenn
resumeTokenungültig ist, MUSSerrormitcode="unknown_session"odercode="permission_denied"zurückgegeben werden.
7.3 session.interrupt
Abschnitt betitelt „7.3 session.interrupt“Unterbricht eine aktive Session, ohne sie zu beenden.
Request
Abschnitt betitelt „Request“interface SessionInterruptPayload { reason?: string; by?: "user" | "system" | "policy" | "transport" | string; metadata?: JsonObject;}Response: session.interrupted
Abschnitt betitelt „Response: session.interrupted“interface SessionInterruptedPayload { status: "interrupted"; reason?: string;}- Im Zustand
INTERRUPTEDDÜRFEN nur Session-Nachrichten verarbeitet werden, sofern kein Profil etwas anderes definiert.
7.4 session.ping
Abschnitt betitelt „7.4 session.ping“Liveness-Prüfung.
Request
Abschnitt betitelt „Request“interface SessionPingPayload { nonce?: string;}Response: session.pong
Abschnitt betitelt „Response: session.pong“interface SessionPongPayload { nonce?: string;}- Wenn
heartbeatMsausgehandelt wurde, SOLLTE jede Seite bei Leerlaufsession.pingsenden. - Bleibt eine Gegenantwort wiederholt aus, DARF die Session beendet werden.
7.5 session.terminate
Abschnitt betitelt „7.5 session.terminate“Beendet die Session geordnet.
Request
Abschnitt betitelt „Request“interface SessionTerminatePayload { reason?: "normal" | "timeout" | "error" | "policy" | "disconnect" | string; metadata?: JsonObject;}Response: session.terminated
Abschnitt betitelt „Response: session.terminated“interface SessionTerminatedPayload { status: "terminated"; reason?: string;}- Nach
session.terminatedDÜRFEN keine weiteren nicht-terminierenden UIAP-Nachrichten mehr verarbeitet werden.
7.6 capabilities.get
Abschnitt betitelt „7.6 capabilities.get“Fordert das Capability-Dokument an.
Request
Abschnitt betitelt „Request“interface CapabilitiesGetPayload { include?: Array<"roles" | "states" | "affordances" | "actions" | "risk" | "signals" | "all">;}Response: capabilities.list
Abschnitt betitelt „Response: capabilities.list“interface CapabilitiesListPayload { revision?: string; capabilities: CapabilityDocument;}- Wenn
includefehlt, MUSS das vollständige Capability-Dokument geliefert werden. revisionKANN für Caching und Change Detection genutzt werden.
7.7 capabilities.changed
Abschnitt betitelt „7.7 capabilities.changed“Meldet eine geänderte Capability-Lage.
interface CapabilitiesChangedPayload { revision: string; reason?: "app_update" | "role_change" | "feature_flag" | "configuration" | string; capabilities: CapabilityDocument;}- In v0.1 MUSS
capabilities.changedimmer ein vollständiges Ersatzdokument liefern, keine Patches. - Empfänger SOLLTEN das alte Dokument vollständig ersetzen.
8. Fehlermodell
Abschnitt betitelt „8. Fehlermodell“Fehler werden als kind="error" gesendet.
Envelope-Regeln für Fehler
Abschnitt betitelt „Envelope-Regeln für Fehler“typeMUSS"error"sein.correlationIdMUSS auf die fehlgeschlagene Request zeigen.
Error Payload
Abschnitt betitelt „Error Payload“interface UIAPErrorPayload { code: ErrorCode; message: string; retryable?: boolean; failedType?: string; details?: JsonObject;}Core Error Codes
Abschnitt betitelt „Core Error Codes“type ErrorCode = | "bad_request" | "invalid_message" | "unknown_message_type" | "unsupported_version" | "unsupported_profile" | "unsupported_extension" | "unknown_session" | "session_not_active" | "permission_denied" | "capability_unavailable" | "timeout" | "rate_limited" | "state_conflict" | "internal_error";Fehlersemantik
Abschnitt betitelt „Fehlersemantik“bad_request: formal gültige Envelope, aber semantisch unzulässiger Requestinvalid_message: Envelope oder Payload strukturell ungültigunknown_message_type:typeunbekannt oder in aktuellem Zustand unzulässigunsupported_version: keine kompatible Version verfügbarunsupported_profile: angeforderte oder erforderliche Profile fehlenunsupported_extension: erforderliche Extension fehlt oder falsche Versionunknown_session: Session nicht bekannt oder nicht wiederaufnehmbarsession_not_active: Nachricht in falschem Session-Zustandpermission_denied: Auth-/Policy-Verletzungcapability_unavailable: gewünschte Fähigkeit ist nicht deklariert oder nicht aktivtimeout: Anfrage oder Ausführung lief in Timeoutrate_limited: Empfänger begrenzt den Trafficstate_conflict: Request passt nicht mehr zum aktuellen Zustandinternal_error: unerwarteter interner Fehler
Fehlerregeln
Abschnitt betitelt „Fehlerregeln“- Auf eine
requestMUSS entwederresponseodererrorfolgen. - Fehlercodes DÜRFEN durch Erweiterungen ergänzt werden.
- Vendor-spezifische Fehler SOLLTEN namespaced sein, z. B.
x.vendor.foo_error.
9. Versionierung
Abschnitt betitelt „9. Versionierung“9.1 Versionsformat
Abschnitt betitelt „9.1 Versionsformat“UIAP Core v0.1 verwendet major.minor.
Beispiele:
0.10.21.0
9.2 Aushandlung
Abschnitt betitelt „9.2 Aushandlung“- Der Initiator MUSS in
session.initialize.supportedVersionsalle unterstützten Versionen nennen. - Der Empfänger MUSS genau eine
selectedVersionauswählen. - Nach erfolgreichem Handshake MUSS jede weitere Nachricht
uiap = selectedVersiontragen.
9.3 Kompatibilitätsregeln
Abschnitt betitelt „9.3 Kompatibilitätsregeln“Für v0.x gilt bewusst wenig Romantik:
- Gleiche Major-Version bedeutet nicht automatisch volle Kompatibilität.
- Kompatibilität entsteht erst durch explizite Aushandlung.
- Nach Aushandlung gilt die ausgewählte Version als verbindlich.
9.4 Patch-/Errata-Regel
Abschnitt betitelt „9.4 Patch-/Errata-Regel“Rein redaktionelle Änderungen SOLLTEN die Wire-Semantik nicht ändern. Wenn sich Wire-Semantik ändert, MUSS mindestens die Minor-Version steigen.
10. Erweiterungsmechanismus
Abschnitt betitelt „10. Erweiterungsmechanismus“UIAP Core ist erweiterbar.
10.1 Extension-Negotiation
Abschnitt betitelt „10.1 Extension-Negotiation“Erweiterungen werden in session.initialize.supportedExtensions angeboten und in session.initialized.selectedExtensions bestätigt.
10.2 Envelope-Feld ext
Abschnitt betitelt „10.2 Envelope-Feld ext“ext transportiert Erweiterungsdaten.
Beispiel:
{ "ext": { "uiap.policy": { "decision": "confirm_required" } }}ext-Einträge MÜSSEN nach Extension-ID gruppiert sein.- Unverhandelte optionale Erweiterungen SOLLTEN ignoriert werden.
- Wenn eine Nachricht eine Erweiterung zwingend voraussetzt, MUSS sie diese in
requiresnennen. - Trifft eine Nachricht mit unerfülltem
requiresein, MUSSunsupported_extensionoderunsupported_profilezurückgegeben werden. - Erweiterungen DÜRFEN Core-Felder nicht umdefinieren.
10.3 Erweiterte Nachrichtentypen
Abschnitt betitelt „10.3 Erweiterte Nachrichtentypen“Erweiterungen DÜRFEN neue type-Namespaces definieren, z. B.:
uiap.policy.evaluateuiap.workflow.startx.vendor.analytics.sample
11. Minimale Core-Konformität
Abschnitt betitelt „11. Minimale Core-Konformität“Eine UIAP Core v0.1-konforme Implementierung MUSS:
- Envelope validieren
session.initializeverarbeitensession.terminateverarbeitensession.ping/session.pongunterstützencapabilities.get/capabilities.listunterstützen- Fehler im definierten Format senden
- unbekannte optionale Felder ignorieren
- Versionen, Profile und Extensions verhandeln können
12. Minimaler Beispiel-Handshake
Abschnitt betitelt „12. Minimaler Beispiel-Handshake“12.1 Request
Abschnitt betitelt „12.1 Request“{ "uiap": "0.1", "kind": "request", "type": "session.initialize", "id": "msg_1", "ts": "2026-03-26T13:00:00.000Z", "source": { "role": "agent", "id": "agent-runtime" }, "payload": { "supportedVersions": ["0.1"], "supportedExtensions": [ { "id": "uiap.policy", "versions": ["0.1"], "required": false } ], "capabilityDelivery": "deferred", "peer": { "role": "agent", "name": "onboarding-agent", "version": "0.1.0", "locale": "de-CH", "timezone": "Europe/Zurich" } }}12.2 Response
Abschnitt betitelt „12.2 Response“{ "uiap": "0.1", "kind": "response", "type": "session.initialized", "id": "msg_2", "correlationId": "msg_1", "sessionId": "sess_123", "ts": "2026-03-26T13:00:00.040Z", "source": { "role": "app", "id": "videoland-app" }, "payload": { "sessionId": "sess_123", "selectedVersion": "0.1", "selectedExtensions": [ { "id": "uiap.policy", "version": "0.1" } ], "capabilityDelivery": "deferred", "heartbeatMs": 15000 }}Normative Referenzen
Abschnitt betitelt „Normative Referenzen“- [RFC2119] Key words for use in RFCs to Indicate Requirement Levels, BCP 14
Security Considerations
Abschnitt betitelt „Security Considerations“- Transport-Sicherheit ist nicht Teil von UIAP Core; die Absicherung des Transportkanals (z.B. TLS für WebSocket) MUSS vom Binding sichergestellt werden.
- Session-Tokens (
resumeToken) SOLLTEN kryptographisch zufällig und kurzlebig sein. ext-Felder DÜRFEN NICHT dazu verwendet werden, Sicherheitsmechanismen zu umgehen.- Implementierungen SOLLTEN Rate-Limiting für eingehende Nachrichten unterstützen.
Changelog
Abschnitt betitelt „Changelog“| Version | Datum | Änderungen |
|---|---|---|
| 0.1 | 2026-03-27 | Initialer Entwurf |