Playbook-Tools

Mit Tools können Sie Playbooks mit externen Systemen verbinden. Diese Systeme können das Wissen von Playbooks erweitern und ihnen ermöglichen, komplexe Aufgaben effizient auszuführen.

Sie können integrierte Tools verwenden oder benutzerdefinierte Tools erstellen, die Ihren Anforderungen entsprechen.

Tool testen

Nachdem Sie ein Tool erstellt haben, können Sie mit der Funktion zum Testen von Tools prüfen, ob es funktioniert. Klicken Sie beim Aufrufen eines Tools über dem Toolbereich auf die Schaltfläche Testen. Dadurch wird das Tool für die Eingabe im Simulator geöffnet. Geben Sie die Tool-Eingabe an und klicken Sie dann auf Ausgabe ansehen, um die korrekte Tool-Ausgabe zu prüfen.

Sie können die Funktion zum Testen von Tools auch verwenden, wenn Sie einem Beispiel ein Tool hinzufügen.

Integrierte Tools

Integrierte Tools werden von Google gehostet. Sie können diese Tools in KI-Agenten aktivieren, ohne dass eine manuelle Konfiguration erforderlich ist.

Die unterstützten integrierten Tools sind:

  • Code Interpreter: Ein Google-Tool, das die Capability zur Codegenerierung und Code-Ausführung kombiniert und dem Nutzer verschiedene Tasks ermöglicht, darunter Datenanalyse, Datenvisualisierung, Textverarbeitung, Lösen von Gleichungen oder Optimierungsproblemen.

Ihr KI-Agent ist so optimiert, dass er ermitteln kann, wie und wann diese Tools aufgerufen werden sollen. Sie können jedoch zusätzliche Beispiele für Ihre Anwendungsfälle bereitstellen.

Beispiele sollten ein Schema wie das folgende haben:

{
  "toolUse": {
    "tool": "projects/PROJECT_ID/locations/LOCATION_ID/agents/AGENT_ID/tools/df-code-interpreter-tool",
    "action": "generate_and_execute",
    "inputParameters": [
      {
        "name": "generate_and_execute input",
        "value": "4 + 4"
      }
    ],
    "outputParameters": [
      {
        "name": "generate_and_execute output",
        "value": {
          "output_files": [
            {
              "name": "",
              "contents": ""
            }
          ],
          "execution_result": "8",
          "execution_error": "",
          "generated_code": "GENERATED_CODE"
        }
      }
    ]
  }
}

OpenAPI-Tools

Ein KI-Agent kann sich über ein OpenAPI-Tool mit einer externen API verbinden, wenn das OpenAPI Schema bereitgestellt wird. Standardmäßig ruft der KI-Agent die API in Ihrem Namen auf.

Sie können mit der Funktion „Tool testen“ auf der Toolseite prüfen, ob das Tool richtig eingerichtet ist. Diese Funktion ist auch in der Beispielansicht verfügbar, wenn Sie dem Beispiel einen Toolaufruf hinzufügen.

Alternativ können Sie OpenAPI-Tools auf der Clientseite ausführen.

Beispielschema:

openapi: 3.0.0
info:
  title: Simple Pets API
  version: 1.0.0
servers:
  - url: 'https://api.pet-service-example.com/v1'
paths:
  /pets/{petId}:
    get:
      summary: Return a pet by ID.
      operationId: getPet
      parameters:
        - in: path
          name: petId
          required: true
          description: Pet id
          schema:
            type: integer
      responses:
        200:
          description: OK
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      parameters:
        - name: petName
          in: query
          required: false
          description: Pet name
          schema:
            type: string
        - name: label
          in: query
          description: Pet label
          style: form
          explode: true
          required: false
          schema:
            type: array
            items:
              type: string
        - name: X-OWNER
          in: header
          description: Optional pet owner provided in the HTTP header
          required: false
          schema:
            type: string
        - name: X-SESSION
          in: header
          description: Dialogflow session id
          required: false
          schema:
            $ref: "@dialogflow/sessionId"
      responses:
        '200':
          description: An array of pets
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
    post:
      summary: Create a new pet
      operationId: createPet
      requestBody:
        description: Pet to add to the store
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
      responses:
        '201':
          description: Pet created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        owner:
          type: string
        label:
          type: array
          items:
            type: string

Optional können Sie die interne Schemareferenz @dialogflow/sessionId als Schematyp für Parameter verwenden. Mit diesem Schematyp für Parameter wird die Dialogflow-Sitzungs-ID für die aktuelle Unterhaltung als Parameterwert angegeben.

Beispiel:

- name: X-SESSION
   in: header
   description: Dialogflow session id
   required: false
   schema:
     $ref: "@dialogflow/sessionId"

Einschränkungen von OpenAPI-Tools

Es gelten folgende Einschränkungen:

  • Unterstützte Parametertypen sind path, query und header. Der Parametertyp cookie wird nicht unterstützt.
  • Parameter, die durch das OpenAPI-Schema definiert werden, unterstützen die folgenden Datentypen: string, number, integer, boolean und array. Der Typ object wird nicht unterstützt.
  • Sie können im Beispiel-Editor der Konsole keine Abfrageparameter angeben.
  • Anfrage- und Antworttext müssen leer oder JSON sein.

OpenAPI-Toolschema generieren

Wenn Sie ein Schema bereitstellen, können Sie mit der Schaltfläche Gemini verwenden generative KI verwenden, um Ihr Schema zu erstellen.

Sie können Folgendes angeben, um die Generierung zu steuern:

  • Eine URL der Anfrage
  • Eine HTTP-Methode (GET, POST usw.)
  • Beispieleingabe
  • Beispielausgabe
  • Ein Text-Prompt, der das Tool beschreibt

Sobald das Schema generiert wurde, können Sie es nach Bedarf bearbeiten und manuell zusätzliche URLs und Methoden hinzufügen.

API-Authentifizierung für OpenAPI-Tools

Die folgenden Authentifizierungsoptionen werden beim Aufrufen einer externen API unterstützt.

Authentifizierung mit dem Dialogflow-Dienst-Agent

Dialogflow kann mit dem Dialogflow-Dienst-Agentein ID-Tokengenerieren. Das Token wird im HTTP-Autorisierungsheader hinzugefügt, wenn Dialogflow eine externe API aufruft.

Ein ID-Token kann für den Zugriff auf Cloud Run-Funktionen und Cloud Run Dienste verwendet werden, nachdem Sie die Rolle „Cloud Functions-Aufrufer“ (roles/cloudfunctions.invoker) und die Rolle „Cloud Run-Aufrufer“ (roles/run.invoker) für service-agent-project-number@gcp-sa-dialogflow gewährt haben. Wenn sich die Cloud Run-Funktionen und Cloud Run-Dienste im selben Ressourcenprojekt befinden, benötigen Sie keine zusätzliche IAM-Berechtigung (Identity and Access Management), um sie aufzurufen.

Authentifizierung mit Dienstkonten

Dienstkonten können verwendet werden, um Toolanfragen bei allen Google APIs zu authentifizieren, die dies unterstützen.

Erstellen Sie ein Dienstkonto, falls Sie noch keines haben, create a service account.

Da es sich bei Dienstkonten um Hauptkonten handelt, können Sie ihnen Zugriff auf Ressourcen in Ihrem Projekt gewähren, indem Sie ihnen eine Rolle zuweisen, wie Sie es auch für jedes andere Hauptkonto tun würden. Mit der E‑Mail-Adresse des Dienstkontos wird verwendet, um ein Zugriffstoken zu generieren , das im Authorization Header der Toolanfrage gesendet wird.

Der Nutzer, der das Tool für die Verwendung von Dienstkonten konfiguriert, muss die folgenden Berechtigungen haben:

  • roles/iam.serviceAccountUser

Damit Dialogflow CX Tokens generieren kann, muss der Dialogflow-Dienst-Agent die folgenden Berechtigungen haben:

  • roles/iam.serviceAccountTokenCreator

Das Dienstkonto muss außerdem Berechtigungen für den Zugriff auf den Dienst haben, der das Tool hostet.

API-Schlüssel

  • Sie können die API-Schlüsselauthentifizierung konfigurieren, indem Sie den Schlüsselnamen, den Anfragespeicherort (Header oder Abfragestring) und den API-Schlüssel angeben, damit Dialogflow den API-Schlüssel in der Anfrage übergibt.
  • Wir empfehlen, den API-Schlüssel mit Secret Manager bereitzustellen. Nach dem 15. August 2025 enthalten exportierte KI-Agenten keine API-Schlüssel mit Rohwerten mehr.

OAuth

  • Der OAuth-Vorgang für Clientanmeldedaten wird für die Server-zu-Server-Authentifizierung unterstützt:
    • Dieser Vorgang kann verwendet werden, wenn der Generative AI App Builder der Ressourceninhaber ist und keine Endnutzerautorisierung erforderlich ist.
    • Die Client-ID, der Clientschlüssel und der Token-Endpunkt eines OAuth-Anbieters müssen in Dialogflow konfiguriert werden.
    • Wir empfehlen, den Clientschlüssel mit Secret Manager bereitzustellen. Nach dem 15. August 2025 enthalten exportierte KI-Agenten keine Clientschlüssel mit Rohwerten mehr.
    • Dialogflow tauscht ein OAuth-Zugriffstoken von einem OAuth-Anbieter aus und übergibt es im Autorisierungsheader der Anfrage.

Inhabertoken

  • Sie können die Inhaberauthentifizierung konfigurieren, um das Inhabertoken dynamisch vom Client zu übergeben. Dieses Token ist im Autorisierungsheader der Anfrage enthalten.
  • Beim Einrichten der Toolauthentifizierung können Sie einen Sitzungsparameter als Inhabertoken festlegen. Verwenden Sie beispielsweise $session.params.<parameter-name-for-token>, um das Token anzugeben.
  • Weisen Sie zur Laufzeit das Inhabertoken dem Sitzungsparameter zu:

    DetectIntentRequest {
      ...
      query_params {
        parameters {
          <parameter-name-for-token>: <the-auth-token>
        }
      }
      ...
    }
    
  • Wenn Sie ein statisches Token konfigurieren müssen, anstatt das Token aus einem Sitzungsparameter abzurufen, empfehlen wir, das Token mit Secret Manager bereitzustellen. Nach dem 15. August 2025 enthalten exportierte KI-Agenten keine Inhabertokens mit Rohwerten mehr.

Gegenseitige TLS-Authentifizierung

  • Weitere Informationen finden Sie in der Dokumentation zur gegenseitigen TLS-Authentifizierung.
  • Benutzerdefinierte Clientzertifikate werden unterstützt. Sie können Clientzertifikate auf Agentenebene auf dem Tab „Sicherheit“ in den Agenteneinstellungen einrichten. Das Zertifikat (PEM-Format) und der private Schlüssel (PEM-Format) sind Pflichtfelder. Nach der Einrichtung wird dieses Clientzertifikat bei der gegenseitigen TLS-Authentifizierung für alle Tools und Webhooks verwendet.

Benutzerdefiniertes CA-Zertifikat

Secret Manager-Authentifizierung

Wenn Sie OAuth, API-Schlüssel oder Inhabertoken verwenden, können Sie die Anmeldedaten mit Secret Manager als Secrets speichern. So authentifizieren Sie Ihr Tool mit Secrets:

  1. Erstellen Sie ein Secret falls Sie noch keines haben.
  2. Gewähren Sie Dialogflow-Dienst-Agent die Rolle Secret Manager Secret Accessor (roles/secretmanager.secretAccessor) für das neue Secret.
  3. Kopieren Sie die Anmeldedaten in die Zwischenablage.
  4. Fügen Sie Ihrem Secret eine neue Secret-Version hinzu. Fügen Sie die Anmeldedaten als Secret-Wert ein.
    • Lassen Sie am Ende alle Zeilenumbrüche weg.
  5. Kopieren Sie den Namen der gerade hinzugefügten Secret-Version. Das Namensformat ist projects/{project_id}/secrets/{secret_id}/versions/{version_id}".
  6. Öffnen Sie den Bildschirm zum Bearbeiten des Tools und gehen Sie so vor:
    • Wenn Sie OAuth verwenden, wählen Sie OAuth als Authentifizierungstyp aus und klicken Sie unter Clientschlüssel auf Secret-Version und fügen Sie den Namen der Secret-Version in das Eingabefeld Secret-Version ein.
    • Wenn Sie einen API-Schlüssel verwenden, wählen Sie API-Schlüssel als Authentifizierungstyp aus und klicken Sie dann unter API-Schlüssel auf Secret-Version. Fügen Sie den Namen der Secret-Version in das Eingabefeld Secret-Version ein.
    • Wenn Sie ein Inhabertoken verwenden, wählen Sie Inhabertoken als Authentifizierungstyp, dann klicken Sie unter Inhabertoken auf Secret-Version. Fügen Sie den Namen der Secret-Version in das Eingabefeld Secret-Version ein.
  7. Klicken Sie auf Speichern.

Privater Netzwerkzugriff für OpenAPI-Tools

OpenAPI-Tools werden in privaten Service Directory-Zugriff, eingebunden, sodass eine Verbindung zu API-Zielen in Ihrem VPC-Netzwerk hergestellt werden kann. Dadurch wird der Traffic innerhalb des Google Cloud Netzwerks beibehalten und IAM sowie VPC Service Controls erzwungen.

So richten Sie ein OpenAPI-Tool ein, das auf ein privates Netzwerk ausgerichtet ist:

  1. Folgen Sie der Anleitung unter Private Netzwerkkonfiguration für Service Directory , um Ihr VPC-Netzwerk und Ihren Service Directory-Endpunkt zu konfigurieren.
  2. Das Dialogflow-Dienst-Agent Dienstkonto mit der folgenden Adresse muss für Ihr Agent-Projekt vorhanden sein:
    service-agent-project-number@gcp-sa-dialogflow.
    Gewähren Sie dem Dienstkonto Dialogflow-Dienst-Agent die folgenden IAM-Rollen (Identity and Access Management):
    • servicedirectory.viewer des Service Directory-Projekts
    • servicedirectory.pscAuthorizedService des Netzwerkprojekts
  3. Geben Sie beim Erstellen des Tools den Service Directory-Dienst mit dem OpenAPI-Schema und optionalen Authentifizierungsinformationen an.

Zugriff auf Sitzungsparameter für OpenAPI-Tools

Die Eingaben für OpenAPI-Tools werden aus der Unterhaltung der Nutzer mit dem LLM abgeleitet, wobei das Schema als Leitfaden dient. In einigen Fällen müssen Eingaben aus Sitzungsparametern abgeleitet werden, die während eines Ablaufs erfasst wurden, oder als Abfrageparameter zusammen mit der Nutzereingabe bereitgestellt werden.

Der Sitzungsparameter, der als Eingabe übergeben werden muss, kann so angegeben werden:

     parameters:
       - in: query
         name: petId
         required: true
         description: Pet id
         schema:
           type: integer
           x-agent-input-parameter: petId # Reads from the $session.params.petId
       - in: header
         name: X-other
         schema:
           type: string
           x-agent-input-parameter: $request.payload.header # Reads from the header specified in the request payload input
     requestBody:
       required: false
       content:
         application/json:
           schema:
             type: object
             properties:
               name:
                 type: string
                 x-agent-input-parameter: petName # Reads from the $session.params.petName
                 description: Name of the person to greet (optional).
               breed:
                 type: string
                 description: Bread of the pet.

Wenn kein solcher Sitzungsparameter verfügbar ist, wird die vom LLM generierte Eingabe an das Tool übergeben.

Standardwerte für OpenAPI-Tools

Im Open API-Schema können Standardwerte angegeben werden. Die Standardwerte werden nur verwendet, wenn für diesen Parameter oder diese Eigenschaft kein vom LLM generierter Eingabewert oder kein auf Sitzungsparametern basierender Eingabewert vorhanden ist.

Die Standardwerte können als Teil des Schemas so angegeben werden:

     parameters:
       - in: query
         name: zipcode
         required: true
         description: Zip code to search for
         schema:
           type: integer
           default: 94043
     requestBody:
       content:
         application/json:
           schema:
             type: object
             properties:
               breed:
                 type: string
                 description: Bread of the pet.
               page_size:
                 type: integer
                 description: Number of pets to return.
                 default: 10

Wenn kein vom LLM generierter Wert, kein Sitzungsparameterwert und kein Standardwert vorhanden ist, wird die Eingabe nicht angegeben.

Datenspeichertools

Informationen zur Verwendung von Datenspeichertools mit einem Playbook finden Sie in der Dokumentation zu Datenspeichertools.

Anschlussstecker-Tools

Connector-Tools können von einem KI-Agenten verwendet werden, um Aktionen mit Ihren in Integration Connectorskonfigurierten Verbindungen auszuführen. Jedes Connector-Tool wird mit einer Verbindung und einer oder mehreren Aktionen konfiguriert. Bei Bedarf können mehrere Tools für eine einzelne Verbindung erstellt werden, um verschiedene Aktionen zusammenzufassen, die Ihr KI-Agent verwenden soll.

Das Connector-Tool unterstützt die folgenden Connector-Typen:

Beispiele sollten verwendet werden, um die Nutzung von Connector-Tools durch den KI-Agenten zu verbessern, indem sie zeigen, wie der KI-Agent das Tool aufrufen und die Antwort verwenden sollte.

Verbindung herstellen

Wenn Sie eine Verbindung erstellen und sie mit Ihrem KI-Agenten verbinden möchten, rufen Sie Tools > Erstellen auf, wählen Sie den Tooltyp Connector und den gewünschten Connectortyp aus und klicken Sie auf die Schaltfläche Verbindung erstellen. Dadurch gelangen Sie zur Erstellung von Integration Connectors, wobei eine Reihe von Feldern bereits ausgefüllt ist.

Alternativ können Sie zu Integration Connectors navigieren und der Anleitung folgen, um eine Verbindung zu erstellen.

Anschlussstecker-Aktionen

Für jedes Connector-Tool gibt es zwei Arten von Aktionen, die Ihrem KI-Agenten zur Verfügung gestellt werden können (weitere Informationen finden Sie unter Entitäten, Vorgänge und Aktionen ):

  1. CRUD-Vorgänge für Entitäten

    Jede Ihrer Verbindungen hat „Entitäten“, die den Objekten dieser Datenquelle entsprechen. Bei BigQuery sind das Tabellen, bei Salesforce Objekte wie „Bestellung“ oder „Fall“.

    Sie können für jede Entität CRUD-Vorgänge ausführen:

    • Erstellen: Erstellung einer Entität mit den angegebenen Feldwerten
    • Auflisten: Filterbasierte Suche nach Entitätsinstanzen
    • Aktualisieren: Filterbasierte Methode zum Ändern von Entitätsfeldwerten
    • Löschen: Löschen einer Entität
    • Abrufen : Abrufen einer einzelnen Entität anhand der Entitäts-ID

    Weitere Informationen zu CRUD-Vorgängen für Entitäten finden Sie in der Dokumentation zu Connectors.

  2. Connectorspezifische Aktionen

    Viele Connectors unterstützen die 'ExecuteCustomQuery' Aktion, mit der eine SQL-Abfrage für die Datenquelle ausgeführt werden kann. Dabei kann auf jede der Datenquellenentitäten als Tabelle verwiesen werden. Eine Liste der unterstützten Connectors finden Sie hier.

    Zusätzliche Aktionen unterscheiden sich je nach Connectortyp. Weitere Informationen finden Sie beispielsweise unter BigQuery-Connector-Aktionen oder Salesforce-Connector-Aktionen.

Eingabe-/Ausgabefelder für CRUD-Vorgänge konfigurieren

Wenn Sie bestimmte Eingabe- oder Ausgabefelder für die Aktion Ihres Connector-Tools auswählen, können Sie die Komplexität dieser Aktionen für den KI-Agenten begrenzen.

Wenn Sie beispielsweise nur eine Entität mit einer Teilmenge ihrer Felder erstellen müssen, vereinfacht die Konfiguration dieser Felder in Ihrer Aktion die Aktion für den KI-Agenten.

Durch die Angabe einer Reihe von Ausgabefeldern wird die Größe der Toolantwort reduziert (hilfreich, wenn Tokenlimits ein Problem darstellen) und die Verarbeitung der Ausgabe durch den KI-Agenten vereinfacht, da nur die relevanten Felder angezeigt werden.

Authentifizierung

Wenn für die verwendete Verbindung festgelegt ist, dass die Authentifizierung überschrieben werden darf, kann das Tool so konfiguriert werden, dass Anmeldedaten aus angegebenen Sitzungsparametern übergeben werden.

Sie als Entwickler des KI-Agenten sind dafür verantwortlich, wie diese Anmeldedaten in die Sitzungsparameter eingefügt werden. Das Tool übergibt sie dann automatisch an die Datenquelle, um sie für die Authentifizierung zu verwenden, wenn die Aktionen des Tools aufgerufen werden.

Funktionstools

Wenn Sie Funktionen haben, auf die Ihr Clientcode zugreifen kann, OpenAPI-Tools aber nicht, können Sie Funktionstools verwenden. Funktionstools werden immer clientseitig ausgeführt, nicht vom KI-Agenten.

So läuft der Vorgang ab:

  1. Ihr Clientcode sendet eine Anfrage zur Intent-Erkennung.
  2. Der KI-Agent erkennt, dass ein Funktionstool erforderlich ist, und die Antwort zur Intent-Erkennung enthält den Namen des Tools zusammen mit Eingabeargumenten. Diese Sitzung wird angehalten, bis eine weitere Anfrage zur Intent-Erkennung mit dem Toolergebnis eingeht.
  3. Ihr Clientcode ruft das Tool auf.
  4. Ihr Clientcode sendet eine weitere Anfrage zur Intent-Erkennung, die das Toolergebnis als Ausgabeargumente bereitstellt.

Das folgende Beispiel zeigt das Eingabe- und Ausgabeschema eines Funktionstools:

{
  "type": "object",
  "properties": {
    "location": {
      "type": "string",
      "description": "The city and state, for example, San Francisco, CA"
    }
  },
  "required": [
    "location"
  ]
}
{
  "type": "object",
  "properties": {
    "temperature": {
      "type": "number",
      "description": "The temperature"
    }
  }
}

Das folgende Beispiel zeigt die erste Anfrage und Antwort zur Intent-Erkennung mit REST:

HTTP method and URL:
POST https://REGION_ID-dialogflow.googleapis.com/v3/projects/PROJECT_ID/locations/LOCATION_ID/agents/AGENT_ID/sessions/SESSION_ID:detectIntent
{
  "queryInput": {
    "text": {
      "text": "what is the weather in Mountain View"
    },
    "languageCode": "en"
  }
}
{
  "queryResult": {
    "text": "what is the weather in Mountain View",
    "languageCode": "en",
    "responseMessages": [
      {
        "source": "VIRTUAL_AGENT",
        "toolCall": {
          "tool": "<tool-resource-name>",
          "action": "get-weather-tool",
          "inputParameters": {
            "location": "Mountain View"
          }
        }
      }
    ]
  }
}

Das folgende Beispiel zeigt die zweite Anfrage zur Intent-Erkennung, die das Toolergebnis liefert:

{
  "queryInput": {
    "toolCallResult": {
      "tool": "<tool-resource-name>",
      "action": "get-weather-tool",
      "outputParameters": {
        "temperature": 28.0
      }
    },
    "languageCode": "en"
  }
}

Clientseitige Ausführung

Wie Funktionstools können auch OpenAPI- und Datenspeichertools clientseitig ausgeführt werden, indem bei der Interaktion mit der Sitzung eine API-Überschreibung angewendet wird.

Beispiel:

DetectIntentRequest {
  ...
  query_params {
    playbook_state_override {
      playbook_execution_mode: ALWAYS_CLIENT_EXECUTION
    }
  }
  ...
}

So läuft der Vorgang ab:

  1. Ihr Clientcode sendet eine Anfrage zur Intent-Erkennung, in der die clientseitige Ausführung angegeben ist.
  2. Der KI-Agent erkennt, dass ein Tool erforderlich ist, und die Antwort zur Intent-Erkennung enthält den Namen des Tools zusammen mit Eingabeargumenten. Diese Sitzung wird angehalten, bis eine weitere Anfrage zur Intent-Erkennung mit dem Toolergebnis eingeht.
  3. Ihr Clientcode ruft das Tool auf.
  4. Ihr Clientcode sendet eine weitere Anfrage zur Intent-Erkennung, die das Toolergebnis als Ausgabeargumente bereitstellt.