@standardagents/builder 0.10.1-next.bbd142a → 0.11.0-next.ab7e1ea

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/LICENSE.txt ADDED
@@ -0,0 +1,48 @@
1
+ PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2024-2025 FormKit Inc. All Rights Reserved.
4
+
5
+ UNLICENSED - DO NOT USE
6
+
7
+ This software and associated documentation files (the "Software") are the sole
8
+ and exclusive property of FormKit Inc. ("FormKit").
9
+
10
+ USE RESTRICTIONS
11
+
12
+ The Software is UNLICENSED and proprietary. NO PERMISSION is granted to use,
13
+ copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14
+ the Software, or to permit persons to whom the Software is furnished to do so,
15
+ under any circumstances, without prior written authorization from FormKit Inc.
16
+
17
+ UNAUTHORIZED USE PROHIBITED
18
+
19
+ Any use of this Software without a valid, written license agreement signed by
20
+ authorized officers of FormKit Inc. is strictly prohibited and constitutes
21
+ unauthorized use and infringement of FormKit's intellectual property rights.
22
+
23
+ LICENSING INQUIRIES
24
+
25
+ Organizations interested in licensing this Software should contact:
26
+ enterprise@formkit.com
27
+
28
+ A written license agreement must be executed before any use of this Software
29
+ is authorized.
30
+
31
+ NO WARRANTY
32
+
33
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
36
+ FORMKIT INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
37
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
38
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39
+
40
+ GOVERNING LAW
41
+
42
+ This license shall be governed by and construed in accordance with the laws
43
+ of the jurisdiction in which FormKit Inc. is incorporated, without regard to
44
+ its conflict of law provisions.
45
+
46
+ FormKit Inc.
47
+ https://formkit.com
48
+ enterprise@formkit.com
@@ -777,6 +777,11 @@ var providers_get_default = defineController(async ({ env }) => {
777
777
 
778
778
  // src/api/threads/index.post.ts
779
779
  var index_post_default3 = defineController(async ({ req, env }) => {
780
+ const authResult = await requireAuth(req, env);
781
+ if (authResult instanceof Response) {
782
+ return authResult;
783
+ }
784
+ const auth = authResult;
780
785
  let body;
781
786
  try {
782
787
  body = await req.json();
@@ -786,7 +791,8 @@ var index_post_default3 = defineController(async ({ req, env }) => {
786
791
  { status: 400 }
787
792
  );
788
793
  }
789
- const { agent_id, user_id, initial_messages, data, tags } = body;
794
+ const { agent_id, initial_messages, data, tags } = body;
795
+ const user_id = auth.authType === "super_admin" ? null : auth.user.id;
790
796
  if (!agent_id) {
791
797
  return Response.json(
792
798
  { error: "Missing required field: agent_id" },
@@ -828,7 +834,7 @@ var index_post_default3 = defineController(async ({ req, env }) => {
828
834
  try {
829
835
  const thread = await agentBuilder.createThread({
830
836
  agent_name: agent_id,
831
- user_id,
837
+ user_id: user_id ?? void 0,
832
838
  tags
833
839
  });
834
840
  return Response.json({
@@ -848,16 +854,32 @@ var index_post_default3 = defineController(async ({ req, env }) => {
848
854
  });
849
855
 
850
856
  // src/api/threads/index.ts
857
+ function resolveIconUrl(icon, origin) {
858
+ if (!icon) return void 0;
859
+ if (icon.startsWith("http://") || icon.startsWith("https://")) {
860
+ return icon;
861
+ }
862
+ if (icon.startsWith("/")) {
863
+ return `${origin}${icon}`;
864
+ }
865
+ return icon;
866
+ }
851
867
  var threads_default = defineController(async ({ req, env }) => {
852
868
  if (req.method !== "GET") {
853
869
  return new Response("Method Not Allowed", { status: 405 });
854
870
  }
871
+ const authResult = await requireAuth(req, env);
872
+ if (authResult instanceof Response) {
873
+ return authResult;
874
+ }
875
+ const auth = authResult;
855
876
  try {
856
877
  const url = new URL(req.url);
878
+ const origin = url.origin;
857
879
  const limit = parseInt(url.searchParams.get("limit") || "50", 10);
858
880
  const offset = parseInt(url.searchParams.get("offset") || "0", 10);
859
881
  const agentName = url.searchParams.get("agent_id");
860
- const userId = url.searchParams.get("user_id");
882
+ const userId = auth.user.role === "admin" ? void 0 : auth.user.id;
861
883
  const agentBuilderId = env.AGENT_BUILDER.idFromName("singleton");
862
884
  const agentBuilder = env.AGENT_BUILDER.get(agentBuilderId);
863
885
  const result = await agentBuilder.listThreads({
@@ -872,11 +894,14 @@ var threads_default = defineController(async ({ req, env }) => {
872
894
  try {
873
895
  const agentDef = await agentBuilder.loadAgent(thread.agent_name);
874
896
  agentDetails = {
875
- title: agentDef.title,
876
- type: agentDef.type || "ai_human"
897
+ name: thread.agent_name,
898
+ title: agentDef.title || thread.agent_name,
899
+ type: agentDef.type || "ai_human",
900
+ description: agentDef.description,
901
+ icon: resolveIconUrl(agentDef.icon, origin)
877
902
  };
878
903
  } catch {
879
- agentDetails = { title: thread.agent_name, type: "unknown" };
904
+ agentDetails = { name: thread.agent_name, title: thread.agent_name, type: "unknown" };
880
905
  }
881
906
  return {
882
907
  id: thread.id,
@@ -1065,6 +1090,7 @@ var index_get_default2 = defineController(async ({ req, env }) => {
1065
1090
  });
1066
1091
 
1067
1092
  // src/api/users/index.post.ts
1093
+ var VALID_ROLES = ["admin", "user"];
1068
1094
  var index_post_default4 = defineController(async ({ req, env }) => {
1069
1095
  try {
1070
1096
  const authResult = await requireAdmin(req, env);
@@ -1072,7 +1098,7 @@ var index_post_default4 = defineController(async ({ req, env }) => {
1072
1098
  return authResult;
1073
1099
  }
1074
1100
  const body = await req.json();
1075
- const { username, password, role = "admin" } = body;
1101
+ const { username, password, role = "user" } = body;
1076
1102
  if (!username || !password) {
1077
1103
  return Response.json(
1078
1104
  { error: "Username and password are required" },
@@ -1097,6 +1123,12 @@ var index_post_default4 = defineController(async ({ req, env }) => {
1097
1123
  { status: 400 }
1098
1124
  );
1099
1125
  }
1126
+ if (!VALID_ROLES.includes(role)) {
1127
+ return Response.json(
1128
+ { error: `Invalid role. Must be one of: ${VALID_ROLES.join(", ")}` },
1129
+ { status: 400 }
1130
+ );
1131
+ }
1100
1132
  const agentBuilderId = env.AGENT_BUILDER.idFromName("singleton");
1101
1133
  const agentBuilder = env.AGENT_BUILDER.get(agentBuilderId);
1102
1134
  const existingUser = await agentBuilder.getUserByUsername(username);
@@ -1317,8 +1349,24 @@ var name_get_default2 = defineController(async ({ params, prompts, models, model
1317
1349
  }
1318
1350
  });
1319
1351
 
1352
+ // src/utils/permissions.ts
1353
+ function canAccessThread(auth, thread) {
1354
+ if (auth.user.role === "admin") {
1355
+ return true;
1356
+ }
1357
+ if (thread.user_id === null) {
1358
+ return false;
1359
+ }
1360
+ return thread.user_id === auth.user.id;
1361
+ }
1362
+
1320
1363
  // src/api/threads/[id].delete.ts
1321
1364
  var id_delete_default2 = defineController(async ({ req, env, params }) => {
1365
+ const authResult = await requireAuth(req, env);
1366
+ if (authResult instanceof Response) {
1367
+ return authResult;
1368
+ }
1369
+ const auth = authResult;
1322
1370
  const threadId = params.id;
1323
1371
  if (!threadId) {
1324
1372
  return Response.json({ error: "Missing thread ID" }, { status: 400 });
@@ -1332,6 +1380,12 @@ var id_delete_default2 = defineController(async ({ req, env, params }) => {
1332
1380
  { status: 404 }
1333
1381
  );
1334
1382
  }
1383
+ if (!canAccessThread(auth, thread)) {
1384
+ return Response.json(
1385
+ { error: "Forbidden: You don't have access to this thread" },
1386
+ { status: 403 }
1387
+ );
1388
+ }
1335
1389
  try {
1336
1390
  await agentBuilder.deleteThread(threadId);
1337
1391
  const durableId = env.AGENT_BUILDER_THREAD.idFromName(threadId);
@@ -1359,6 +1413,11 @@ var id_patch_default = defineController(async ({ req, env, params }) => {
1359
1413
  if (req.method !== "PATCH") {
1360
1414
  return new Response("Method Not Allowed", { status: 405 });
1361
1415
  }
1416
+ const authResult = await requireAuth(req, env);
1417
+ if (authResult instanceof Response) {
1418
+ return authResult;
1419
+ }
1420
+ const auth = authResult;
1362
1421
  const threadId = params?.id;
1363
1422
  if (!threadId) {
1364
1423
  return Response.json({ error: "Thread ID required" }, { status: 400 });
@@ -1375,6 +1434,12 @@ var id_patch_default = defineController(async ({ req, env, params }) => {
1375
1434
  { status: 404 }
1376
1435
  );
1377
1436
  }
1437
+ if (!canAccessThread(auth, existingThread)) {
1438
+ return Response.json(
1439
+ { error: "Forbidden: You don't have access to this thread" },
1440
+ { status: 403 }
1441
+ );
1442
+ }
1378
1443
  const updates = {};
1379
1444
  if (tags !== void 0) {
1380
1445
  if (!Array.isArray(tags)) {
@@ -1447,12 +1512,42 @@ var id_patch_default = defineController(async ({ req, env, params }) => {
1447
1512
  });
1448
1513
 
1449
1514
  // src/api/threads/[id].ts
1515
+ function resolveIconUrl2(icon, origin) {
1516
+ if (!icon) return void 0;
1517
+ if (icon.startsWith("http://") || icon.startsWith("https://")) {
1518
+ return icon;
1519
+ }
1520
+ if (icon.startsWith("/")) {
1521
+ return `${origin}${icon}`;
1522
+ }
1523
+ return icon;
1524
+ }
1450
1525
  var id_default = defineController(async ({ req, params, env }) => {
1526
+ const authResult = await requireAuth(req, env);
1527
+ if (authResult instanceof Response) {
1528
+ return authResult;
1529
+ }
1530
+ const auth = authResult;
1451
1531
  const threadId = params.id;
1452
1532
  if (!threadId) {
1453
1533
  return Response.json({ error: "Thread ID required" }, { status: 400 });
1454
1534
  }
1455
1535
  try {
1536
+ const agentBuilderId = env.AGENT_BUILDER.idFromName("singleton");
1537
+ const agentBuilder = env.AGENT_BUILDER.get(agentBuilderId);
1538
+ const thread = await agentBuilder.getThread(threadId);
1539
+ if (!thread) {
1540
+ return Response.json(
1541
+ { error: `Thread not found: ${threadId}` },
1542
+ { status: 404 }
1543
+ );
1544
+ }
1545
+ if (!canAccessThread(auth, thread)) {
1546
+ return Response.json(
1547
+ { error: "Forbidden: You don't have access to this thread" },
1548
+ { status: 403 }
1549
+ );
1550
+ }
1456
1551
  const durableId = env.AGENT_BUILDER_THREAD.idFromName(threadId);
1457
1552
  const stub = env.AGENT_BUILDER_THREAD.get(durableId);
1458
1553
  const doData = await stub.getThreadMeta(threadId);
@@ -1462,6 +1557,10 @@ var id_default = defineController(async ({ req, params, env }) => {
1462
1557
  { status: 404 }
1463
1558
  );
1464
1559
  }
1560
+ if (doData.agent?.icon) {
1561
+ const origin = new URL(req.url).origin;
1562
+ doData.agent.icon = resolveIconUrl2(doData.agent.icon, origin);
1563
+ }
1465
1564
  return Response.json(doData);
1466
1565
  } catch (error) {
1467
1566
  console.error(`Error fetching thread ${threadId}:`, error);
@@ -1624,7 +1723,7 @@ var login_post_default = defineController(async ({ req, env }) => {
1624
1723
  { status: 400 }
1625
1724
  );
1626
1725
  }
1627
- if (env.SUPER_ADMIN_PASSWORD && password === env.SUPER_ADMIN_PASSWORD) {
1726
+ if (env.SUPER_ADMIN_PASSWORD && username === "admin" && password === env.SUPER_ADMIN_PASSWORD) {
1628
1727
  if (!env.ENCRYPTION_KEY) {
1629
1728
  return Response.json(
1630
1729
  { error: "Server misconfigured: ENCRYPTION_KEY required for super admin" },
@@ -2077,7 +2176,7 @@ var logs_get_default = defineController(async ({ req, params, env }) => {
2077
2176
  }
2078
2177
  });
2079
2178
 
2080
- // src/api/threads/[id]/message.post.ts
2179
+ // src/api/threads/[id]/messages.post.ts
2081
2180
  function needsProcessing(base64Data, mimeType) {
2082
2181
  const binarySize = Math.ceil(base64Data.length * 3 / 4);
2083
2182
  const MAX_SIZE = 2 * 1024 * 1024;
@@ -2089,7 +2188,7 @@ function needsProcessing(base64Data, mimeType) {
2089
2188
  }
2090
2189
  return false;
2091
2190
  }
2092
- var message_post_default = defineController(async ({ req, params, env }) => {
2191
+ var messages_post_default = defineController(async ({ req, params, env }) => {
2093
2192
  const threadId = params.id;
2094
2193
  if (!threadId) {
2095
2194
  return Response.json({ error: "Thread ID required" }, { status: 400 });
@@ -2148,9 +2247,6 @@ var message_post_default = defineController(async ({ req, params, env }) => {
2148
2247
  }
2149
2248
  const ext = mimeType === "image/png" ? "png" : mimeType === "image/jpeg" ? "jpg" : attachment.name.split(".").pop() || "bin";
2150
2249
  const path = `/attachments/${timestamp}-${attachmentId}.${ext}`;
2151
- const metadata = {};
2152
- if (width) metadata.width = width;
2153
- if (height) metadata.height = height;
2154
2250
  const base64Size = fileData.length;
2155
2251
  const binarySize = Math.ceil(base64Size * 3 / 4);
2156
2252
  console.log(`[writeFile] Storing ${attachment.name}: ${(binarySize / 1024 / 1024).toFixed(2)}MB binary (${(base64Size / 1024 / 1024).toFixed(2)}MB base64) to ${path}`);
@@ -2159,8 +2255,9 @@ var message_post_default = defineController(async ({ req, params, env }) => {
2159
2255
  fileData,
2160
2256
  mimeType,
2161
2257
  {
2162
- metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
2163
- thumbnail: attachment.thumbnail
2258
+ thumbnail: attachment.thumbnail,
2259
+ width,
2260
+ height
2164
2261
  }
2165
2262
  );
2166
2263
  console.log(`[writeFile] Result:`, result.success ? "success" : result.error);
@@ -2323,6 +2420,22 @@ var stream_default = defineController(async ({ req, params, env }) => {
2323
2420
  });
2324
2421
 
2325
2422
  // src/api/threads/[id]/fs/[...path].ts
2423
+ function toAttachmentRef(file) {
2424
+ const metadata = file.metadata;
2425
+ const width = file.width ?? metadata?.width;
2426
+ const height = file.height ?? metadata?.height;
2427
+ return {
2428
+ id: file.path,
2429
+ // Use path as unique ID
2430
+ type: "file",
2431
+ path: file.path,
2432
+ name: file.name,
2433
+ mimeType: file.mimeType,
2434
+ size: file.size,
2435
+ ...width && { width },
2436
+ ...height && { height }
2437
+ };
2438
+ }
2326
2439
  var path_default = defineController(async ({ req, params, env }) => {
2327
2440
  console.log("[fs] params received:", JSON.stringify(params));
2328
2441
  const threadId = params.id;
@@ -2444,7 +2557,7 @@ async function handlePut(stub, path, req) {
2444
2557
  if (!result2.success) {
2445
2558
  return Response.json({ error: result2.error }, { status: 400 });
2446
2559
  }
2447
- return Response.json({ file: result2.file }, { status: 201 });
2560
+ return Response.json(toAttachmentRef(result2.file), { status: 201 });
2448
2561
  }
2449
2562
  if (body.data) {
2450
2563
  const result2 = await stub.writeFile(path, body.data, body.mimeType || "application/octet-stream", {
@@ -2454,7 +2567,7 @@ async function handlePut(stub, path, req) {
2454
2567
  if (!result2.success) {
2455
2568
  return Response.json({ error: result2.error }, { status: 400 });
2456
2569
  }
2457
- return Response.json({ file: result2.file }, { status: 201 });
2570
+ return Response.json(toAttachmentRef(result2.file), { status: 201 });
2458
2571
  }
2459
2572
  return Response.json({ error: "Invalid request body" }, { status: 400 });
2460
2573
  }
@@ -2470,7 +2583,7 @@ async function handlePut(stub, path, req) {
2470
2583
  if (!result.success) {
2471
2584
  return Response.json({ error: result.error }, { status: 400 });
2472
2585
  }
2473
- return Response.json({ file: result.file }, { status: 201 });
2586
+ return Response.json(toAttachmentRef(result.file), { status: 201 });
2474
2587
  }
2475
2588
  async function handleDelete(stub, path) {
2476
2589
  const statResult = await stub.statFile(path);
@@ -2654,7 +2767,7 @@ var routeHandlers = {
2654
2767
  "GET:/threads/:id/cost": cost_get_default,
2655
2768
  "GET:/threads/:id/fs": fs_default,
2656
2769
  "GET:/threads/:id/logs": logs_get_default,
2657
- "POST:/threads/:id/message": message_post_default,
2770
+ "POST:/threads/:id/messages": messages_post_default,
2658
2771
  "GET:/threads/:id/messages": messages_get_default,
2659
2772
  "POST:/threads/:id/rpc": rpc_post_default,
2660
2773
  "POST:/threads/:id/stop": stop_post_default,