Zum Hauptinhalt springen
connic

WebSocket

Von connic
Sync

Öffne einen Socket, sende JSON-Nachrichten und streame jede Antwort in deine App, während der Agent sie schreibt. Agenten-Sessions halten das Gespräch über mehrere Nachrichten und neue Verbindungen hinweg zusammen.

Publisher
Von connic
Modi
Sync
Einrichtung
Dashboard oder connectors/*.yaml
Dokumentation
WebSocket Docs

Streame die Antwort, während der Agent schreibt

Öffne den Socket, sende JSON und zeige jeden Textteil an, sobald er ankommt. Jede Nachricht bekommt ein ack, und die Antwort endet mit dem vollständigen Text und der Token-Nutzung.

Streaming an
Du bekommst stream_start, dann stream_chunk Events mit Textteilen und zum Schluss stream_end mit der vollständigen Antwort und der Token-Nutzung.
Streaming aus
Die Antwort kommt als ein einzelnes response Event, sobald der Run fertig ist.
Erst die Guardrails
Hat der Agent Output-Guardrails, sendet er seine Antwort als einen einzigen stream_chunk, nachdem die Prüfung bestanden ist.
Antworten zuordnen
Gib jeder Nachricht eine id, dann trägt jedes Event ihrer Antwort dieselbe id.
chat.js
const ws = new WebSocket(
  "<websocket-url>?secret=<your-secret-key>"
);

ws.onopen = () => {
  ws.send(JSON.stringify({
    type: "message",
    id: "msg-001",
    payload: { message: "Where is my order ord_8812?" },
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  if (data.type === "stream_chunk") appendToChat(data.chunk);
};
events.json
{ "type": "ack", "id": "msg-001", "message_number": 1 }
{ "type": "stream_start", "id": "msg-001",
  "agent": "support-chat" }
{ "type": "stream_chunk", "id": "msg-001",
  "agent": "support-chat", "chunk": "Order ord_8812 " }
{ "type": "stream_chunk", "id": "msg-001",
  "agent": "support-chat", "chunk": "shipped on October 12." }
{ "type": "stream_end", "id": "msg-001",
  "agent": "support-chat",
  "full_response": "Order ord_8812 shipped on October 12.",
  "token_usage": { "input_tokens": 812, "output_tokens": 14,
    "total_tokens": 826 } }

Halte das Gespräch über mehrere Nachrichten

Jede Nachricht startet einen eigenen Agent Run. Eine persistente Session mit einer Gesprächs-ID als Schlüssel trägt den Verlauf von einer Nachricht zur nächsten.

Der Verlauf gehört zum Gespräch
Setze session.key auf input.conversation_id und sende dieses Feld mit jeder Nachricht. Verbindest du dich mit derselben ID neu, geht das Gespräch weiter.
Ein Schlüssel pro Gespräch
Ohne Schlüssel teilen sich alle Gespräche des Agenten eine Session.
Eine Nachricht nach der anderen
Eine Verbindung verarbeitet Nachrichten in der Reihenfolge ihres Eingangs. Kommt eine Nachricht während einer Antwort, wartet sie, bis alle verknüpften Agenten geantwortet haben.
Freigaben halten die Antwort an
Ein Tool mit Freigabepflicht pausiert die Antwort, bis jemand entscheidet, und spätere Nachrichten warten. Halte approval.timeout bei Chat-Agenten kurz.
agents/support-chat.yaml
session:
  key: input.conversation_id
  ttl: 86400
message.json
{
  "type": "message",
  "id": "msg-002",
  "payload": {
    "message": "Can you send it to my office instead?",
    "conversation_id": "conv_4821"
  }
}

Halte den Socket neben deinen Agenten

Deklariere ihn als YAML-Datei in connectors/. Jedes Deployment legt ihn für sein Environment an oder aktualisiert ihn, und ein Rollback stellt ihn wieder her. URL und Secret erzeugt connic, deshalb stehen beide nicht in der Datei.

connectors/support-chat.yaml
type: websocket
name: Support chat
config:
  streaming: true
  max_messages_per_session: 500
agents:
  - support-chat
create: connectors/support-chat.yaml (websocket)

Lege fest, wer sich verbindet und wie lange

Die Authentifizierung ist standardmäßig aktiv, und jede Verbindung schließt nach einer Leerlaufzeit oder einem Nachrichtenlimit, das du festlegst.

Ein Secret beim Verbinden
Übergib es als Query-Parameter secret, als X-Connic-Secret Header oder als erste JSON-Nachricht. Bei falschem Secret schließt der Socket, bevor ein Run startet.
Eigene Prüfung der Aufrufer
Deaktiviere Require Authentication nur, wenn Middleware jeden Aufrufer prüft, zum Beispiel über ein signiertes Token.
Limits pro Verbindung
Eine inaktive Verbindung schließt nach session_timeout, und sobald sie max_messages_per_session erreicht, schließt sie ebenfalls. Der Verlauf bleibt in der Agenten-Session, also verbindet sich der Client neu und macht weiter.
Einstellungen der Verbindung
FeldStandardErlaubte Werte
streamingtruetrue, false
require_authtruetrue, false
session_timeout360060 bis 86400 Sekunden
max_messages_per_session1001 bis 10000

Wo ein WebSocket passt

Wähle ein Szenario und sieh, was der Client sendet und was über den Socket zurückkommt.

Deine Web-App streamt die Antwort ins Chatfenster, während der Agent sie schreibt.

Chat in der Web-App
WebSocket
support-chat
Gestreamte Antwort im Chat
message.json
{
  "type": "message",
  "id": "msg-001",
  "payload": {
    "message": "Where is my order ord_8812?",
    "conversation_id": "conv_4821"
  }
}
events.json
{ "type": "ack", "id": "msg-001", "message_number": 1 }
{ "type": "stream_start", "id": "msg-001",
  "agent": "support-chat" }
{ "type": "stream_chunk", "id": "msg-001",
  "agent": "support-chat", "chunk": "Order ord_8812 " }
{ "type": "stream_chunk", "id": "msg-001",
  "agent": "support-chat", "chunk": "shipped on October 12." }
{ "type": "stream_end", "id": "msg-001",
  "agent": "support-chat",
  "full_response": "Order ord_8812 shipped on October 12.",
  "token_usage": { "input_tokens": 812, "output_tokens": 14,
    "total_tokens": 826 } }

Nutzer laden in deinem Portal einen Vertrag hoch und fragen danach. Die Antwort streamt mit der Datei im Kontext zurück.

Kundenportal
WebSocket
contract-reader
Antwort im Portal
message.json
{
  "type": "message",
  "id": "msg-007",
  "payload": {
    "message": "Which notice period applies to this contract?",
    "conversation_id": "conv_9310",
    "files": [
      {
        "name": "service-agreement.pdf",
        "mime_type": "application/pdf",
        "data": "<base64-bytes>",
        "size": 284113
      }
    ]
  }
}
stream_end.json
{
  "type": "stream_end",
  "id": "msg-007",
  "agent": "contract-reader",
  "full_response": "Section 9: three months' notice to the end of a quarter.",
  "token_usage": { "input_tokens": 6120, "output_tokens": 22, "total_tokens": 6142 }
}

Deine App zeigt den nächsten Einrichtungsschritt als vollständige Nachricht, deshalb läuft die Verbindung ohne Streaming.

Onboarding-Flow
WebSocket
onboarding-guide
Nächster Schritt in der App
message.json
{
  "type": "message",
  "id": "msg-003",
  "payload": {
    "message": "I imported my contacts. What comes next?",
    "conversation_id": "onb_5520"
  }
}
events.json
{ "type": "ack", "id": "msg-003", "message_number": 3 }
{
  "type": "response",
  "id": "msg-003",
  "agent": "onboarding-guide",
  "response": "Next, create your first campaign. Pick a template to start from.",
  "token_usage": { "input_tokens": 930, "output_tokens": 16, "total_tokens": 946 }
}

Dein CRM-Backend fragt ein Briefing zu einem Account an und zeigt den fertigen Text in einer Seitenleiste.

CRM-Backend
WebSocket
account-briefing
Briefing in der CRM-Seitenleiste
briefing.py
import json

import websockets


async def brief(account_id: str) -> str:
    url = "<websocket-url>?secret=<your-secret-key>"
    async with websockets.connect(url) as ws:
        await ws.recv()  # connected
        await ws.send(json.dumps({"payload": {
            "message": "Brief me before my call.",
            "account_id": account_id,
        }}))
        while True:
            event = json.loads(await ws.recv())
            if event["type"] == "stream_end":
                return event.get("full_response", "")
stream_end.json
{
  "type": "stream_end",
  "id": "3f2b8c1e-6d4a-4e9b-9a7c-2d5e8f1b4c6a",
  "agent": "account-briefing",
  "full_response": "Example GmbH renewed in March and has two open tickets.",
  "token_usage": { "input_tokens": 1460, "output_tokens": 24, "total_tokens": 1484 }
}

FAQ zu WebSocket

Füge dem Agenten eine WebSocket-Verbindung hinzu, öffne den Socket mit URL und Secret und sende eine JSON-Nachricht. Die Antwort kommt als stream_chunk Events, während der Agent schreibt, und ein stream_end Event enthält den vollständigen Text und die Token-Nutzung.

Ja, mit einer persistenten Session. Setze session.key auf ein Feld der Payload wie input.conversation_id und sende dieses Feld mit jeder Nachricht. Der Verlauf gehört zum Gespräch, deshalb geht es nach dem erneuten Verbinden mit derselben ID weiter.

Mit dem Secret der Verbindung, als Query-Parameter secret, als X-Connic-Secret Header oder als erste JSON-Nachricht. Deaktiviere Require Authentication nur, wenn Middleware jeden Aufrufer prüft, zum Beispiel über ein signiertes Token.

Ja. Füge der Payload ein files Array mit name, mime_type und base64-codierten data hinzu. Pro Nachricht sind bis zu 10 Dateien und insgesamt 10 MiB möglich, und jede angenommene Datei geht zusammen mit der Nachricht an das Modell.

Wenn eine einzelne Anfrage auf die fertige Antwort warten soll und du weder einen Stream noch eine offene Verbindung brauchst. Ein Sync Webhook liefert die Ausgabe des Agenten in der HTTP-Response und wartet standardmäßig fünf Minuten.