@standardagents/builder 0.11.0-next.ab7e1ea → 0.11.0-next.af971ae
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/built-in-routes.js +230 -66
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/assets/index.css +1 -1
- package/dist/client/index.js +25 -19
- package/dist/client/vendor.js +1 -1
- package/dist/client/vue.js +1 -1
- package/dist/index.d.ts +367 -814
- package/dist/index.js +4581 -3839
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +18 -61
- package/dist/plugin.js.map +1 -1
- package/package.json +4 -2
package/dist/built-in-routes.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import '@standardagents/spec';
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
|
|
3
4
|
// ../../node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.mjs
|
|
@@ -77,8 +78,6 @@ function getParamRegexp(segment) {
|
|
|
77
78
|
const regex = segment.replace(/:(\w+)/g, (_, id) => `(?<${id}>[^/]+)`).replace(/\./g, "\\.");
|
|
78
79
|
return /* @__PURE__ */ new RegExp(`^${regex}$`);
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
// src/router/index.ts
|
|
82
81
|
function defineController(controller) {
|
|
83
82
|
return controller;
|
|
84
83
|
}
|
|
@@ -145,8 +144,8 @@ var agents_get_default = defineController(async ({ agents, agentNames, prompts,
|
|
|
145
144
|
side_a_stop_on_response: definition.sideA?.stopOnResponse !== void 0 ? definition.sideA.stopOnResponse : true,
|
|
146
145
|
side_a_stop_tool: definition.sideA?.stopTool || null,
|
|
147
146
|
side_a_stop_tool_response_property: definition.sideA?.stopToolResponseProperty || null,
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
side_a_max_steps: definition.sideA?.maxSteps || null,
|
|
148
|
+
side_a_end_session_tool: definition.sideA?.endSessionTool || null,
|
|
150
149
|
side_a_manual_stop_condition: definition.sideA?.manualStopCondition || false,
|
|
151
150
|
// Side B configuration (if dual_ai)
|
|
152
151
|
side_b_label: definition.sideB?.label || null,
|
|
@@ -155,16 +154,14 @@ var agents_get_default = defineController(async ({ agents, agentNames, prompts,
|
|
|
155
154
|
side_b_stop_on_response: definition.sideB?.stopOnResponse !== void 0 ? definition.sideB.stopOnResponse : true,
|
|
156
155
|
side_b_stop_tool: definition.sideB?.stopTool || null,
|
|
157
156
|
side_b_stop_tool_response_property: definition.sideB?.stopToolResponseProperty || null,
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
side_b_max_steps: definition.sideB?.maxSteps || null,
|
|
158
|
+
side_b_end_session_tool: definition.sideB?.endSessionTool || null,
|
|
160
159
|
side_b_manual_stop_condition: definition.sideB?.manualStopCondition || false,
|
|
161
160
|
// Session configuration
|
|
162
161
|
max_session_turns: definition.maxSessionTurns || null,
|
|
163
162
|
// Tool exposure
|
|
164
163
|
expose_as_tool: definition.exposeAsTool || false,
|
|
165
164
|
tool_description: definition.toolDescription || null,
|
|
166
|
-
// Tags
|
|
167
|
-
tags: definition.tags || [],
|
|
168
165
|
created_at: Math.floor(Date.now() / 1e3)
|
|
169
166
|
};
|
|
170
167
|
} catch (error) {
|
|
@@ -733,10 +730,7 @@ var prompts_get_default = defineController(async ({ prompts, promptNames, models
|
|
|
733
730
|
include_past_tools: definition.includePastTools || false,
|
|
734
731
|
parallel_tool_calls: definition.parallelToolCalls || false,
|
|
735
732
|
tool_choice: definition.toolChoice || "auto",
|
|
736
|
-
before_tool: definition.beforeTool || null,
|
|
737
|
-
after_tool: definition.afterTool || null,
|
|
738
733
|
tools,
|
|
739
|
-
prompts: definition.handoffAgents || [],
|
|
740
734
|
reasoning: definition.reasoning || null,
|
|
741
735
|
created_at: Math.floor(Date.now() / 1e3)
|
|
742
736
|
};
|
|
@@ -1200,8 +1194,8 @@ var name_get_default = defineController(async ({ params, agents, prompts, prompt
|
|
|
1200
1194
|
side_a_stop_on_response: definition.sideA?.stopOnResponse !== void 0 ? definition.sideA.stopOnResponse : true,
|
|
1201
1195
|
side_a_stop_tool: definition.sideA?.stopTool || null,
|
|
1202
1196
|
side_a_stop_tool_response_property: definition.sideA?.stopToolResponseProperty || null,
|
|
1203
|
-
|
|
1204
|
-
|
|
1197
|
+
side_a_max_steps: definition.sideA?.maxSteps || null,
|
|
1198
|
+
side_a_end_session_tool: definition.sideA?.endSessionTool || null,
|
|
1205
1199
|
side_a_manual_stop_condition: definition.sideA?.manualStopCondition || false,
|
|
1206
1200
|
// Side B configuration (if dual_ai)
|
|
1207
1201
|
side_b_label: definition.sideB?.label || null,
|
|
@@ -1210,16 +1204,14 @@ var name_get_default = defineController(async ({ params, agents, prompts, prompt
|
|
|
1210
1204
|
side_b_stop_on_response: definition.sideB?.stopOnResponse !== void 0 ? definition.sideB.stopOnResponse : true,
|
|
1211
1205
|
side_b_stop_tool: definition.sideB?.stopTool || null,
|
|
1212
1206
|
side_b_stop_tool_response_property: definition.sideB?.stopToolResponseProperty || null,
|
|
1213
|
-
|
|
1214
|
-
|
|
1207
|
+
side_b_max_steps: definition.sideB?.maxSteps || null,
|
|
1208
|
+
side_b_end_session_tool: definition.sideB?.endSessionTool || null,
|
|
1215
1209
|
side_b_manual_stop_condition: definition.sideB?.manualStopCondition || false,
|
|
1216
1210
|
// Session configuration
|
|
1217
1211
|
max_session_turns: definition.maxSessionTurns || null,
|
|
1218
1212
|
// Tool exposure
|
|
1219
1213
|
expose_as_tool: definition.exposeAsTool || false,
|
|
1220
1214
|
tool_description: definition.toolDescription || null,
|
|
1221
|
-
// Tags
|
|
1222
|
-
tags: definition.tags || [],
|
|
1223
1215
|
created_at: Math.floor(Date.now() / 1e3)
|
|
1224
1216
|
};
|
|
1225
1217
|
return Response.json({ agent });
|
|
@@ -1332,10 +1324,7 @@ var name_get_default2 = defineController(async ({ params, prompts, models, model
|
|
|
1332
1324
|
include_past_tools: definition.includePastTools || false,
|
|
1333
1325
|
parallel_tool_calls: definition.parallelToolCalls || false,
|
|
1334
1326
|
tool_choice: definition.toolChoice || "auto",
|
|
1335
|
-
before_tool: definition.beforeTool || null,
|
|
1336
|
-
after_tool: definition.afterTool || null,
|
|
1337
1327
|
tools,
|
|
1338
|
-
prompts: definition.handoffAgents || [],
|
|
1339
1328
|
reasoning: definition.reasoning || null,
|
|
1340
1329
|
created_at: Math.floor(Date.now() / 1e3)
|
|
1341
1330
|
};
|
|
@@ -2176,6 +2165,47 @@ var logs_get_default = defineController(async ({ req, params, env }) => {
|
|
|
2176
2165
|
}
|
|
2177
2166
|
});
|
|
2178
2167
|
|
|
2168
|
+
// src/api/threads/[id]/messages.get.ts
|
|
2169
|
+
var messages_get_default = defineController(async ({ req, params, env }) => {
|
|
2170
|
+
const url = new URL(req.url);
|
|
2171
|
+
const threadId = params.id;
|
|
2172
|
+
if (!threadId) {
|
|
2173
|
+
return Response.json({ error: "Thread ID required" }, { status: 400 });
|
|
2174
|
+
}
|
|
2175
|
+
try {
|
|
2176
|
+
const agentBuilderId = env.AGENT_BUILDER.idFromName("singleton");
|
|
2177
|
+
const agentBuilder = env.AGENT_BUILDER.get(agentBuilderId);
|
|
2178
|
+
const thread = await agentBuilder.getThread(threadId);
|
|
2179
|
+
if (!thread) {
|
|
2180
|
+
return Response.json(
|
|
2181
|
+
{ error: `Thread not found: ${threadId}` },
|
|
2182
|
+
{ status: 404 }
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
const limit = parseInt(url.searchParams.get("limit") || "100", 10);
|
|
2186
|
+
const offset = parseInt(url.searchParams.get("offset") || "0", 10);
|
|
2187
|
+
const order = url.searchParams.get("order") === "asc" ? "ASC" : "DESC";
|
|
2188
|
+
const includeSilent = url.searchParams.get("includeSilent") === "true";
|
|
2189
|
+
const maxDepth = parseInt(url.searchParams.get("depth") || "0", 10);
|
|
2190
|
+
const durableId = env.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
2191
|
+
const stub = env.AGENT_BUILDER_THREAD.get(durableId);
|
|
2192
|
+
const result = await stub.getMessages(
|
|
2193
|
+
limit,
|
|
2194
|
+
offset,
|
|
2195
|
+
order,
|
|
2196
|
+
includeSilent,
|
|
2197
|
+
maxDepth
|
|
2198
|
+
);
|
|
2199
|
+
return Response.json(result);
|
|
2200
|
+
} catch (error) {
|
|
2201
|
+
console.error(`Error fetching messages for thread ${threadId}:`, error);
|
|
2202
|
+
return Response.json(
|
|
2203
|
+
{ error: error.message || "Failed to fetch messages" },
|
|
2204
|
+
{ status: 500 }
|
|
2205
|
+
);
|
|
2206
|
+
}
|
|
2207
|
+
});
|
|
2208
|
+
|
|
2179
2209
|
// src/api/threads/[id]/messages.post.ts
|
|
2180
2210
|
function needsProcessing(base64Data, mimeType) {
|
|
2181
2211
|
const binarySize = Math.ceil(base64Data.length * 3 / 4);
|
|
@@ -2288,47 +2318,6 @@ var messages_post_default = defineController(async ({ req, params, env }) => {
|
|
|
2288
2318
|
}
|
|
2289
2319
|
});
|
|
2290
2320
|
|
|
2291
|
-
// src/api/threads/[id]/messages.get.ts
|
|
2292
|
-
var messages_get_default = defineController(async ({ req, params, env }) => {
|
|
2293
|
-
const url = new URL(req.url);
|
|
2294
|
-
const threadId = params.id;
|
|
2295
|
-
if (!threadId) {
|
|
2296
|
-
return Response.json({ error: "Thread ID required" }, { status: 400 });
|
|
2297
|
-
}
|
|
2298
|
-
try {
|
|
2299
|
-
const agentBuilderId = env.AGENT_BUILDER.idFromName("singleton");
|
|
2300
|
-
const agentBuilder = env.AGENT_BUILDER.get(agentBuilderId);
|
|
2301
|
-
const thread = await agentBuilder.getThread(threadId);
|
|
2302
|
-
if (!thread) {
|
|
2303
|
-
return Response.json(
|
|
2304
|
-
{ error: `Thread not found: ${threadId}` },
|
|
2305
|
-
{ status: 404 }
|
|
2306
|
-
);
|
|
2307
|
-
}
|
|
2308
|
-
const limit = parseInt(url.searchParams.get("limit") || "100", 10);
|
|
2309
|
-
const offset = parseInt(url.searchParams.get("offset") || "0", 10);
|
|
2310
|
-
const order = url.searchParams.get("order") === "asc" ? "ASC" : "DESC";
|
|
2311
|
-
const includeSilent = url.searchParams.get("includeSilent") === "true";
|
|
2312
|
-
const maxDepth = parseInt(url.searchParams.get("depth") || "0", 10);
|
|
2313
|
-
const durableId = env.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
2314
|
-
const stub = env.AGENT_BUILDER_THREAD.get(durableId);
|
|
2315
|
-
const result = await stub.getMessages(
|
|
2316
|
-
limit,
|
|
2317
|
-
offset,
|
|
2318
|
-
order,
|
|
2319
|
-
includeSilent,
|
|
2320
|
-
maxDepth
|
|
2321
|
-
);
|
|
2322
|
-
return Response.json(result);
|
|
2323
|
-
} catch (error) {
|
|
2324
|
-
console.error(`Error fetching messages for thread ${threadId}:`, error);
|
|
2325
|
-
return Response.json(
|
|
2326
|
-
{ error: error.message || "Failed to fetch messages" },
|
|
2327
|
-
{ status: 500 }
|
|
2328
|
-
);
|
|
2329
|
-
}
|
|
2330
|
-
});
|
|
2331
|
-
|
|
2332
2321
|
// src/api/threads/[id]/rpc.post.ts
|
|
2333
2322
|
var rpc_post_default = defineController(async ({ req, params, env }) => {
|
|
2334
2323
|
const threadId = params.id;
|
|
@@ -2420,6 +2409,7 @@ var stream_default = defineController(async ({ req, params, env }) => {
|
|
|
2420
2409
|
});
|
|
2421
2410
|
|
|
2422
2411
|
// src/api/threads/[id]/fs/[...path].ts
|
|
2412
|
+
var CHUNK_SIZE = 1.75 * 1024 * 1024;
|
|
2423
2413
|
function toAttachmentRef(file) {
|
|
2424
2414
|
const metadata = file.metadata;
|
|
2425
2415
|
const width = file.width ?? metadata?.width;
|
|
@@ -2449,11 +2439,30 @@ var path_default = defineController(async ({ req, params, env }) => {
|
|
|
2449
2439
|
try {
|
|
2450
2440
|
const durableId = env.AGENT_BUILDER_THREAD.idFromName(threadId);
|
|
2451
2441
|
const stub = env.AGENT_BUILDER_THREAD.get(durableId);
|
|
2442
|
+
const uploadMatch = path.match(/^(.+)\/upload\/(start|complete|chunk\/(\d+))$/);
|
|
2443
|
+
if (uploadMatch) {
|
|
2444
|
+
const filePath = uploadMatch[1];
|
|
2445
|
+
const action = uploadMatch[2];
|
|
2446
|
+
const chunkIndex = uploadMatch[3] ? parseInt(uploadMatch[3], 10) : void 0;
|
|
2447
|
+
if (action === "start" && req.method === "POST") {
|
|
2448
|
+
return handleChunkedUploadStart(stub, filePath, req);
|
|
2449
|
+
}
|
|
2450
|
+
if (action === "complete" && req.method === "POST") {
|
|
2451
|
+
return handleChunkedUploadComplete(stub, filePath, req);
|
|
2452
|
+
}
|
|
2453
|
+
if (action.startsWith("chunk/") && req.method === "PUT" && chunkIndex !== void 0) {
|
|
2454
|
+
return handleChunkedUploadChunk(stub, filePath, chunkIndex, req);
|
|
2455
|
+
}
|
|
2456
|
+
return Response.json(
|
|
2457
|
+
{ error: `Invalid upload action: ${action} with method ${req.method}` },
|
|
2458
|
+
{ status: 400 }
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2452
2461
|
switch (req.method) {
|
|
2453
2462
|
case "GET":
|
|
2454
2463
|
return handleGet(stub, path, url);
|
|
2455
|
-
case "
|
|
2456
|
-
return
|
|
2464
|
+
case "POST":
|
|
2465
|
+
return handlePost(stub, path, req);
|
|
2457
2466
|
case "DELETE":
|
|
2458
2467
|
return handleDelete(stub, path);
|
|
2459
2468
|
default:
|
|
@@ -2520,6 +2529,9 @@ async function handleGet(stub, path, url) {
|
|
|
2520
2529
|
if (acceptHeader === "json") {
|
|
2521
2530
|
return Response.json({ file });
|
|
2522
2531
|
}
|
|
2532
|
+
if (file.isChunked && file.chunkCount) {
|
|
2533
|
+
return streamChunkedFile(stub, path, file);
|
|
2534
|
+
}
|
|
2523
2535
|
const result = await stub.readFile(path);
|
|
2524
2536
|
if (!result.success) {
|
|
2525
2537
|
return Response.json({ error: result.error }, { status: 404 });
|
|
@@ -2537,7 +2549,40 @@ async function handleGet(stub, path, url) {
|
|
|
2537
2549
|
}
|
|
2538
2550
|
});
|
|
2539
2551
|
}
|
|
2540
|
-
|
|
2552
|
+
function streamChunkedFile(stub, path, file) {
|
|
2553
|
+
const { readable, writable } = new TransformStream();
|
|
2554
|
+
const writer = writable.getWriter();
|
|
2555
|
+
(async () => {
|
|
2556
|
+
try {
|
|
2557
|
+
for (let i = 0; i < file.chunkCount; i++) {
|
|
2558
|
+
const result = await stub.readFileChunk(path, i);
|
|
2559
|
+
if (!result.success) {
|
|
2560
|
+
console.error(`Failed to read chunk ${i}:`, result.error);
|
|
2561
|
+
break;
|
|
2562
|
+
}
|
|
2563
|
+
const binary = atob(result.data);
|
|
2564
|
+
const bytes = new Uint8Array(binary.length);
|
|
2565
|
+
for (let j = 0; j < binary.length; j++) {
|
|
2566
|
+
bytes[j] = binary.charCodeAt(j);
|
|
2567
|
+
}
|
|
2568
|
+
await writer.write(bytes);
|
|
2569
|
+
}
|
|
2570
|
+
} catch (error) {
|
|
2571
|
+
console.error("Error streaming chunked file:", error);
|
|
2572
|
+
} finally {
|
|
2573
|
+
await writer.close();
|
|
2574
|
+
}
|
|
2575
|
+
})();
|
|
2576
|
+
return new Response(readable, {
|
|
2577
|
+
headers: {
|
|
2578
|
+
"Content-Type": file.mimeType,
|
|
2579
|
+
"Content-Length": String(file.size),
|
|
2580
|
+
"Content-Disposition": `inline; filename="${file.name}"`
|
|
2581
|
+
// Note: We set Content-Length, but also use chunked transfer internally
|
|
2582
|
+
}
|
|
2583
|
+
});
|
|
2584
|
+
}
|
|
2585
|
+
async function handlePost(stub, path, req) {
|
|
2541
2586
|
const contentType = req.headers.get("Content-Type") || "";
|
|
2542
2587
|
if (contentType.includes("application/json")) {
|
|
2543
2588
|
const body = await req.json();
|
|
@@ -2571,8 +2616,12 @@ async function handlePut(stub, path, req) {
|
|
|
2571
2616
|
}
|
|
2572
2617
|
return Response.json({ error: "Invalid request body" }, { status: 400 });
|
|
2573
2618
|
}
|
|
2574
|
-
const data = await req.arrayBuffer();
|
|
2575
2619
|
const mimeType = contentType.split(";")[0].trim() || "application/octet-stream";
|
|
2620
|
+
const contentLength = parseInt(req.headers.get("Content-Length") || "0", 10);
|
|
2621
|
+
if (contentLength > CHUNK_SIZE && req.body) {
|
|
2622
|
+
return handleStreamingUpload(stub, path, mimeType, contentLength, req);
|
|
2623
|
+
}
|
|
2624
|
+
const data = await req.arrayBuffer();
|
|
2576
2625
|
const bytes = new Uint8Array(data);
|
|
2577
2626
|
let binary = "";
|
|
2578
2627
|
for (let i = 0; i < bytes.length; i++) {
|
|
@@ -2585,6 +2634,64 @@ async function handlePut(stub, path, req) {
|
|
|
2585
2634
|
}
|
|
2586
2635
|
return Response.json(toAttachmentRef(result.file), { status: 201 });
|
|
2587
2636
|
}
|
|
2637
|
+
async function handleStreamingUpload(stub, path, mimeType, totalSize, req) {
|
|
2638
|
+
const startResult = await stub.startChunkedUpload(path, totalSize, mimeType, {});
|
|
2639
|
+
if (!startResult.success) {
|
|
2640
|
+
return Response.json({ error: startResult.error }, { status: 400 });
|
|
2641
|
+
}
|
|
2642
|
+
const reader = req.body.getReader();
|
|
2643
|
+
let chunkIndex = 0;
|
|
2644
|
+
let buffer = new Uint8Array(0);
|
|
2645
|
+
try {
|
|
2646
|
+
while (true) {
|
|
2647
|
+
const { done, value } = await reader.read();
|
|
2648
|
+
if (value) {
|
|
2649
|
+
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
2650
|
+
newBuffer.set(buffer);
|
|
2651
|
+
newBuffer.set(value, buffer.length);
|
|
2652
|
+
buffer = newBuffer;
|
|
2653
|
+
while (buffer.length >= CHUNK_SIZE) {
|
|
2654
|
+
const chunk = buffer.slice(0, CHUNK_SIZE);
|
|
2655
|
+
const base64 = arrayBufferToBase64(chunk);
|
|
2656
|
+
const chunkResult = await stub.writeFileChunk(path, chunkIndex, base64);
|
|
2657
|
+
if (!chunkResult.success) {
|
|
2658
|
+
return Response.json({ error: chunkResult.error }, { status: 400 });
|
|
2659
|
+
}
|
|
2660
|
+
chunkIndex++;
|
|
2661
|
+
buffer = buffer.slice(CHUNK_SIZE);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
if (done) {
|
|
2665
|
+
if (buffer.length > 0) {
|
|
2666
|
+
const base64 = arrayBufferToBase64(buffer);
|
|
2667
|
+
const chunkResult = await stub.writeFileChunk(path, chunkIndex, base64);
|
|
2668
|
+
if (!chunkResult.success) {
|
|
2669
|
+
return Response.json({ error: chunkResult.error }, { status: 400 });
|
|
2670
|
+
}
|
|
2671
|
+
chunkIndex++;
|
|
2672
|
+
}
|
|
2673
|
+
break;
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
const completeResult = await stub.completeChunkedUpload(path, chunkIndex, {});
|
|
2677
|
+
if (!completeResult.success) {
|
|
2678
|
+
return Response.json({ error: completeResult.error }, { status: 400 });
|
|
2679
|
+
}
|
|
2680
|
+
return Response.json(toAttachmentRef(completeResult.file), { status: 201 });
|
|
2681
|
+
} catch (error) {
|
|
2682
|
+
console.error("Streaming upload failed:", error);
|
|
2683
|
+
return Response.json({ error: error.message || "Upload failed" }, { status: 500 });
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
function arrayBufferToBase64(bytes) {
|
|
2687
|
+
const BATCH_SIZE = 32768;
|
|
2688
|
+
let binary = "";
|
|
2689
|
+
for (let i = 0; i < bytes.length; i += BATCH_SIZE) {
|
|
2690
|
+
const slice = bytes.subarray(i, Math.min(i + BATCH_SIZE, bytes.length));
|
|
2691
|
+
binary += String.fromCharCode.apply(null, slice);
|
|
2692
|
+
}
|
|
2693
|
+
return btoa(binary);
|
|
2694
|
+
}
|
|
2588
2695
|
async function handleDelete(stub, path) {
|
|
2589
2696
|
const statResult = await stub.statFile(path);
|
|
2590
2697
|
if (!statResult.success) {
|
|
@@ -2604,6 +2711,61 @@ async function handleDelete(stub, path) {
|
|
|
2604
2711
|
}
|
|
2605
2712
|
return new Response(null, { status: 204 });
|
|
2606
2713
|
}
|
|
2714
|
+
async function handleChunkedUploadStart(stub, filePath, req) {
|
|
2715
|
+
const body = await req.json();
|
|
2716
|
+
if (!body.totalSize || !body.mimeType) {
|
|
2717
|
+
return Response.json(
|
|
2718
|
+
{ error: "totalSize and mimeType are required" },
|
|
2719
|
+
{ status: 400 }
|
|
2720
|
+
);
|
|
2721
|
+
}
|
|
2722
|
+
const result = await stub.startChunkedUpload(filePath, body.totalSize, body.mimeType, {
|
|
2723
|
+
metadata: body.metadata,
|
|
2724
|
+
width: body.width,
|
|
2725
|
+
height: body.height
|
|
2726
|
+
});
|
|
2727
|
+
if (!result.success) {
|
|
2728
|
+
return Response.json({ error: result.error }, { status: 400 });
|
|
2729
|
+
}
|
|
2730
|
+
return Response.json({
|
|
2731
|
+
chunkSize: result.chunkSize,
|
|
2732
|
+
expectedChunks: result.expectedChunks,
|
|
2733
|
+
path: filePath
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
async function handleChunkedUploadChunk(stub, filePath, chunkIndex, req) {
|
|
2737
|
+
const data = await req.arrayBuffer();
|
|
2738
|
+
const bytes = new Uint8Array(data);
|
|
2739
|
+
let binary = "";
|
|
2740
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
2741
|
+
binary += String.fromCharCode(bytes[i]);
|
|
2742
|
+
}
|
|
2743
|
+
const base64 = btoa(binary);
|
|
2744
|
+
const result = await stub.writeFileChunk(filePath, chunkIndex, base64);
|
|
2745
|
+
if (!result.success) {
|
|
2746
|
+
return Response.json({ error: result.error }, { status: 400 });
|
|
2747
|
+
}
|
|
2748
|
+
return Response.json({
|
|
2749
|
+
chunkIndex,
|
|
2750
|
+
received: data.byteLength
|
|
2751
|
+
});
|
|
2752
|
+
}
|
|
2753
|
+
async function handleChunkedUploadComplete(stub, filePath, req) {
|
|
2754
|
+
const body = await req.json();
|
|
2755
|
+
if (typeof body.expectedChunks !== "number") {
|
|
2756
|
+
return Response.json(
|
|
2757
|
+
{ error: "expectedChunks is required" },
|
|
2758
|
+
{ status: 400 }
|
|
2759
|
+
);
|
|
2760
|
+
}
|
|
2761
|
+
const result = await stub.completeChunkedUpload(filePath, body.expectedChunks, {
|
|
2762
|
+
thumbnail: body.thumbnail
|
|
2763
|
+
});
|
|
2764
|
+
if (!result.success) {
|
|
2765
|
+
return Response.json({ error: result.error }, { status: 400 });
|
|
2766
|
+
}
|
|
2767
|
+
return Response.json(toAttachmentRef(result.file), { status: 201 });
|
|
2768
|
+
}
|
|
2607
2769
|
|
|
2608
2770
|
// src/api/threads/[id]/logs/[logId].get.ts
|
|
2609
2771
|
var logId_get_default = defineController(async ({ req, params, env }) => {
|
|
@@ -2767,11 +2929,13 @@ var routeHandlers = {
|
|
|
2767
2929
|
"GET:/threads/:id/cost": cost_get_default,
|
|
2768
2930
|
"GET:/threads/:id/fs": fs_default,
|
|
2769
2931
|
"GET:/threads/:id/logs": logs_get_default,
|
|
2770
|
-
"POST:/threads/:id/messages": messages_post_default,
|
|
2771
2932
|
"GET:/threads/:id/messages": messages_get_default,
|
|
2933
|
+
"POST:/threads/:id/messages": messages_post_default,
|
|
2772
2934
|
"POST:/threads/:id/rpc": rpc_post_default,
|
|
2773
2935
|
"POST:/threads/:id/stop": stop_post_default,
|
|
2774
2936
|
"GET:/threads/:id/stream": stream_default,
|
|
2937
|
+
"DELETE:/threads/:id/fs/**": path_default,
|
|
2938
|
+
"POST:/threads/:id/fs/**": path_default,
|
|
2775
2939
|
"GET:/threads/:id/fs/**": path_default,
|
|
2776
2940
|
"GET:/threads/:id/logs/:logId": logId_get_default,
|
|
2777
2941
|
"DELETE:/threads/:id/messages/:messageId": messageId_delete_default,
|