Ctrl K
ComunidadGuías…

lib/mate-knowledge-text-tools.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// Session-bound text Knowledge mutations for one authorized Mate.
//
// This module deliberately uses the existing portable file store and
// write-through synchronizer. It never accepts a Mate, owner, or filesystem
// root from a tool caller; the caller supplies only a relative document name
// or the stable identity returned by the store.

var crypto = require("crypto");
var path = require("path");
var knowledgeFiles = require("./knowledge-file-store");
var mateSync = require("./mate-knowledge-sync");

function metadataRoot(baseDir, mateDir) {
  var key = crypto.createHash("sha256").update(path.resolve(mateDir)).digest("hex").slice(0, 24);
  return path.join(baseDir || path.join(mateDir, ".clay"), "knowledge-documents", key);
}

function failedSync(summary) {
  if (!summary) return { indexSyncPending: true, syncError: "Knowledge index synchronization returned no result." };
  if (summary.failed === 0) return { indexSyncPending: false, syncError: null };
  var error = summary.errors && summary.errors[0];
  return { indexSyncPending: true, syncError: error && error.message || "Knowledge index synchronization failed." };
}

function createMateKnowledgeTextTools(options) {
  var settings = options || {};
  var stores = new Map();

  function storeFor(mate) {
    if (!mate || typeof mate.mateDir !== "string") throw new Error("Knowledge text tools require an authorized Mate.");
    var directory = path.resolve(mate.mateDir);
    if (!stores.has(directory)) stores.set(directory, knowledgeFiles.createKnowledgeFileStore(directory, { metaDir: metadataRoot(settings.baseDir, directory) }));
    return stores.get(directory);
  }

  function find(store, input) {
    var args = input || {};
    var hasName = typeof args.name === "string" && args.name.length > 0;
    var hasId = typeof args.documentId === "string" && args.documentId.length > 0;
    if (!hasName && !hasId) throw new Error("A document name or stable document id is required.");
    var item = null;
    if (hasId) item = store.list().filter(function (entry) { return entry.id === args.documentId; })[0] || null;
    if (hasId && !item) throw Object.assign(new Error("Knowledge document not found."), { code: "ENOENT" });
    if (hasName) {
      var byName = store.read(args.name);
      if (item && item.id !== byName.id) throw new Error("The document name and id identify different documents.");
      item = byName;
    }
    if (!item) throw Object.assign(new Error("Knowledge document not found."), { code: "ENOENT" });
    if (hasId && !hasName) item = store.read(item.name);
    if (item.itemType !== "text") throw Object.assign(new Error("Only Markdown Knowledge documents are writable through these tools."), { code: "READ_ONLY" });
    return item;
  }

  function sync(mate, name, actor) {
    try {
      var summary = mateSync.syncMateSource({ mateDir: mate.mateDir, fileName: name, baseDir: settings.baseDir, actor: actor });
      return failedSync(summary);
    } catch (error) {
      return { indexSyncPending: true, syncError: error.message || "Knowledge index synchronization failed." };
    }
  }

  function read(mate, args) {
    var item = find(storeFor(mate), args);
    return { documentId: item.id, name: item.name, content: item.content, revision: item.revision };
  }

  function create(mate, args, actor) {
    var input = args || {};
    if (typeof input.name !== "string" || !input.name) throw new Error("A document name is required to create a Knowledge document.");
    if (typeof input.content !== "string") throw new Error("Document content is required.");
    var store = storeFor(mate);
    var saved = store.save(input.name, input.content, null);
    return Object.assign({ documentId: saved.id, name: saved.name, revision: saved.revision }, sync(mate, saved.name, actor));
  }

  function update(mate, args, actor) {
    var input = args || {};
    if (typeof input.expectedRevision !== "string" || !input.expectedRevision) throw Object.assign(new Error("A current document revision is required for updates."), { code: "STALE" });
    if (typeof input.content !== "string") throw new Error("Document content is required.");
    var store = storeFor(mate);
    var current = find(store, input);
    var saved = store.save(current.name, input.content, input.expectedRevision);
    return Object.assign({ documentId: saved.id, name: saved.name, revision: saved.revision }, sync(mate, saved.name, actor));
  }

  function history(mate, args) {
    var current = find(storeFor(mate), args);
    return { documentId: current.id, name: current.name, versions: storeFor(mate).history(current.id) };
  }

  function restore(mate, args, actor) {
    var input = args || {};
    if (typeof input.expectedRevision !== "string" || !input.expectedRevision) throw Object.assign(new Error("A current document revision is required for restore."), { code: "STALE" });
    if (typeof input.version !== "string" || !input.version) throw new Error("A history version is required.");
    var store = storeFor(mate);
    var current = find(store, input);
    var restored = store.restore(current.id, input.version, current.name, input.expectedRevision);
    return Object.assign({ documentId: restored.id, name: restored.name, revision: restored.revision }, sync(mate, restored.name, actor));
  }

  return { read: read, create: create, update: update, history: history, restore: restore };
}

module.exports = { createMateKnowledgeTextTools: createMateKnowledgeTextTools };