Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openclaw/extensions/skill-workshop/src/   (KI Agentensystem Version 22©)  Datei vom 26.3.2026 mit Größe 8 kB image not shown  

Quelle  tool.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import { randomUUID } from "node:crypto";
import { Type } from "typebox";
import { jsonResult, type OpenClawPluginApi } from "../api.js";
import type { SkillWorkshopConfig } from "./config.js";
import {
  applyProposalToWorkspace,
  normalizeSkillName,
  prepareProposalWrite,
  writeSupportFile,
} from "./skills.js";
import type { SkillChange, SkillProposal, SkillWorkshopStatus } from "./types.js";
import { createStoreForContext, resolveWorkspaceDir } from "./workshop.js";

type ToolParams = {
  action?: string;
  id?: string;
  status?: SkillWorkshopStatus;
  skillName?: string;
  title?: string;
  reason?: string;
  description?: string;
  body?: string;
  section?: string;
  oldText?: string;
  newText?: string;
  relativePath?: string;
  apply?: boolean;
};

function readString(value: unknown): string | undefined {
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
}

function buildProposal(params: {
  workspaceDir: string;
  raw: ToolParams;
  source: "tool";
}): SkillProposal {
  const skillName = normalizeSkillName(readString(params.raw.skillName) ?? "");
  if (!skillName) {
    throw new Error("skillName required");
  }
  const now = Date.now();
  const title = readString(params.raw.title) ?? `Skill update: ${skillName}`;
  const reason = readString(params.raw.reason) ?? "Tool-created skill update";
  const body = readString(params.raw.body);
  const description = readString(params.raw.description) ?? title;
  let change: SkillChange;
  if (params.raw.oldText !== undefined || params.raw.newText !== undefined) {
    const oldText = readString(params.raw.oldText);
    const newText = readString(params.raw.newText);
    if (!oldText || !newText) {
      throw new Error("oldText and newText required for replace");
    }
    change = { kind: "replace", oldText, newText };
  } else if (readString(params.raw.section)) {
    if (!body) {
      throw new Error("body required");
    }
    change = {
      kind: "append",
      section: readString(params.raw.section) ?? "Workflow",
      body,
      description,
    };
  } else {
    if (!body) {
      throw new Error("body required");
    }
    change = { kind: "create", description, body };
  }
  return {
    id: randomUUID(),
    createdAt: now,
    updatedAt: now,
    workspaceDir: params.workspaceDir,
    skillName,
    title,
    reason,
    source: params.source,
    status: "pending",
    change,
  };
}

export function createSkillWorkshopTool(params: {
  api: OpenClawPluginApi;
  config: SkillWorkshopConfig;
  ctx: { workspaceDir?: string };
}) {
  return {
    name: "skill_workshop",
    label: "Skill Workshop",
    description:
      "Create, queue, inspect, approve, or safely apply workspace skill updates for repeatable workflows.",
    parameters: Type.Object({
      action: Type.String({
        enum: [
          "status",
          "list_pending",
          "list_quarantine",
          "inspect",
          "suggest",
          "apply",
          "reject",
          "write_support_file",
        ],
      }),
      id: Type.Optional(Type.String()),
      status: Type.Optional(
        Type.String({ enum: ["pending", "applied", "rejected", "quarantined"] }),
      ),
      skillName: Type.Optional(Type.String()),
      title: Type.Optional(Type.String()),
      reason: Type.Optional(Type.String()),
      description: Type.Optional(Type.String()),
      body: Type.Optional(Type.String()),
      section: Type.Optional(Type.String()),
      oldText: Type.Optional(Type.String()),
      newText: Type.Optional(Type.String()),
      relativePath: Type.Optional(Type.String()),
      apply: Type.Optional(Type.Boolean()),
    }),
    async execute(_toolCallId: string, rawParams: Record<string, unknown>) {
      const raw = rawParams as ToolParams;
      const action = raw.action ?? "status";
      const workspaceDir = resolveWorkspaceDir(params);
      const store = createStoreForContext(params);
      if (action === "status") {
        const all = await store.list();
        return jsonResult({
          workspaceDir,
          pending: all.filter((item) => item.status === "pending").length,
          quarantined: all.filter((item) => item.status === "quarantined").length,
          applied: all.filter((item) => item.status === "applied").length,
          rejected: all.filter((item) => item.status === "rejected").length,
        });
      }
      if (action === "list_pending") {
        return jsonResult(await store.list(raw.status ?? "pending"));
      }
      if (action === "list_quarantine") {
        return jsonResult(await store.list("quarantined"));
      }
      if (action === "inspect") {
        if (!raw.id) {
          throw new Error("id required");
        }
        return jsonResult(await store.get(raw.id));
      }
      if (action === "suggest") {
        const proposal = buildProposal({ workspaceDir, raw, source: "tool" });
        const shouldApply =
          raw.apply === true || (raw.apply !== false && params.config.approvalPolicy === "auto");
        if (shouldApply) {
          const prepared = await prepareProposalWrite({
            proposal,
            maxSkillBytes: params.config.maxSkillBytes,
          });
          const critical = prepared.findings.find((finding) => finding.severity === "critical");
          if (critical) {
            const stored = await store.add(
              {
                ...proposal,
                status: "quarantined",
                updatedAt: Date.now(),
                scanFindings: prepared.findings,
                quarantineReason: critical.message,
              },
              params.config.maxPending,
            );
            return jsonResult({ status: "quarantined", proposal: stored });
          }
          const applied = await applyProposalToWorkspace({
            proposal,
            maxSkillBytes: params.config.maxSkillBytes,
          });
          const stored = await store.add(
            {
              ...proposal,
              status: "applied",
              updatedAt: Date.now(),
              scanFindings: applied.findings,
            },
            params.config.maxPending,
          );
          return jsonResult({ status: "applied", skillPath: applied.skillPath, proposal: stored });
        }
        const prepared = await prepareProposalWrite({
          proposal,
          maxSkillBytes: params.config.maxSkillBytes,
        });
        const critical = prepared.findings.find((finding) => finding.severity === "critical");
        if (critical) {
          const stored = await store.add(
            {
              ...proposal,
              status: "quarantined",
              updatedAt: Date.now(),
              scanFindings: prepared.findings,
              quarantineReason: critical.message,
            },
            params.config.maxPending,
          );
          return jsonResult({ status: "quarantined", proposal: stored });
        }
        const stored = await store.add(
          { ...proposal, scanFindings: prepared.findings },
          params.config.maxPending,
        );
        return jsonResult({ status: "pending", proposal: stored });
      }
      if (action === "apply") {
        if (!raw.id) {
          throw new Error("id required");
        }
        const proposal = await store.get(raw.id);
        if (!proposal) {
          throw new Error(`proposal not found: ${raw.id}`);
        }
        if (proposal.status === "quarantined") {
          throw new Error("quarantined proposal cannot be applied");
        }
        const applied = await applyProposalToWorkspace({
          proposal,
          maxSkillBytes: params.config.maxSkillBytes,
        });
        const updated = await store.updateStatus(raw.id, "applied");
        return jsonResult({ status: "applied", skillPath: applied.skillPath, proposal: updated });
      }
      if (action === "reject") {
        if (!raw.id) {
          throw new Error("id required");
        }
        return jsonResult(await store.updateStatus(raw.id, "rejected"));
      }
      if (action === "write_support_file") {
        const skillName = readString(raw.skillName);
        const relativePath = readString(raw.relativePath);
        const body = raw.body;
        if (!skillName || !relativePath || typeof body !== "string") {
          throw new Error("skillName, relativePath, and body required");
        }
        const filePath = await writeSupportFile({
          workspaceDir,
          skillName,
          relativePath,
          content: body,
          maxBytes: params.config.maxSkillBytes,
        });
        return jsonResult({ status: "written", filePath });
      }
      throw new Error(`unknown action: ${action}`);
    },
  };
}

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.