robotrock 1.3.4 → 1.5.0

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.
Files changed (80) hide show
  1. package/README.md +11 -1
  2. package/dist/agent-admin.d.ts +5 -0
  3. package/dist/agent-admin.js +75 -2
  4. package/dist/agent-admin.js.map +1 -1
  5. package/dist/ai/index.d.ts +5 -5
  6. package/dist/ai/index.js +120 -4
  7. package/dist/ai/index.js.map +1 -1
  8. package/dist/ai/trigger.d.ts +3 -3
  9. package/dist/ai/trigger.js +120 -4
  10. package/dist/ai/trigger.js.map +1 -1
  11. package/dist/ai/workflow.d.ts +3 -3
  12. package/dist/ai/workflow.js +120 -4
  13. package/dist/ai/workflow.js.map +1 -1
  14. package/dist/{client-CZ5eWH5v.d.ts → client-BxbxttFH.d.ts} +19 -1
  15. package/dist/eve/agent/index.d.ts +4 -4
  16. package/dist/eve/agent/index.js +577 -261
  17. package/dist/eve/agent/index.js.map +1 -1
  18. package/dist/eve/index.d.ts +4 -4
  19. package/dist/eve/index.js +507 -7
  20. package/dist/eve/index.js.map +1 -1
  21. package/dist/eve/tools/admin/assign-tasks.d.ts +40 -19
  22. package/dist/eve/tools/admin/assign-tasks.js +334 -25
  23. package/dist/eve/tools/admin/assign-tasks.js.map +1 -1
  24. package/dist/eve/tools/admin/get-workspace-usage.d.ts +71 -0
  25. package/dist/eve/tools/admin/get-workspace-usage.js +1365 -0
  26. package/dist/eve/tools/admin/get-workspace-usage.js.map +1 -0
  27. package/dist/eve/tools/admin/manage-groups.d.ts +122 -7
  28. package/dist/eve/tools/admin/manage-groups.js +350 -31
  29. package/dist/eve/tools/admin/manage-groups.js.map +1 -1
  30. package/dist/eve/tools/admin/manage-team-members.d.ts +86 -7
  31. package/dist/eve/tools/admin/manage-team-members.js +318 -16
  32. package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
  33. package/dist/eve/tools/admin/query-tasks.d.ts +82 -7
  34. package/dist/eve/tools/admin/query-tasks.js +363 -40
  35. package/dist/eve/tools/admin/query-tasks.js.map +1 -1
  36. package/dist/eve/tools/catalog/generate-image.d.ts +64 -0
  37. package/dist/eve/tools/catalog/generate-image.js +2077 -0
  38. package/dist/eve/tools/catalog/generate-image.js.map +1 -0
  39. package/dist/eve/tools/catalog/generate-random-chart.d.ts +77 -0
  40. package/dist/eve/tools/catalog/generate-random-chart.js +411 -0
  41. package/dist/eve/tools/catalog/generate-random-chart.js.map +1 -0
  42. package/dist/eve/tools/catalog/search-products.d.ts +36 -43
  43. package/dist/eve/tools/catalog/search-products.js +253 -6
  44. package/dist/eve/tools/catalog/search-products.js.map +1 -1
  45. package/dist/eve/tools/identity/index.d.ts +2 -1
  46. package/dist/eve/tools/identity/index.js +26 -6
  47. package/dist/eve/tools/identity/index.js.map +1 -1
  48. package/dist/eve/tools/identity/my-access.d.ts +88 -3
  49. package/dist/eve/tools/identity/my-access.js +26 -6
  50. package/dist/eve/tools/identity/my-access.js.map +1 -1
  51. package/dist/eve/tools/identity/whoami.d.ts +1 -1
  52. package/dist/eve/tools/identity/whoami.js.map +1 -1
  53. package/dist/eve/tools/inbox/create-task.d.ts +1 -1
  54. package/dist/eve/tools/inbox/create-task.js +119 -2
  55. package/dist/eve/tools/inbox/create-task.js.map +1 -1
  56. package/dist/eve/tools/inbox/index.d.ts +1 -1
  57. package/dist/eve/tools/inbox/index.js +119 -2
  58. package/dist/eve/tools/inbox/index.js.map +1 -1
  59. package/dist/eve/tools/index.d.ts +5 -2
  60. package/dist/eve/tools/index.js +964 -115
  61. package/dist/eve/tools/index.js.map +1 -1
  62. package/dist/index-amkHKVGs.d.ts +1054 -0
  63. package/dist/index.d.ts +5 -5
  64. package/dist/index.js +328 -13
  65. package/dist/index.js.map +1 -1
  66. package/dist/schemas/index.js +67 -1
  67. package/dist/schemas/index.js.map +1 -1
  68. package/dist/{tool-approval-bridge-DnGaRES4.d.ts → tool-approval-bridge-Cz7qQUpw.d.ts} +1 -1
  69. package/dist/{tool-reply-guidance-C3qrT1In.d.ts → tool-reply-guidance-CJko9liH.d.ts} +5 -2
  70. package/dist/tool-result-ui-meta-KT0VafEO.d.ts +52 -0
  71. package/dist/trigger/index.d.ts +1 -1
  72. package/dist/trigger/index.js +118 -2
  73. package/dist/trigger/index.js.map +1 -1
  74. package/dist/{trigger--qTIK0s6.d.ts → trigger-C1ooSegc.d.ts} +2 -2
  75. package/dist/workflow/index.d.ts +1 -1
  76. package/dist/workflow/index.js +118 -2
  77. package/dist/workflow/index.js.map +1 -1
  78. package/package.json +21 -4
  79. package/dist/index-Blq0XoAr.d.ts +0 -204
  80. package/dist/tool-ui-hint-CMpug5sC.d.ts +0 -13
@@ -1,6 +1,6 @@
1
1
  // src/eve/tools/admin/manage-groups.ts
2
2
  import { defineTool } from "eve/tools";
3
- import { z as z5 } from "zod";
3
+ import { z as z6 } from "zod";
4
4
 
5
5
  // src/http.ts
6
6
  var RobotRockError = class extends Error {
@@ -493,6 +493,40 @@ var agentChatLinkTaskBodySchema = z.object({
493
493
  publicTaskId: z.string().min(1),
494
494
  toolCallId: z.string().min(1)
495
495
  });
496
+ var AGENT_FILE_TAGS_MAX = 20;
497
+ var AGENT_FILE_TAG_MAX_LENGTH = 64;
498
+ function normalizeAgentFileTags(tags) {
499
+ if (!tags?.length) return void 0;
500
+ const seen = /* @__PURE__ */ new Set();
501
+ const out = [];
502
+ for (const raw of tags) {
503
+ const tag = raw.trim().toLowerCase().slice(0, AGENT_FILE_TAG_MAX_LENGTH);
504
+ if (!tag || seen.has(tag)) continue;
505
+ seen.add(tag);
506
+ out.push(tag);
507
+ if (out.length >= AGENT_FILE_TAGS_MAX) break;
508
+ }
509
+ return out.length > 0 ? out : void 0;
510
+ }
511
+ var agentChatUploadImageBodySchema = z.object({
512
+ mediaType: z.string().min(1),
513
+ /** Raw base64 (no data: URL prefix). */
514
+ base64: z.string().min(1),
515
+ chatId: z.string().min(1).optional(),
516
+ publicTaskId: z.string().min(1).optional(),
517
+ source: z.string().min(1).optional(),
518
+ /** Display / search name (e.g. `sunset-robot.png`). */
519
+ filename: z.string().min(1).max(255).optional(),
520
+ /** Human-readable description (e.g. generation prompt). */
521
+ description: z.string().min(1).max(2e3).optional(),
522
+ /**
523
+ * Optional labels for later grouping/filtering.
524
+ * Normalized to lowercase trimmed unique strings (max 20, 64 chars each).
525
+ */
526
+ tags: z.array(z.string().min(1).max(AGENT_FILE_TAG_MAX_LENGTH)).max(AGENT_FILE_TAGS_MAX).optional().transform((tags) => normalizeAgentFileTags(tags))
527
+ }).refine((data) => Boolean(data.chatId || data.publicTaskId), {
528
+ message: "Provide chatId and/or publicTaskId"
529
+ });
496
530
 
497
531
  // ../core/src/schemas/tool-result-display.ts
498
532
  import { z as z2 } from "zod";
@@ -521,7 +555,8 @@ var tenantRoleSchema = z3.enum(["admin", "member"]);
521
555
  var agentAdminUserSchema = z3.object({
522
556
  id: z3.string(),
523
557
  email: z3.string().email(),
524
- name: z3.string()
558
+ name: z3.string(),
559
+ profilePictureUrl: z3.string().nullable().optional()
525
560
  });
526
561
  var agentAdminMemberSchema = z3.object({
527
562
  userId: z3.string(),
@@ -606,6 +641,37 @@ var assignTasksBodySchema = z3.object({
606
641
  { message: "assignTo needs at least one user email or group slug." }
607
642
  )
608
643
  });
644
+ var agentAdminPlanLimitsSchema = z3.object({
645
+ tasksPerDay: z3.number(),
646
+ members: z3.number(),
647
+ apiKeys: z3.number(),
648
+ groups: z3.number(),
649
+ auditLogRetention: z3.number(),
650
+ rateLimitPerSecond: z3.number(),
651
+ taskRetentionDays: z3.number()
652
+ });
653
+ var agentAdminUsageSchema = z3.object({
654
+ workspace: z3.string(),
655
+ planName: z3.string(),
656
+ planType: z3.string(),
657
+ trialState: z3.enum(["none", "active", "expired"]),
658
+ daysRemaining: z3.number().nullable(),
659
+ isPaidPro: z3.boolean(),
660
+ subscriptionStatus: z3.string().nullable(),
661
+ tasksToday: z3.number(),
662
+ maxTasksPerDay: z3.number().nullable(),
663
+ tasksResetAt: z3.number(),
664
+ openTasks: z3.number(),
665
+ totalTasks: z3.number(),
666
+ seatsCurrent: z3.number(),
667
+ seatsMax: z3.number().nullable(),
668
+ groupsCurrent: z3.number(),
669
+ groupsMax: z3.number().nullable(),
670
+ apiKeysCurrent: z3.number(),
671
+ apiKeysMax: z3.number().nullable(),
672
+ rateLimitPerSecond: z3.number(),
673
+ limits: agentAdminPlanLimitsSchema
674
+ });
609
675
 
610
676
  // ../core/src/handler-retry.ts
611
677
  var HANDLER_RETRY_DELAYS_MS = [
@@ -701,7 +767,11 @@ function resolveRobotRockAuthConfig(overrides) {
701
767
  "RobotRock auth is required. Set ROBOTROCK_API_KEY, ROBOTROCK_AGENT_SERVICE_TOKEN with tenant context, or pass auth when creating the client."
702
768
  );
703
769
  }
704
- return { kind: "apiKey", apiKey };
770
+ return {
771
+ kind: "apiKey",
772
+ apiKey,
773
+ ...overrides?.actingUserId?.trim() ? { actingUserId: overrides.actingUserId.trim() } : {}
774
+ };
705
775
  }
706
776
 
707
777
  // src/eve/agent/attributes.ts
@@ -837,6 +907,9 @@ async function agentAdminFetch(config, path, init) {
837
907
  }
838
908
  function createAgentAdminApi(config) {
839
909
  return {
910
+ usage: {
911
+ get: () => agentAdminFetch(config, "/usage")
912
+ },
840
913
  members: {
841
914
  list: () => agentAdminFetch(config, "/members"),
842
915
  get: (memberRef) => agentAdminFetch(config, `/members/${encodeURIComponent(memberRef)}`),
@@ -979,6 +1052,9 @@ function requireBoundAgentAdminClient(ctx) {
979
1052
  return createBoundAgentAdminClient(ctx);
980
1053
  }
981
1054
 
1055
+ // src/eve/entity-schemas.ts
1056
+ import { z as z5 } from "zod";
1057
+
982
1058
  // src/eve/tool-ui-hint.ts
983
1059
  var TOOL_UI_HINT_FIELD = "uiHint";
984
1060
  function withUiHint(result, hint) {
@@ -988,6 +1064,215 @@ function withUiHint(result, hint) {
988
1064
  };
989
1065
  }
990
1066
 
1067
+ // src/eve/tool-result-ui-meta.ts
1068
+ var TOOL_UI_FIELD = "ui";
1069
+ var TOOL_RESULT_UI_ENTITY_ID_RE = /^[a-z][a-z0-9_]{0,63}$/;
1070
+ function withToolUi(result, ui) {
1071
+ const existing = typeof result[TOOL_UI_FIELD] === "object" && result[TOOL_UI_FIELD] !== null && !Array.isArray(result[TOOL_UI_FIELD]) ? result[TOOL_UI_FIELD] : {};
1072
+ return {
1073
+ ...result,
1074
+ [TOOL_UI_FIELD]: {
1075
+ ...existing,
1076
+ ...ui
1077
+ }
1078
+ };
1079
+ }
1080
+
1081
+ // src/eve/entity-schemas.ts
1082
+ function buildTenantGroupUrl(tenantSlug, slug) {
1083
+ return `/${tenantSlug}/team/groups/${slug}`;
1084
+ }
1085
+ var toolResultUiMetaSchema = z5.object({
1086
+ present: z5.boolean().optional(),
1087
+ entity: z5.string().regex(TOOL_RESULT_UI_ENTITY_ID_RE).optional(),
1088
+ rowsPath: z5.string().min(1).optional(),
1089
+ layout: z5.enum(["list", "chart", "table"]).optional()
1090
+ }).strict();
1091
+ var agentOnlyFields = {
1092
+ replyGuidance: z5.string().optional(),
1093
+ ui: toolResultUiMetaSchema.optional(),
1094
+ uiHint: z5.enum(["list", "chart", "table"]).optional()
1095
+ };
1096
+ function withAgentOnlyFields(shape) {
1097
+ return z5.object({
1098
+ ...shape,
1099
+ ...agentOnlyFields
1100
+ });
1101
+ }
1102
+ var productEntityRowSchema = z5.object({
1103
+ id: z5.string().min(1),
1104
+ name: z5.string().min(1),
1105
+ price: z5.number(),
1106
+ currency: z5.string().min(1),
1107
+ inStock: z5.boolean(),
1108
+ url: z5.string().min(1)
1109
+ });
1110
+ var metricPointEntityRowSchema = z5.object({
1111
+ date: z5.string().optional().describe("X-axis value when xKey is date/time"),
1112
+ category: z5.string().optional().describe("X-axis value when xKey is category"),
1113
+ label: z5.string().optional().describe("X-axis value when xKey is label")
1114
+ }).catchall(z5.union([z5.string(), z5.number()])).describe(
1115
+ "Wide chart point: x-axis field + numeric columns named by yKeys (one series per column)"
1116
+ );
1117
+ var toolChartResultSchema = withAgentOnlyFields({
1118
+ title: z5.string().min(1).optional().describe("Chart title shown above the plot"),
1119
+ description: z5.string().min(1).optional().describe("Optional short subtitle"),
1120
+ type: z5.enum(["line", "bar", "area"]).describe("TRL/shadcn chart variant (time series \u2192 line, categories \u2192 bar)"),
1121
+ xKey: z5.string().min(1).describe('Field on each series row for the x-axis, e.g. "date" or "category"'),
1122
+ yKeys: z5.array(z5.string().min(1)).min(1).describe(
1123
+ 'Numeric series column names on each row, e.g. ["NL","BE"] or ["created","handled"]'
1124
+ ),
1125
+ series: z5.array(metricPointEntityRowSchema).describe(
1126
+ "Wide-format points only \u2014 one object per x value with yKeys as numeric fields"
1127
+ )
1128
+ });
1129
+ var memberEntityRowSchema = z5.object({
1130
+ name: z5.string(),
1131
+ email: z5.string(),
1132
+ role: z5.string(),
1133
+ membershipKind: z5.string(),
1134
+ profilePictureUrl: z5.string().nullable()
1135
+ });
1136
+ var taskEntityRowSchema = z5.object({
1137
+ id: z5.string().min(1),
1138
+ name: z5.string().min(1),
1139
+ status: z5.string().min(1),
1140
+ type: z5.string().nullable(),
1141
+ description: z5.string().nullable(),
1142
+ validUntil: z5.number(),
1143
+ createdAt: z5.number(),
1144
+ url: z5.string().min(1),
1145
+ threadPriority: z5.string().nullable().optional()
1146
+ });
1147
+ var groupEntityRowSchema = z5.object({
1148
+ name: z5.string().min(1),
1149
+ slug: z5.string().min(1),
1150
+ description: z5.string().nullable(),
1151
+ memberCount: z5.number().nullable(),
1152
+ url: z5.string().min(1)
1153
+ });
1154
+ var groupDetailEntitySchema = z5.object({
1155
+ name: z5.string().min(1),
1156
+ slug: z5.string().min(1),
1157
+ description: z5.string().nullable(),
1158
+ url: z5.string().min(1),
1159
+ members: z5.array(
1160
+ z5.object({
1161
+ name: z5.string(),
1162
+ email: z5.string(),
1163
+ profilePictureUrl: z5.string().nullable()
1164
+ })
1165
+ )
1166
+ });
1167
+ var statusEntityRowSchema = z5.object({
1168
+ id: z5.string().min(1),
1169
+ name: z5.string().min(1),
1170
+ status: z5.string().min(1),
1171
+ url: z5.string().min(1),
1172
+ type: z5.string().nullable().optional(),
1173
+ description: z5.string().nullable().optional()
1174
+ });
1175
+ var agentAdminErrorResultSchema = z5.object({
1176
+ ok: z5.literal(false),
1177
+ status: z5.number().optional(),
1178
+ message: z5.string(),
1179
+ response: z5.unknown().optional()
1180
+ });
1181
+ var agentAdminMutationResultSchema = z5.object({
1182
+ ...agentOnlyFields
1183
+ }).passthrough();
1184
+ var searchProductsOutputSchema = withAgentOnlyFields({
1185
+ items: z5.array(productEntityRowSchema)
1186
+ });
1187
+ var generateRandomChartOutputSchema = toolChartResultSchema.extend({
1188
+ title: z5.string().min(1)
1189
+ });
1190
+ var generateImageOutputSchema = withAgentOnlyFields({
1191
+ prompt: z5.string().min(1),
1192
+ mediaType: z5.string().min(1),
1193
+ model: z5.string().min(1),
1194
+ storageId: z5.string().min(1),
1195
+ url: z5.string().min(1),
1196
+ /** @deprecated Legacy sessions only — prefer storageId/url. */
1197
+ base64: z5.string().min(1).optional()
1198
+ });
1199
+ var manageTeamMembersListOutputSchema = withAgentOnlyFields({
1200
+ members: z5.array(memberEntityRowSchema)
1201
+ });
1202
+ var manageTeamMembersDetailOutputSchema = withAgentOnlyFields(
1203
+ memberEntityRowSchema.shape
1204
+ );
1205
+ var manageTeamMembersOutputSchema = z5.union([
1206
+ manageTeamMembersListOutputSchema,
1207
+ manageTeamMembersDetailOutputSchema,
1208
+ agentAdminMutationResultSchema,
1209
+ agentAdminErrorResultSchema
1210
+ ]);
1211
+ var manageGroupsListOutputSchema = withAgentOnlyFields({
1212
+ groups: z5.array(groupEntityRowSchema)
1213
+ });
1214
+ var manageGroupsDetailOutputSchema = withAgentOnlyFields(
1215
+ groupDetailEntitySchema.shape
1216
+ );
1217
+ var manageGroupsSummaryOutputSchema = withAgentOnlyFields(
1218
+ groupEntityRowSchema.shape
1219
+ );
1220
+ var manageGroupsOutputSchema = z5.union([
1221
+ manageGroupsListOutputSchema,
1222
+ manageGroupsDetailOutputSchema,
1223
+ manageGroupsSummaryOutputSchema,
1224
+ agentAdminMutationResultSchema,
1225
+ agentAdminErrorResultSchema
1226
+ ]);
1227
+ var queryTasksListOutputSchema = withAgentOnlyFields({
1228
+ items: z5.array(taskEntityRowSchema),
1229
+ nextCursor: z5.string().nullable().optional()
1230
+ });
1231
+ var queryTasksDetailOutputSchema = withAgentOnlyFields({
1232
+ id: z5.string().nullable(),
1233
+ status: z5.string().nullable(),
1234
+ type: z5.string().nullable(),
1235
+ name: z5.string().nullable(),
1236
+ description: z5.string().nullable(),
1237
+ validUntil: z5.number().nullable(),
1238
+ createdAt: z5.number().nullable(),
1239
+ url: z5.string().min(1).nullable()
1240
+ });
1241
+ var queryTasksOutputSchema = z5.union([
1242
+ queryTasksListOutputSchema,
1243
+ queryTasksDetailOutputSchema,
1244
+ agentAdminErrorResultSchema
1245
+ ]);
1246
+ var assignTasksOutputSchema = z5.union([
1247
+ withAgentOnlyFields({
1248
+ results: z5.array(statusEntityRowSchema)
1249
+ }),
1250
+ agentAdminErrorResultSchema
1251
+ ]);
1252
+ var workspaceUsageEntitySchema = z5.object({
1253
+ workspace: z5.string(),
1254
+ plan: z5.string(),
1255
+ planType: z5.string(),
1256
+ trialState: z5.string(),
1257
+ daysRemaining: z5.number().nullable(),
1258
+ isPaidPro: z5.boolean(),
1259
+ subscriptionStatus: z5.string(),
1260
+ tasksToday: z5.string(),
1261
+ tasksResetAt: z5.string(),
1262
+ openTasks: z5.number(),
1263
+ totalTasks: z5.number(),
1264
+ seats: z5.string(),
1265
+ groups: z5.string(),
1266
+ apiKeys: z5.string(),
1267
+ rateLimitPerSecond: z5.number()
1268
+ });
1269
+ var getWorkspaceUsageOutputSchema = z5.union([
1270
+ withAgentOnlyFields({
1271
+ usage: workspaceUsageEntitySchema
1272
+ }),
1273
+ agentAdminErrorResultSchema
1274
+ ]);
1275
+
991
1276
  // src/eve/tool-reply-guidance.ts
992
1277
  var TOOL_REPLY_GUIDANCE_FIELD = "replyGuidance";
993
1278
  var MANAGE_GROUPS_LIST_REPLY_GUIDANCE = "Groups render as a list card in chat. Do not restate group names, slugs, or descriptions from the list. Use slug (not internal id) for get, update, delete, and membership actions. Only add context not shown.";
@@ -1002,63 +1287,85 @@ function withReplyGuidance(result, guidance) {
1002
1287
 
1003
1288
  // src/eve/tool-display-format.ts
1004
1289
  function formatToolObjectResult(data, options) {
1005
- const withGuidance = withReplyGuidance(data, options.replyGuidance);
1290
+ let result = withReplyGuidance(
1291
+ data,
1292
+ options.replyGuidance
1293
+ );
1294
+ if (options.ui) {
1295
+ result = withToolUi(result, options.ui);
1296
+ }
1006
1297
  if (options.uiHint) {
1007
- return withUiHint(withGuidance, options.uiHint);
1298
+ result = withUiHint(result, options.uiHint);
1008
1299
  }
1009
- return withGuidance;
1300
+ return result;
1010
1301
  }
1011
1302
  function formatToolListResult(listKey, items, options) {
1303
+ const ui = {
1304
+ ...options.ui,
1305
+ layout: "list",
1306
+ rowsPath: listKey,
1307
+ ...options.entity ? { entity: options.entity } : {},
1308
+ ...options.present !== void 0 ? { present: options.present } : {}
1309
+ };
1012
1310
  return withUiHint(
1013
- withReplyGuidance({ [listKey]: items }, options.replyGuidance),
1311
+ withToolUi(
1312
+ withReplyGuidance({ [listKey]: items }, options.replyGuidance),
1313
+ ui
1314
+ ),
1014
1315
  "list"
1015
1316
  );
1016
1317
  }
1017
1318
 
1018
1319
  // src/eve/tools/admin/format-groups-list.ts
1019
- function serializeGroupRow(group) {
1320
+ function serializeGroupRow(group, tenantSlug) {
1020
1321
  return {
1021
1322
  name: group.name,
1022
1323
  slug: group.slug,
1023
1324
  description: group.description,
1024
- memberCount: group.memberCount ?? null
1325
+ memberCount: group.memberCount ?? null,
1326
+ url: buildTenantGroupUrl(tenantSlug, group.slug)
1025
1327
  };
1026
1328
  }
1027
- function formatGroupsListResult(groups) {
1329
+ function formatGroupsListResult(groups, options) {
1028
1330
  return formatToolListResult(
1029
1331
  "groups",
1030
- groups.map(serializeGroupRow),
1332
+ groups.map((group) => serializeGroupRow(group, options.tenantSlug)),
1031
1333
  {
1032
- replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE
1334
+ replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE,
1335
+ entity: "group"
1033
1336
  }
1034
1337
  );
1035
1338
  }
1036
- function formatGroupDetailResult(group) {
1339
+ function formatGroupDetailResult(group, options) {
1037
1340
  return formatToolObjectResult(
1038
1341
  {
1039
1342
  name: group.name,
1040
1343
  slug: group.slug,
1041
1344
  description: group.description,
1345
+ url: buildTenantGroupUrl(options.tenantSlug, group.slug),
1042
1346
  members: group.members.map((member) => ({
1043
1347
  name: member.user.name,
1044
- email: member.user.email
1348
+ email: member.user.email,
1349
+ profilePictureUrl: member.user.profilePictureUrl ?? null
1045
1350
  }))
1046
1351
  },
1047
1352
  {
1048
- replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
1353
+ replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
1354
+ ui: { entity: "group" }
1049
1355
  }
1050
1356
  );
1051
1357
  }
1052
- function formatGroupSummaryResult(group) {
1053
- return formatToolObjectResult(serializeGroupRow(group), {
1054
- replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
1358
+ function formatGroupSummaryResult(group, options) {
1359
+ return formatToolObjectResult(serializeGroupRow(group, options.tenantSlug), {
1360
+ replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
1361
+ ui: { entity: "group" }
1055
1362
  });
1056
1363
  }
1057
1364
 
1058
1365
  // src/eve/tools/admin/manage-groups.ts
1059
1366
  var MANAGE_GROUPS_TOOL_NAME = "manage_groups";
1060
- var manageGroupsInputSchema = z5.object({
1061
- action: z5.enum([
1367
+ var manageGroupsInputSchema = z6.object({
1368
+ action: z6.enum([
1062
1369
  "list",
1063
1370
  "get",
1064
1371
  "create",
@@ -1067,18 +1374,18 @@ var manageGroupsInputSchema = z5.object({
1067
1374
  "add_member",
1068
1375
  "remove_member"
1069
1376
  ]),
1070
- groupId: z5.string().min(1).optional().describe(
1377
+ groupId: z6.string().min(1).optional().describe(
1071
1378
  "Convex group id for get, update, delete, and membership actions. Prefer slug when the group list only shows slug."
1072
1379
  ),
1073
- slug: z5.string().min(1).optional().describe(
1380
+ slug: z6.string().min(1).optional().describe(
1074
1381
  "Group slug (e.g. finance) for get, update, delete, and membership actions."
1075
1382
  ),
1076
- userId: z5.string().min(1).optional().describe(
1383
+ userId: z6.string().min(1).optional().describe(
1077
1384
  "User id for add_member and remove_member. Prefer email when the member list only shows email."
1078
1385
  ),
1079
- email: z5.string().email().optional().describe("Member email for add_member and remove_member."),
1080
- name: z5.string().min(1).optional().describe("Group name for create and update."),
1081
- description: z5.string().optional().describe("Group description for create and update.")
1386
+ email: z6.string().email().optional().describe("Member email for add_member and remove_member."),
1387
+ name: z6.string().min(1).optional().describe("Group name for create and update."),
1388
+ description: z6.string().optional().describe("Group description for create and update.")
1082
1389
  }).superRefine((input, ctx) => {
1083
1390
  const requireField = (field, message) => {
1084
1391
  if (!input[field]) {
@@ -1132,33 +1439,45 @@ function resolveMemberRef(input) {
1132
1439
  }
1133
1440
  function defineManageGroupsTool() {
1134
1441
  return defineTool({
1135
- description: "Tenant-admin tool for workspace groups: list, get, create, update, delete, and manage group membership. Requires tenant admin access. Call get_my_access in the same turn before this tool to verify admin access (the check renders as its own chat tool card). Use group slug (e.g. finance) from list results for get and membership actions \u2014 internal ids are optional. Use member email for add_member and remove_member when user ids are unknown. Results render as chat UI cards \u2014 do not restate group or member fields in your reply.",
1442
+ description: "Tenant-admin tool for workspace groups: list, get, create, update, delete, and manage group membership. Requires tenant admin access. Call get_my_access in the same turn before this tool to verify admin access (the check stays a compact success marker unless it is the only presentable result). Use group slug (e.g. finance) from list results for get and membership actions \u2014 internal ids are optional. Use member email for add_member and remove_member when user ids are unknown. Results render as chat UI cards \u2014 do not restate group or member fields in your reply.",
1136
1443
  inputSchema: manageGroupsInputSchema,
1444
+ outputSchema: manageGroupsOutputSchema,
1137
1445
  async execute(input, ctx) {
1446
+ const caller = requireAdminCaller(ctx);
1138
1447
  const api = requireBoundAgentAdminClient(ctx);
1448
+ const tenantSlug = caller.tenantSlug;
1139
1449
  try {
1140
1450
  switch (input.action) {
1141
1451
  case "list": {
1142
1452
  const result = await api.groups.list();
1143
- return formatGroupsListResult(result.groups);
1453
+ return formatGroupsListResult(result.groups, {
1454
+ tenantSlug
1455
+ });
1144
1456
  }
1145
1457
  case "get": {
1146
1458
  const result = await api.groups.get(resolveGroupRef(input));
1147
- return formatGroupDetailResult(result.group);
1459
+ return formatGroupDetailResult(
1460
+ result.group,
1461
+ { tenantSlug }
1462
+ );
1148
1463
  }
1149
1464
  case "create": {
1150
1465
  const result = await api.groups.create({
1151
1466
  name: input.name,
1152
1467
  description: input.description
1153
1468
  });
1154
- return formatGroupSummaryResult(result.group);
1469
+ return formatGroupSummaryResult(result.group, {
1470
+ tenantSlug
1471
+ });
1155
1472
  }
1156
1473
  case "update": {
1157
1474
  const result = await api.groups.update(resolveGroupRef(input), {
1158
1475
  name: input.name,
1159
1476
  description: input.description
1160
1477
  });
1161
- return formatGroupSummaryResult(result.group);
1478
+ return formatGroupSummaryResult(result.group, {
1479
+ tenantSlug
1480
+ });
1162
1481
  }
1163
1482
  case "delete": {
1164
1483
  const result = await api.groups.delete(resolveGroupRef(input));