Skip to content

Commit cf6d0da

Browse files
committed
✨ CAT.agent.opfs.write 支持 Blob 和 data URL 二进制写入
- writeWorkspaceFile 支持 Uint8Array、Blob、data URL 字符串三种输入 - data URL 自动检测并解码为原始二进制存储 - OPFSApiRequest write content 类型扩展为 string | Blob - GM API CAT.agent.opfs.write 参数同步更新
1 parent 2a1314e commit cf6d0da

4 files changed

Lines changed: 31 additions & 6 deletions

File tree

src/app/service/agent/opfs_helpers.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,47 @@ export function decodeDataUrl(dataUrl: string): { data: Uint8Array; mimeType: st
6363
return { data: bytes, mimeType };
6464
}
6565

66+
/** 检测字符串是否是 data URL */
67+
export function isDataUrl(str: string): boolean {
68+
return /^data:[^;]+;base64,/.test(str);
69+
}
70+
6671
/** 将二进制数据写入 OPFS workspace 指定路径 */
6772
export async function writeWorkspaceFile(
6873
path: string,
69-
data: Uint8Array | string
74+
data: Uint8Array | Blob | string
7075
): Promise<{ path: string; size: number }> {
7176
const safePath = sanitizePath(path);
7277
if (!safePath) throw new Error("path is required");
7378

79+
// data URL 字符串自动解码为二进制
80+
if (typeof data === "string" && isDataUrl(data)) {
81+
const decoded = decodeDataUrl(data);
82+
data = decoded.data;
83+
}
84+
7485
const workspace = await getWorkspaceRoot(true);
7586
const { dirPath, fileName } = splitPath(safePath);
7687
const dir = dirPath ? await getDirectory(workspace, dirPath, true) : workspace;
7788
const fileHandle = await dir.getFileHandle(fileName, { create: true });
7889
const writable = await fileHandle.createWritable();
79-
await writable.write(data instanceof Uint8Array ? (data.buffer as ArrayBuffer) : data);
90+
91+
if (data instanceof Blob) {
92+
await writable.write(data);
93+
} else if (data instanceof Uint8Array) {
94+
await writable.write(data.buffer as ArrayBuffer);
95+
} else {
96+
await writable.write(data);
97+
}
8098
await writable.close();
8199

82-
const size = typeof data === "string" ? new Blob([data]).size : data.byteLength;
100+
let size: number;
101+
if (data instanceof Blob) {
102+
size = data.size;
103+
} else if (data instanceof Uint8Array) {
104+
size = data.byteLength;
105+
} else {
106+
size = new Blob([data]).size;
107+
}
83108
return { path: safePath, size };
84109
}

src/app/service/agent/tools/opfs_tools.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export function createOPFSTools(): {
109109
} {
110110
const writeExecutor: ToolExecutor = {
111111
execute: async (args: Record<string, unknown>) => {
112-
const result = await writeWorkspaceFile(args.path as string, args.content as string);
112+
const result = await writeWorkspaceFile(args.path as string, args.content as string | Blob);
113113
return JSON.stringify(result);
114114
},
115115
};

src/app/service/agent/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export type SkillApiRequest =
251251

252252
// CAT.agent.opfs API 请求
253253
export type OPFSApiRequest =
254-
| { action: "write"; path: string; content: string; scriptUuid: string }
254+
| { action: "write"; path: string; content: string | Blob; scriptUuid: string }
255255
| { action: "read"; path: string; format?: "text" | "bloburl"; scriptUuid: string }
256256
| { action: "list"; path?: string; scriptUuid: string }
257257
| { action: "delete"; path: string; scriptUuid: string };

src/app/service/content/gm_api/cat_agent_opfs.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default class CATAgentOPFSApi {
2525
protected scriptRes?: { uuid: string };
2626

2727
@GMContext.API({ follow: "CAT.agent.opfs" })
28-
public "CAT.agent.opfs.write"(path: string, content: string): Promise<{ path: string; size: number }> {
28+
public "CAT.agent.opfs.write"(path: string, content: string | Blob): Promise<{ path: string; size: number }> {
2929
const ctx = this as unknown as GMBaseContext;
3030
return ctx.sendMessage("CAT_agentOPFS", [
3131
{ action: "write", path, content, scriptUuid: ctx.scriptRes?.uuid || "" } as OPFSApiRequest,

0 commit comments

Comments
 (0)