Skip to content

Skill-Manifest

Externe Skills sind Subprozess-Executables, die durch eine skill.json-Datei beschrieben werden, die unter einem der Allow-List-Verzeichnisse des Managers abgelegt wird. Der Loader durchsucht diese Verzeichnisse beim Boot, parst jede skill.json und registriert einen SubprocessSkill in der globalen Skill-Registry. Das LLM sieht den Skill dann neben den eingebauten Werkzeugen.

Source of truth: internal/skill/loader.go.

Layout auf Platte

text
/etc/ongrid/skills/                  ← one entry in $ONGRID_SKILLS_EXTERNAL_DIRS
└── disk-cleaner/
    ├── skill.json
    └── run.sh                       ← the executable

Jede skill.json liegt an der Spitze ihres eigenen Unterverzeichnisses. Der Verzeichnisbaum wird rekursiv durchlaufen; jede Datei mit dem Namen skill.json wird als Manifest behandelt. Mehrere Skills können unter derselben Allow-List-Wurzel leben.

Manifest-Schema

json
{
  "name": "disk_cleaner",
  "description": "Free up disk by clearing stale build caches and journals.",
  "schema": {
    "type": "object",
    "properties": {
      "path":   { "type": "string", "description": "Root path to clean." },
      "dry_run": { "type": "boolean", "default": true }
    },
    "required": ["path"]
  },
  "entry": "run.sh",
  "env_allow": ["PATH", "HOME"],
  "timeout_seconds": 60,
  "class": "mutating",
  "category": "ops"
}
FeldTypPflichtBeschreibung
namestringjaSkill-Schlüssel. Muss lower_snake matchend [a-z0-9_]+ sein. Wird zum LLM-zugewandten Funktionsnamen.
descriptionstringjaWird Menschen (UI) und dem LLM (Funktionsbeschreibung) gezeigt.
schemaJSON SchemaneinRohes JSON Schema für das Args-Objekt. Fehlend = leeres Objekt-Schema.
entrystringjaPfad zum Executable. Relative Pfade lösen sich gegen das Verzeichnis auf, das skill.json enthält. Absolute Pfade müssen unter einer Allow-List-Wurzel liegen.
env_allowstring[]neinExplizite Liste von Env-Variablennamen, die an das Kind weitergeleitet werden. Leere Liste = überhaupt keine Env (nicht einmal PATH). Fügen Sie "PATH" hinzu, um PATH zu aktivieren.
timeout_secondsintneinSubprozess-Timeout. Null fällt auf DefaultSubprocessTimeout zurück (30s).
classenumneinsafe (Standard), mutating, dangerous. Siehe Klassen-Taxonomie.
categorystringneinFrei formuliertes Gruppen-Label. Standard ist external. UI gruppiert Subprozess-Skills danach.

Wire-Protokoll

Der Subprozess wird aufgerufen mit stdin = JSON args object, stdout = JSON result object, stderr = Log-Zeilen für den Manager.

text
$ cat /tmp/args.json
{"path": "/var/cache", "dry_run": true}

$ run.sh < /tmp/args.json
{"freed_bytes": 1048576, "files_deleted": 17}

Ein Nicht-Null-Exit-Code wird als Fehlschlag behandelt. Stderr wird in die Tool-Call-Event-Timeline erfasst, sodass das LLM partiellen Fortschritt lesen kann.

Das Result-Objekt wird wortgetreu an das LLM zurückgegeben. Der Agent-Kernel formatiert es als Tool-Call-Antwort; vom LLM wird erwartet, dass es über die JSON-Form räsonniert.

Klassen-Taxonomie

Dieselbe {safe, mutating, dangerous}-Taxonomie gilt für native Skills und Subprozess-Skills.

KlasseWas sie tun kannErforderliche Persona-Berechtigung
safeRead-only — keine Seiteneffekte auf dem Host oder einem System.read-only (jede Persona)
mutatingErstellt / aktualisiert Zustand. Reversibel.mutating-with-confirm oder dual-sign-required
dangerousIrreversibel (löscht, startet neu, exec-arbitrary).dual-sign-required (SOP)

Das permission_mode-Feld der Persona steuert, welche Klassen ohne Bestätigung laufen dürfen. Siehe Agent-Persona-Format.

Allow-List-Regeln

Operatoren konfigurieren Allow-List-Verzeichnisse über ONGRID_SKILLS_EXTERNAL_DIRS (doppelpunkt- oder komma-getrennte absolute Pfade). Der Loader erzwingt sie strikt:

  • Jedes Verzeichnis muss ein absoluter Pfad sein. Relative Pfade werden mit einer Log-Zeile übersprungen.
  • Nicht existierende Pfade werden übersprungen (sodass eine frische Installation ohne /etc/ongrid/skills problemlos bootet).
  • Das entry jedes Manifests wird mit filepath.EvalSymlinks kanonisiert und geprüft, dass es unter der Allow-List-Wurzel liegt. Ein Symlink, der außerhalb der Wurzel zeigt, wird abgelehnt (entry %s escapes allowlist root %s).

Sandboxing darüber hinaus ist Verantwortung des Subprozesses. Wenn der Skill eng eingeschlossen werden muss, führen Sie ihn unter einem Wrapper aus (bwrap, firejail, nsenter), der als entry referenziert wird.

Loader-Verhalten

text
LoadDirs(cfg)
  for each dir in cfg.Dirs:
    filepath.Walk(dir)
      for each skill.json found:
        parseManifest(path)
        buildSubprocessSkill(manifest, path, root)
        if skill already registered: skip (log line)
        else Register(skill)
  • Per-Manifest-Validierungsfehler werden geloggt und übersprungen. Ein kaputtes Pack soll den Boot nicht blockieren.
  • Duplikatnamen werden eher übersprungen als zu erroren (sodass ein Redeploy, der ein neues Manifest ablegt, bevor das alte entfernt wird, den Manager nicht crasht).
  • Der Loader gibt die Anzahl erfolgreich registrierter Skills zurück. Der Manager-Start ist nicht-blockierend am Skill-Loader: ein leeres externes Verzeichnis ist ein No-Op.

Logging beim Start

Der Manager loggt eine Zeile pro Manifest:

text
skill loader: registered subprocess skill "disk_cleaner" from /etc/ongrid/skills/disk-cleaner/skill.json
skill loader: skill "broken_one" already registered, skipping /etc/ongrid/skills/broken-one/skill.json
skill loader: parse /etc/ongrid/skills/typo/skill.json: invalid character ',' looking for beginning of object key
skill loader: build "bad_path": entry /tmp/escape.sh escapes allowlist root /etc/ongrid/skills

Tailen Sie journalctl -u docker-compose@ongrid oder docker compose logs ongrid, um zu bestätigen, was aufgenommen wurde.

Siehe auch

Native Skill-Metadaten (SKILL.md-Frontmatter)

Eingebaute Skills, die unter ./skills/ ausgeliefert werden, verwenden ein reichhaltigeres YAML-Frontmatter-SKILL.md-Format, das mit den openclaw-/claude-code-Skill-Ökosystemen interoperabel ist. Das Schema ist in internal/manager/biz/aiops/chatruntime/types.go definiert:

yaml
---
name: query_promql
description: Run a PromQL query and return the result matrix.
when_to_use: When the user asks for current or recent metric values.
activation:
  mode: always
metadata:
  os: [linux, darwin]
  requires:
    bins: []
    config: []
  ongrid:
    scope: manager
    activation:
      mode: always
tools:
  - name: query_promql
    impl: builtin:prom.QueryPromQL
    class: read
    description: Execute a PromQL query and return the matrix.
---

# query_promql

PromQL query tool ...

Für Subprozess-Skills, die von Dritten geschrieben werden, bevorzugen Sie das einfachere skill.json-Format oben. SKILL.md ist für Skills, die in das Manager-Binary kompiliert werden.