lib/mate-knowledge-text-tools.js
Rama main · réplica de lectura del repositorio original.
// 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 };