UNPKG

@stll/folio-agents

Version:

Framework-neutral LLM tool layer over folio's ai-edits engine: function-calling tools so an agent can read and mutate .docx documents through @stll/folio-core.

70 lines (69 loc) • 2.57 kB
import { registerDecodedCommentHandlers, registerOperationSession } from "../bridge.js"; import { decodeCommentId } from "../codecs.js"; import { toAgentChange } from "./shared.js"; //#region src/bridges/reviewer.ts const toAgentCommentReply = (reply) => ({ id: String(reply.id), author: reply.author, text: reply.text }); const toAgentComment = (comment) => ({ id: String(comment.id), author: comment.author, text: comment.text, resolved: comment.done, blockId: comment.blockId, quote: comment.anchoredText, replies: comment.replies.map(toAgentCommentReply) }); /** * Build a {@link FolioAgentBridge} over a headless {@link FolioDocxReviewer} * (`@stll/folio-core/server`). No optional capability members are * implemented: a headless document has no live page/selection/scroll * surface, so `read_page`, `read_selection`, and `scroll_to_block` report an * unsupported-capability error via {@link executeFolioToolCall} on this * bridge. */ const createReviewerBridge = (reviewer, options = {}) => { const mode = options.mode ?? "tracked-changes"; const { revisionStamp } = options; const applyOptions = revisionStamp === void 0 ? {} : { revisionStamp }; const replyDate = revisionStamp === void 0 ? {} : { date: revisionStamp.date }; const bridge = { snapshot: () => reviewer.snapshot(), documentOperationMode: mode, applyDocumentOperations: (batch) => reviewer.applyDocumentOperations(batch.mode === void 0 ? { ...batch, mode } : batch, { ...applyOptions, undefinedReferences: "refuse" }), undoDocumentOperations: (undoHandle) => reviewer.undoDocumentOperations(undoHandle), getComments: () => reviewer.getComments().map(toAgentComment), getChanges: () => reviewer.getChanges().map(toAgentChange), listStories: () => reviewer.listStories(), readStory: (handle) => reviewer.readStory(handle), replyToComment: (commentId, text) => { const decoded = decodeCommentId(commentId); return decoded !== null && reviewer.replyTo(decoded.numeric, { text, ...replyDate }) !== null; }, resolveComment: (commentId, resolved) => { const decoded = decodeCommentId(commentId); return decoded !== null && reviewer.resolveComment(decoded.raw, { resolved }); } }; registerOperationSession(bridge, reviewer); return registerDecodedCommentHandlers(bridge, { replyToComment: ({ numeric }, text) => reviewer.replyTo(numeric, { text, ...replyDate }) !== null, resolveComment: ({ raw }, resolved) => reviewer.resolveComment(raw, { resolved }) }); }; //#endregion export { createReviewerBridge };