Zum Inhalt springen

Implementierungen

Edge Connector Development

Implementierungen sind die Code-Dateien, die du schreibst, um EDGE-Tool-Ausführungen zu behandeln. Wenn ein Agent ein Tool mit dem Ausführungstyp EDGE aufruft, wird die Anfrage an den Edge Connector weitergeleitet, der die entsprechende Implementierung lädt, sie mit den übergebenen Parametern ausführt und ein strukturiertes Ergebnis zurückgibt. Diese Seite erklärt, wie du eigene Implementierungen erstellst, testest, paketierst und deployst.

Jedes EDGE-Tool in der nara-Registry hat definierte Eingabeparameter (ein Schema) und ein Ergebnis-Schema. Eine Implementierung ist eine JavaScript- oder TypeScript-Datei, die eine Handler-Funktion exportiert, die diesen Schemas entspricht. Der Handler empfängt die geparsten Parameter und einen Ausführungskontext, erledigt die nötige Arbeit (API aufrufen, Datenbank abfragen, Systembefehle ausführen) und gibt ein Ergebnisobjekt zurück.

Implementierungen sind als einzelne Dateien in einem tools/-Verzeichnis organisiert, eine Datei pro Tool. Diese Struktur ermöglicht es dem Edge Connector, jedes Tool unabhängig zu bündeln, versionieren und verteilen.

Eigene Implementierungen folgen einem Standard-Verzeichnislayout:

custom-implementations/
package.json # Abhängigkeiten für deinen Tool-Code
tsconfig.json # TypeScript-Konfiguration (bei Verwendung von TypeScript)
tools/ # Eine Datei pro Tool
getSystemInfo.ts # Implementierung für das getSystemInfo-Tool
restartService.ts # Implementierung für das restartService-Tool
queryDatabase.ref.json # Referenz auf servergehostete Version (kein lokaler Quellcode)
dist/ # Kompilierte Ausgabe (automatisch generiert beim Build)
index.js # Automatisch generierter Index, der alle Tools exportiert
tools/
getSystemInfo.js # Kompiliertes Tool
restartService.js # Kompiliertes Tool

Der schnellste Weg, eine neue Implementierung zu erstellen, ist der generate-Befehl. Er verbindet sich mit dem nara Platform Server, holt die Schemas des Tools und generiert eine korrekt typisierte TypeScript-Datei.

  1. Stelle sicher, dass du authentifiziert bist:

    Terminal-Fenster
    edge-connector auth --browser
  2. Generiere die Implementierung:

    Terminal-Fenster
    edge-connector generate -l typescript -t getSystemInfo -o ./custom-implementations
  3. Die CLI erstellt eine TypeScript-Datei unter ./custom-implementations/tools/getSystemInfo.ts mit:

    • Typisierten Eingabeparametern, abgeleitet aus dem Tool-Schema
    • Einem Ergebnistyp, der dem Ergebnis-Schema des Tools entspricht
    • Einem Handler-Funktions-Stub mit Fehlerbehandlungs-Scaffolding
    • Einem Ausführungskontext-Parameter mit Benutzer- und Organisationsinformationen
  4. Öffne die Datei in deinem Editor und implementiere die Logik.

Du kannst auch edge-connector generate --interactive ausführen, um verfügbare EDGE-Tools zu durchsuchen und eines aus einer Liste auszuwählen.

Hier ist ein vollständiges Beispiel einer TypeScript-Tool-Implementierung:

type GetSystemInfoParams = {
includeNetwork?: boolean
}
type GetSystemInfoResult = {
hostname: string
platform: string
arch: string
uptime: number
memory: {
total: number
free: number
used: number
}
network?: {
interfaces: string[]
}
}
export default async function getSystemInfo(
params: GetSystemInfoParams,
_context: unknown
): Promise<{
status: 'success' | 'error'
result?: GetSystemInfoResult
error?: { message: string; isRetryable: boolean }
}> {
try {
const os = await import('node:os')
const result: GetSystemInfoResult = {
hostname: os.hostname(),
platform: os.platform(),
arch: os.arch(),
uptime: os.uptime(),
memory: {
total: os.totalmem(),
free: os.freemem(),
used: os.totalmem() - os.freemem(),
},
}
if (params.includeNetwork) {
const interfaces = os.networkInterfaces()
result.network = {
interfaces: Object.keys(interfaces),
}
}
return { status: 'success', result }
} catch (err) {
return {
status: 'error',
error: {
message: err instanceof Error ? err.message : 'Unknown error',
isRetryable: false,
},
}
}
}

Jede Implementierung muss diese Anforderungen erfüllen:

AnforderungBeschreibung
Default-ExportDie Datei muss eine Standard-Async-Funktion als Handler exportieren
ParameterDas erste Argument empfängt die geparsten Tool-Parameter (gemäß dem Tool-Schema)
KontextDas zweite Argument enthält Ausführungskontext, wenn anfragebezogene Metadaten verfügbar sind
RückgabewertMuss ein Objekt mit status ('success' oder 'error') und entweder einem result- oder error-Feld zurückgeben
FehlerstrukturFehlerobjekte müssen message (String) und isRetryable (Boolean) enthalten
DateibenennungDer Dateiname (ohne Erweiterung) muss dem registrierten Namen des Tools entsprechen

Teste deine Implementierungen lokal mit dem run-Befehl, bevor du sie in Produktion hochlädst.

  1. Stelle sicher, dass der nara Platform Server läuft.

  2. Starte den Edge Connector im Testmodus:

    Terminal-Fenster
    edge-connector run --implementations ./custom-implementations --url ws://localhost:3001
  3. Öffne die nara Webapp und starte eine Konversation mit einem Agent, dem dein EDGE-Tool zugewiesen ist.

  4. Löse das Tool aus (z.B. bitte den Agent, eine Systemdiagnose durchzuführen). Die Tool-Ausführungsanfrage fließt über die Plattform zu deinem lokalen Edge Connector.

  5. Prüfe die Terminal-Ausgabe auf Ausführungslogs und Ergebnisse.

Wenn deine Implementierung fertig ist, paketiere sie als verteilbares Bundle.

Terminal-Fenster
edge-connector package -i ./custom-implementations -o ./artifacts

Was beim Paketieren passiert:

  1. Die CLI entdeckt alle Tool-Quelldateien in tools/ (.ts, .js, .mjs, .cjs).

  2. Jedes Tool wird einzeln mit esbuild in dist/tools/ kompiliert.

  3. Ein automatisch generierter dist/index.js wird erstellt, der alle Tool-Handler exportiert.

  4. Alle .ref.json-Referenzdateien werden in das Manifest aufgenommen (für Tools mit servergehosteten Versionen).

  5. Ein Manifest (manifest.json) wird erstellt mit der Organisations-ID, Sprache, Tool-Einträgen (Name, Checksumme, Größe), Referenzen, Build-Zeitstempel und Gesamt-Checksumme.

  6. Alles wird in eine .tgz-Datei im Ausgabeverzeichnis archiviert.

Wenn du eine package.json in deinem Implementierungsverzeichnis mit Abhängigkeiten hast, führt die CLI automatisch pnpm install aus, wenn node_modules/ nicht existiert.

Die TypeScript-Kompilierung wird beim Paketierungsschritt automatisch von esbuild übernommen. Jede Tool-Datei wird einzeln gebündelt und ergibt eine eigenständige .js-Datei pro Tool. Das bedeutet:

  • Tools sind auf Bundle-Ebene voneinander isoliert.
  • Abhängigkeiten werden inline eingebettet (kein node_modules im Bundle nötig).
  • Der Build ist schnell — esbuild verarbeitet Dateien in Millisekunden.

Um den Build-Schritt zu überspringen (wenn du bereits manuell kompiliert hast), verwende --no-build:

Terminal-Fenster
edge-connector package --no-build

Fehler sauber behandeln

Umschließe deine Implementierungslogik immer mit try/catch. Gib strukturierte Fehlerobjekte mit aussagekräftigen Meldungen zurück. Setze isRetryable: true für vorübergehende Fehler (Netzwerk-Timeouts, temporäre Nichtverfügbarkeit) und isRetryable: false für permanente Fehler (ungültige Eingabe, fehlende Ressource).

Strukturierte Ergebnisse zurückgeben

Halte dich exakt an das Ergebnis-Schema des Tools. Der Agent empfängt das Ergebnisobjekt und nutzt es, um Antworten zu formulieren. Füge alle Felder ein, die das Schema erwartet, auch wenn manche null oder leer sind.

Timeouts beachten

Tool-Ausführungen haben ein vom Platform Server erzwungenes Timeout. Halte Implementierungen schnell und reaktionsfreudig. Für langwierige Operationen erwäge, sie in kleinere Schritte aufzuteilen oder einen Status zurückzugeben, den der Agent pollen kann.

Secrets sicher aufbewahren

Hardcode niemals Anmeldedaten in Implementierungsdateien. Verwende Umgebungsvariablen, Secret-Manager oder die Konfiguration des Edge Connectors, um sensible Werte zur Laufzeit einzuschleusen. Tool-Bundles werden auf dem Platform Server gespeichert.