MCPcopy Create free account
hub / github.com/scriptscat/scriptcat / createOPFSTools

Function createOPFSTools

src/app/service/agent/core/tools/opfs_tools.ts:133–247  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

131// ---- Factory ----
132
133export function createOPFSTools(): {
134 tools: Array<{ definition: ToolDefinition; executor: ToolExecutor }>;
135} {
136 const writeExecutor: ToolExecutor = {
137 execute: async (args: Record<string, unknown>) => {
138 const path = requireString(args, "path");
139 const result = await writeWorkspaceFile(path, args.content as string | Blob);
140 return JSON.stringify(result);
141 },
142 };
143
144 const readExecutor: ToolExecutor = {
145 execute: async (args: Record<string, unknown>) => {
146 const safePath = sanitizePath(requireString(args, "path"));
147 if (!safePath) throw new Error("path is required");
148
149 const workspace = await getWorkspaceRoot();
150 const { dirPath, fileName } = splitPath(safePath);
151 const dir = dirPath ? await getDirectory(workspace, dirPath) : workspace;
152 const fileHandle = await dir.getFileHandle(fileName);
153 const file = await fileHandle.getFile();
154 const mimeType = guessMimeType(safePath);
155 const arrayBuffer = await file.arrayBuffer();
156
157 // 确定返回模式:auto 通过内容字节检测文本/二进制
158 const mode = (args.mode as string) || "auto";
159 const useText = mode === "text" || (mode === "auto" && isText(new Uint8Array(arrayBuffer)));
160
161 // blob 模式:返回 blob URL
162 if (!useText) {
163 if (!createBlobUrlFn) {
164 throw new Error("Blob URL creation not available (Offscreen not initialized)");
165 }
166 const blobUrl = await createBlobUrlFn(arrayBuffer, mimeType);
167 return JSON.stringify({ path: safePath, blobUrl, size: file.size, mimeType, type: "binary" });
168 }
169
170 // text 模式:返回文本内容
171 const text = new TextDecoder().decode(arrayBuffer);
172 const lines = text.split("\n");
173 const totalLines = lines.length;
174
175 const offset = typeof args.offset === "number" ? args.offset : undefined;
176 const limit = typeof args.limit === "number" ? args.limit : undefined;
177
178 // 超过行数限制且未指定分页参数,报错要求分段读取
179 if (offset == null && limit == null && totalLines > MAX_TEXT_LINES) {
180 throw new Error(
181 `文件共 ${totalLines} 行,超过单次读取上限(${MAX_TEXT_LINES} 行)。` +
182 `请使用 offset 和 limit 参数分段读取,例如:offset=1, limit=${MAX_TEXT_LINES}`
183 );
184 }
185
186 const startLine = offset != null ? Math.max(1, offset) : 1;
187 const endLine = limit != null ? Math.min(totalLines, startLine + limit - 1) : totalLines;
188 const selectedLines = lines.slice(startLine - 1, endLine);
189 const content = selectedLines.join("\n");
190

Callers 4

handleOPFSApiMethod · 0.90
initMethod · 0.90
getToolFunction · 0.90
opfs_tools.test.tsFile · 0.90

Calls 11

requireStringFunction · 0.90
writeWorkspaceFileFunction · 0.90
sanitizePathFunction · 0.90
getWorkspaceRootFunction · 0.90
splitPathFunction · 0.90
getDirectoryFunction · 0.90
isTextFunction · 0.90
guessMimeTypeFunction · 0.85
pushMethod · 0.80
arrayBufferMethod · 0.45
sliceMethod · 0.45

Tested by 1

getToolFunction · 0.72