robotrock 1.3.4 → 1.4.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 +565 -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 +384 -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 +322 -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 +1353 -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 +338 -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 +306 -16
  32. package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
  33. package/dist/eve/tools/admin/query-tasks.d.ts +85 -10
  34. package/dist/eve/tools/admin/query-tasks.js +351 -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 +2065 -0
  38. package/dist/eve/tools/catalog/generate-image.js.map +1 -0
  39. package/dist/eve/tools/catalog/generate-random-chart.d.ts +71 -0
  40. package/dist/eve/tools/catalog/generate-random-chart.js +372 -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 +241 -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 +90 -5
  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 +908 -115
  61. package/dist/eve/tools/index.js.map +1 -1
  62. package/dist/index-Drj0Rzf_.d.ts +905 -0
  63. package/dist/index.d.ts +5 -5
  64. package/dist/index.js +316 -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
@@ -449,6 +449,40 @@ var agentChatLinkTaskBodySchema = z.object({
449
449
  publicTaskId: z.string().min(1),
450
450
  toolCallId: z.string().min(1)
451
451
  });
452
+ var AGENT_FILE_TAGS_MAX = 20;
453
+ var AGENT_FILE_TAG_MAX_LENGTH = 64;
454
+ function normalizeAgentFileTags(tags) {
455
+ if (!tags?.length) return void 0;
456
+ const seen = /* @__PURE__ */ new Set();
457
+ const out = [];
458
+ for (const raw of tags) {
459
+ const tag = raw.trim().toLowerCase().slice(0, AGENT_FILE_TAG_MAX_LENGTH);
460
+ if (!tag || seen.has(tag)) continue;
461
+ seen.add(tag);
462
+ out.push(tag);
463
+ if (out.length >= AGENT_FILE_TAGS_MAX) break;
464
+ }
465
+ return out.length > 0 ? out : void 0;
466
+ }
467
+ var agentChatUploadImageBodySchema = z.object({
468
+ mediaType: z.string().min(1),
469
+ /** Raw base64 (no data: URL prefix). */
470
+ base64: z.string().min(1),
471
+ chatId: z.string().min(1).optional(),
472
+ publicTaskId: z.string().min(1).optional(),
473
+ source: z.string().min(1).optional(),
474
+ /** Display / search name (e.g. `sunset-robot.png`). */
475
+ filename: z.string().min(1).max(255).optional(),
476
+ /** Human-readable description (e.g. generation prompt). */
477
+ description: z.string().min(1).max(2e3).optional(),
478
+ /**
479
+ * Optional labels for later grouping/filtering.
480
+ * Normalized to lowercase trimmed unique strings (max 20, 64 chars each).
481
+ */
482
+ tags: z.array(z.string().min(1).max(AGENT_FILE_TAG_MAX_LENGTH)).max(AGENT_FILE_TAGS_MAX).optional().transform((tags) => normalizeAgentFileTags(tags))
483
+ }).refine((data) => Boolean(data.chatId || data.publicTaskId), {
484
+ message: "Provide chatId and/or publicTaskId"
485
+ });
452
486
 
453
487
  // ../core/src/schemas/tool-result-display.ts
454
488
  import { z as z2 } from "zod";
@@ -477,7 +511,8 @@ var tenantRoleSchema = z3.enum(["admin", "member"]);
477
511
  var agentAdminUserSchema = z3.object({
478
512
  id: z3.string(),
479
513
  email: z3.string().email(),
480
- name: z3.string()
514
+ name: z3.string(),
515
+ profilePictureUrl: z3.string().nullable().optional()
481
516
  });
482
517
  var agentAdminMemberSchema = z3.object({
483
518
  userId: z3.string(),
@@ -562,6 +597,37 @@ var assignTasksBodySchema = z3.object({
562
597
  { message: "assignTo needs at least one user email or group slug." }
563
598
  )
564
599
  });
600
+ var agentAdminPlanLimitsSchema = z3.object({
601
+ tasksPerDay: z3.number(),
602
+ members: z3.number(),
603
+ apiKeys: z3.number(),
604
+ groups: z3.number(),
605
+ auditLogRetention: z3.number(),
606
+ rateLimitPerSecond: z3.number(),
607
+ taskRetentionDays: z3.number()
608
+ });
609
+ var agentAdminUsageSchema = z3.object({
610
+ workspace: z3.string(),
611
+ planName: z3.string(),
612
+ planType: z3.string(),
613
+ trialState: z3.enum(["none", "active", "expired"]),
614
+ daysRemaining: z3.number().nullable(),
615
+ isPaidPro: z3.boolean(),
616
+ subscriptionStatus: z3.string().nullable(),
617
+ tasksToday: z3.number(),
618
+ maxTasksPerDay: z3.number().nullable(),
619
+ tasksResetAt: z3.number(),
620
+ openTasks: z3.number(),
621
+ totalTasks: z3.number(),
622
+ seatsCurrent: z3.number(),
623
+ seatsMax: z3.number().nullable(),
624
+ groupsCurrent: z3.number(),
625
+ groupsMax: z3.number().nullable(),
626
+ apiKeysCurrent: z3.number(),
627
+ apiKeysMax: z3.number().nullable(),
628
+ rateLimitPerSecond: z3.number(),
629
+ limits: agentAdminPlanLimitsSchema
630
+ });
565
631
 
566
632
  // src/schemas/index.ts
567
633
  var handlerUrlSchema2 = z4.string().refine((url) => isAllowedHandlerUrl(url), {
@@ -865,7 +931,11 @@ function resolveRobotRockAuthConfig(overrides) {
865
931
  "RobotRock auth is required. Set ROBOTROCK_API_KEY, ROBOTROCK_AGENT_SERVICE_TOKEN with tenant context, or pass auth when creating the client."
866
932
  );
867
933
  }
868
- return { kind: "apiKey", apiKey };
934
+ return {
935
+ kind: "apiKey",
936
+ apiKey,
937
+ ...overrides?.actingUserId?.trim() ? { actingUserId: overrides.actingUserId.trim() } : {}
938
+ };
869
939
  }
870
940
 
871
941
  // src/chat-correlation.ts
@@ -1070,6 +1140,51 @@ function createChatsApi(config) {
1070
1140
  data
1071
1141
  );
1072
1142
  }
1143
+ },
1144
+ async uploadImage(input) {
1145
+ const validation = agentChatUploadImageBodySchema.safeParse(input);
1146
+ if (!validation.success) {
1147
+ throw new RobotRockError(
1148
+ `Invalid image upload: ${validation.error.issues[0]?.message}`,
1149
+ 400,
1150
+ validation.error.issues
1151
+ );
1152
+ }
1153
+ const response = await fetch(`${config.baseUrl}/agent-chats/images`, {
1154
+ method: "POST",
1155
+ headers: headers(),
1156
+ body: JSON.stringify(validation.data)
1157
+ });
1158
+ const data = await parseResponseBody(response);
1159
+ if (!response.ok) {
1160
+ throw new RobotRockError(
1161
+ getErrorMessage(data, "Failed to upload chat image"),
1162
+ response.status,
1163
+ data
1164
+ );
1165
+ }
1166
+ const uploaded = data;
1167
+ if (typeof uploaded.storageId !== "string" || typeof uploaded.url !== "string" || typeof uploaded.mediaType !== "string") {
1168
+ throw new RobotRockError(
1169
+ "Image upload returned an invalid response",
1170
+ 500,
1171
+ data
1172
+ );
1173
+ }
1174
+ return {
1175
+ storageId: uploaded.storageId,
1176
+ url: uploaded.url,
1177
+ mediaType: uploaded.mediaType,
1178
+ ...typeof uploaded.chatId === "string" ? { chatId: uploaded.chatId } : {},
1179
+ ...typeof uploaded.publicTaskId === "string" ? { publicTaskId: uploaded.publicTaskId } : {},
1180
+ ...typeof uploaded.filename === "string" ? { filename: uploaded.filename } : {},
1181
+ ...typeof uploaded.description === "string" ? { description: uploaded.description } : {},
1182
+ ...Array.isArray(uploaded.tags) ? {
1183
+ tags: uploaded.tags.filter(
1184
+ (tag) => typeof tag === "string"
1185
+ )
1186
+ } : {}
1187
+ };
1073
1188
  }
1074
1189
  };
1075
1190
  }
@@ -1139,6 +1254,7 @@ var RobotRock = class {
1139
1254
  }
1140
1255
  this.auth = resolveRobotRockAuthConfig({
1141
1256
  ...apiKey ? { apiKey } : {},
1257
+ ...config.actingUserId ? { actingUserId: config.actingUserId } : {},
1142
1258
  ...agentService ? { agentService } : {}
1143
1259
  });
1144
1260
  this.chatCorrelation = config.chatCorrelation;
@@ -1543,6 +1659,7 @@ function tryCreateBoundRobotRockClient(ctx) {
1543
1659
  if (apiKey) {
1544
1660
  return createClient({
1545
1661
  apiKey,
1662
+ ...caller?.userId ? { actingUserId: caller.userId } : {},
1546
1663
  baseUrl: process.env.ROBOTROCK_BASE_URL?.trim(),
1547
1664
  chatCorrelation
1548
1665
  });
@@ -1719,12 +1836,29 @@ function withUiHint(result, hint) {
1719
1836
  };
1720
1837
  }
1721
1838
 
1839
+ // src/eve/tool-result-ui-meta.ts
1840
+ var TOOL_UI_FIELD = "ui";
1841
+ var TOOL_RESULT_UI_ENTITY_ID_RE = /^[a-z][a-z0-9_]{0,63}$/;
1842
+ function withToolUi(result, ui) {
1843
+ const existing = typeof result[TOOL_UI_FIELD] === "object" && result[TOOL_UI_FIELD] !== null && !Array.isArray(result[TOOL_UI_FIELD]) ? result[TOOL_UI_FIELD] : {};
1844
+ return {
1845
+ ...result,
1846
+ [TOOL_UI_FIELD]: {
1847
+ ...existing,
1848
+ ...ui
1849
+ }
1850
+ };
1851
+ }
1852
+
1722
1853
  // src/eve/tool-reply-guidance.ts
1723
1854
  var TOOL_REPLY_GUIDANCE_FIELD = "replyGuidance";
1724
1855
  var WHOAMI_REPLY_GUIDANCE = "The dashboard shows a profile card with name, email, workspace, role, and groups. Do not restate those in your reply. Only add context not in the card (e.g. permissions, refund approval rules, missing group membership).";
1725
- var MY_ACCESS_REPLY_GUIDANCE = "Access details may render in chat UI. Do not restate role, groups, or admin capabilities if already visible. Only explain what the user can or cannot do for their question (e.g. finance group required for refunds \u2265 $10,000). When access.tenantAdmin is false and the user needs manageTeam, manageGroups, or query-tasks capabilities, explain briefly then call ask_question to offer sending an admin request to tenant admins \u2014 do not tell them to find an admin manually without offering delegation first.";
1856
+ var MY_ACCESS_REPLY_GUIDANCE = "Access details may render in chat UI. Do not restate role, groups, or admin capabilities if already visible. Only explain what the user can or cannot do for their question (e.g. finance group required for refunds \u2265 $10,000). When access.tenantAdmin is false and the user needs manageTeam, manageGroups, query-tasks, or workspace-usage capabilities, explain briefly then call ask_question to offer sending an admin request to tenant admins \u2014 do not tell them to find an admin manually without offering delegation first.";
1857
+ var GET_WORKSPACE_USAGE_REPLY_GUIDANCE = "Workspace plan and usage render as a card in chat. Do not restate plan name, task counts, seats, groups, API keys, or rate limits from the card. Only add context not shown (e.g. upgrade options, that LLM token/cost meters are not tracked, or next steps). Never invent token or dollar spend numbers.";
1726
1858
  var CREATE_INBOX_TASK_REPLY_GUIDANCE = "A task card shows title, assignee, and inbox status in chat. Do not restate task ID, assignee, or delegation details from the card. Only mention next steps or answer the user's question.";
1727
1859
  var SEARCH_PRODUCTS_REPLY_GUIDANCE = "Product results render as a list card in chat. Do not restate product names, prices, or SKUs. Only add context not in the list (e.g. no matches, recommendations).";
1860
+ var GENERATE_RANDOM_CHART_REPLY_GUIDANCE = "Chart metrics render as a chart card in chat. Do not restate series values, dates, or categories from the chart. Only add brief context (e.g. that this is demo data).";
1861
+ var GENERATE_IMAGE_REPLY_GUIDANCE = "The generated image renders in chat UI. Do not describe the image pixels or restate the prompt. Only add a short acknowledgement or next-step question if useful.";
1728
1862
  var MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE = "Team members render as a list card in chat. Do not restate names, emails, or roles from the list. Only add context not shown (e.g. duplicates, next admin actions).";
1729
1863
  var MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE = "Team member details render in chat UI. Do not restate name, email, or role from the card. Only add next steps or policy context.";
1730
1864
  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.";
@@ -1835,15 +1969,31 @@ import { z as z7 } from "zod";
1835
1969
 
1836
1970
  // src/eve/tool-display-format.ts
1837
1971
  function formatToolObjectResult(data, options) {
1838
- const withGuidance = withReplyGuidance(data, options.replyGuidance);
1972
+ let result = withReplyGuidance(
1973
+ data,
1974
+ options.replyGuidance
1975
+ );
1976
+ if (options.ui) {
1977
+ result = withToolUi(result, options.ui);
1978
+ }
1839
1979
  if (options.uiHint) {
1840
- return withUiHint(withGuidance, options.uiHint);
1980
+ result = withUiHint(result, options.uiHint);
1841
1981
  }
1842
- return withGuidance;
1982
+ return result;
1843
1983
  }
1844
1984
  function formatToolListResult(listKey, items, options) {
1985
+ const ui = {
1986
+ ...options.ui,
1987
+ layout: "list",
1988
+ rowsPath: listKey,
1989
+ ...options.entity ? { entity: options.entity } : {},
1990
+ ...options.present !== void 0 ? { present: options.present } : {}
1991
+ };
1845
1992
  return withUiHint(
1846
- withReplyGuidance({ [listKey]: items }, options.replyGuidance),
1993
+ withToolUi(
1994
+ withReplyGuidance({ [listKey]: items }, options.replyGuidance),
1995
+ ui
1996
+ ),
1847
1997
  "list"
1848
1998
  );
1849
1999
  }
@@ -1865,7 +2015,8 @@ function formatMyAccessResult(input) {
1865
2015
  }
1866
2016
  },
1867
2017
  {
1868
- replyGuidance: MY_ACCESS_REPLY_GUIDANCE
2018
+ replyGuidance: MY_ACCESS_REPLY_GUIDANCE,
2019
+ ui: { entity: "access" }
1869
2020
  }
1870
2021
  );
1871
2022
  }
@@ -1883,7 +2034,7 @@ function tenantCapabilities(isAdmin) {
1883
2034
  }
1884
2035
  function defineMyAccessTool() {
1885
2036
  return defineTool2({
1886
- description: "Check the authenticated user's tenant role, group memberships, and admin capabilities in RobotRock. Always call this before tenant-admin tools (manage_team_members, manage_groups, query_tasks) in the same turn \u2014 including read-only requests like listing users. Results render as a visible access tool card in chat like other tools; do not restate role, groups, or capabilities in your reply.",
2037
+ description: "Check the authenticated user's tenant role, group memberships, and admin capabilities in RobotRock. Always call this before tenant-admin tools (manage_team_members, manage_groups, query_tasks, get_workspace_usage) in the same turn \u2014 including read-only requests like listing users or usage. Results render as a visible access tool card in chat like other tools; do not restate role, groups, or capabilities in your reply.",
1887
2038
  inputSchema: myAccessInputSchema,
1888
2039
  async execute(_input, ctx) {
1889
2040
  const caller = tryResolveTenantCaller(ctx);
@@ -1951,10 +2102,207 @@ var whoamiTool = defineWhoamiTool();
1951
2102
 
1952
2103
  // src/eve/tools/catalog/search-products.ts
1953
2104
  import { defineTool as defineTool4 } from "eve/tools";
2105
+ import { z as z10 } from "zod";
2106
+
2107
+ // src/eve/entity-schemas.ts
1954
2108
  import { z as z9 } from "zod";
2109
+ function buildTenantTaskUrl(tenantSlug, task) {
2110
+ const q = new URLSearchParams();
2111
+ if (task.app && task.app !== "default") {
2112
+ q.set("app", task.app);
2113
+ }
2114
+ if (task.type?.trim()) {
2115
+ q.set("type", task.type.trim());
2116
+ }
2117
+ q.set("selected", task.id);
2118
+ return `/${tenantSlug}/inbox?${q.toString()}`;
2119
+ }
2120
+ function buildTenantGroupUrl(tenantSlug, slug) {
2121
+ return `/${tenantSlug}/team/groups/${slug}`;
2122
+ }
2123
+ var toolResultUiMetaSchema = z9.object({
2124
+ present: z9.boolean().optional(),
2125
+ entity: z9.string().regex(TOOL_RESULT_UI_ENTITY_ID_RE).optional(),
2126
+ rowsPath: z9.string().min(1).optional(),
2127
+ layout: z9.enum(["list", "chart", "table"]).optional()
2128
+ }).strict();
2129
+ var agentOnlyFields = {
2130
+ replyGuidance: z9.string().optional(),
2131
+ ui: toolResultUiMetaSchema.optional(),
2132
+ uiHint: z9.enum(["list", "chart", "table"]).optional()
2133
+ };
2134
+ function withAgentOnlyFields(shape) {
2135
+ return z9.object({
2136
+ ...shape,
2137
+ ...agentOnlyFields
2138
+ });
2139
+ }
2140
+ var productEntityRowSchema = z9.object({
2141
+ id: z9.string().min(1),
2142
+ name: z9.string().min(1),
2143
+ price: z9.number(),
2144
+ currency: z9.string().min(1),
2145
+ inStock: z9.boolean(),
2146
+ url: z9.string().min(1)
2147
+ });
2148
+ var metricPointEntityRowSchema = z9.object({
2149
+ date: z9.string().optional(),
2150
+ category: z9.string().optional(),
2151
+ label: z9.string().optional()
2152
+ }).catchall(z9.union([z9.string(), z9.number()]));
2153
+ var memberEntityRowSchema = z9.object({
2154
+ name: z9.string(),
2155
+ email: z9.string(),
2156
+ role: z9.string(),
2157
+ membershipKind: z9.string(),
2158
+ profilePictureUrl: z9.string().nullable()
2159
+ });
2160
+ var taskEntityRowSchema = z9.object({
2161
+ id: z9.string().min(1),
2162
+ name: z9.string().min(1),
2163
+ status: z9.string().min(1),
2164
+ type: z9.string().nullable(),
2165
+ description: z9.string().nullable(),
2166
+ validUntil: z9.number(),
2167
+ createdAt: z9.number(),
2168
+ url: z9.string().min(1),
2169
+ threadPriority: z9.string().nullable().optional()
2170
+ });
2171
+ var groupEntityRowSchema = z9.object({
2172
+ name: z9.string().min(1),
2173
+ slug: z9.string().min(1),
2174
+ description: z9.string().nullable(),
2175
+ memberCount: z9.number().nullable(),
2176
+ url: z9.string().min(1)
2177
+ });
2178
+ var groupDetailEntitySchema = z9.object({
2179
+ name: z9.string().min(1),
2180
+ slug: z9.string().min(1),
2181
+ description: z9.string().nullable(),
2182
+ url: z9.string().min(1),
2183
+ members: z9.array(
2184
+ z9.object({
2185
+ name: z9.string(),
2186
+ email: z9.string(),
2187
+ profilePictureUrl: z9.string().nullable()
2188
+ })
2189
+ )
2190
+ });
2191
+ var statusEntityRowSchema = z9.object({
2192
+ id: z9.string().min(1),
2193
+ name: z9.string().min(1),
2194
+ status: z9.string().min(1),
2195
+ url: z9.string().min(1),
2196
+ type: z9.string().nullable().optional(),
2197
+ description: z9.string().nullable().optional()
2198
+ });
2199
+ var agentAdminErrorResultSchema = z9.object({
2200
+ ok: z9.literal(false),
2201
+ status: z9.number().optional(),
2202
+ message: z9.string(),
2203
+ response: z9.unknown().optional()
2204
+ });
2205
+ var agentAdminMutationResultSchema = z9.object({
2206
+ ...agentOnlyFields
2207
+ }).passthrough();
2208
+ var searchProductsOutputSchema = withAgentOnlyFields({
2209
+ items: z9.array(productEntityRowSchema)
2210
+ });
2211
+ var generateRandomChartOutputSchema = withAgentOnlyFields({
2212
+ title: z9.string().min(1),
2213
+ axis: z9.enum(["time", "category"]),
2214
+ series: z9.array(metricPointEntityRowSchema)
2215
+ });
2216
+ var generateImageOutputSchema = withAgentOnlyFields({
2217
+ prompt: z9.string().min(1),
2218
+ mediaType: z9.string().min(1),
2219
+ model: z9.string().min(1),
2220
+ storageId: z9.string().min(1),
2221
+ url: z9.string().min(1),
2222
+ /** @deprecated Legacy sessions only — prefer storageId/url. */
2223
+ base64: z9.string().min(1).optional()
2224
+ });
2225
+ var manageTeamMembersListOutputSchema = withAgentOnlyFields({
2226
+ members: z9.array(memberEntityRowSchema)
2227
+ });
2228
+ var manageTeamMembersDetailOutputSchema = withAgentOnlyFields(
2229
+ memberEntityRowSchema.shape
2230
+ );
2231
+ var manageTeamMembersOutputSchema = z9.union([
2232
+ manageTeamMembersListOutputSchema,
2233
+ manageTeamMembersDetailOutputSchema,
2234
+ agentAdminMutationResultSchema,
2235
+ agentAdminErrorResultSchema
2236
+ ]);
2237
+ var manageGroupsListOutputSchema = withAgentOnlyFields({
2238
+ groups: z9.array(groupEntityRowSchema)
2239
+ });
2240
+ var manageGroupsDetailOutputSchema = withAgentOnlyFields(
2241
+ groupDetailEntitySchema.shape
2242
+ );
2243
+ var manageGroupsSummaryOutputSchema = withAgentOnlyFields(
2244
+ groupEntityRowSchema.shape
2245
+ );
2246
+ var manageGroupsOutputSchema = z9.union([
2247
+ manageGroupsListOutputSchema,
2248
+ manageGroupsDetailOutputSchema,
2249
+ manageGroupsSummaryOutputSchema,
2250
+ agentAdminMutationResultSchema,
2251
+ agentAdminErrorResultSchema
2252
+ ]);
2253
+ var queryTasksListOutputSchema = withAgentOnlyFields({
2254
+ items: z9.array(taskEntityRowSchema),
2255
+ nextCursor: z9.string().nullable().optional()
2256
+ });
2257
+ var queryTasksDetailOutputSchema = withAgentOnlyFields({
2258
+ id: z9.string().nullable(),
2259
+ status: z9.string().nullable(),
2260
+ type: z9.string().nullable(),
2261
+ name: z9.string().nullable(),
2262
+ description: z9.string().nullable(),
2263
+ validUntil: z9.number().nullable(),
2264
+ createdAt: z9.number().nullable(),
2265
+ url: z9.string().min(1).nullable()
2266
+ });
2267
+ var queryTasksOutputSchema = z9.union([
2268
+ queryTasksListOutputSchema,
2269
+ queryTasksDetailOutputSchema,
2270
+ agentAdminErrorResultSchema
2271
+ ]);
2272
+ var assignTasksOutputSchema = z9.union([
2273
+ withAgentOnlyFields({
2274
+ results: z9.array(statusEntityRowSchema)
2275
+ }),
2276
+ agentAdminErrorResultSchema
2277
+ ]);
2278
+ var workspaceUsageEntitySchema = z9.object({
2279
+ workspace: z9.string(),
2280
+ plan: z9.string(),
2281
+ planType: z9.string(),
2282
+ trialState: z9.string(),
2283
+ daysRemaining: z9.number().nullable(),
2284
+ isPaidPro: z9.boolean(),
2285
+ subscriptionStatus: z9.string(),
2286
+ tasksToday: z9.string(),
2287
+ tasksResetAt: z9.string(),
2288
+ openTasks: z9.number(),
2289
+ totalTasks: z9.number(),
2290
+ seats: z9.string(),
2291
+ groups: z9.string(),
2292
+ apiKeys: z9.string(),
2293
+ rateLimitPerSecond: z9.number()
2294
+ });
2295
+ var getWorkspaceUsageOutputSchema = z9.union([
2296
+ withAgentOnlyFields({
2297
+ usage: workspaceUsageEntitySchema
2298
+ }),
2299
+ agentAdminErrorResultSchema
2300
+ ]);
2301
+
2302
+ // src/eve/tools/catalog/search-products.ts
1955
2303
  var SEARCH_PRODUCTS_TOOL_NAME = "search_products";
1956
- var searchProductsInputSchema = z9.object({
1957
- query: z9.string().min(1).describe("Product name or SKU to search for.")
2304
+ var searchProductsInputSchema = z10.object({
2305
+ query: z10.string().min(1).describe("Product name or SKU to search for.")
1958
2306
  });
1959
2307
  var DEMO_PRODUCTS = [
1960
2308
  {
@@ -1962,38 +2310,348 @@ var DEMO_PRODUCTS = [
1962
2310
  name: "Wireless Keyboard",
1963
2311
  price: 79.99,
1964
2312
  currency: "USD",
1965
- inStock: true
2313
+ inStock: true,
2314
+ url: "https://shop.example.com/products/sku-1001"
1966
2315
  },
1967
2316
  {
1968
2317
  id: "sku-2042",
1969
2318
  name: "USB-C Hub",
1970
2319
  price: 45.99,
1971
2320
  currency: "USD",
1972
- inStock: true
2321
+ inStock: true,
2322
+ url: "https://shop.example.com/products/sku-2042"
1973
2323
  },
1974
2324
  {
1975
2325
  id: "sku-3308",
1976
2326
  name: "Monitor Stand",
1977
2327
  price: 129.99,
1978
2328
  currency: "USD",
1979
- inStock: false
2329
+ inStock: false,
2330
+ url: "https://shop.example.com/products/sku-3308"
1980
2331
  }
1981
2332
  ];
1982
2333
  function defineSearchProductsTool() {
1983
2334
  return defineTool4({
1984
2335
  description: "Search the product catalog and return matching items. Results render in chat UI \u2014 do not restate product names, prices, or SKUs in your reply.",
1985
2336
  inputSchema: searchProductsInputSchema,
2337
+ outputSchema: searchProductsOutputSchema,
1986
2338
  async execute({ query }) {
1987
2339
  const normalized = query.trim().toLowerCase();
1988
2340
  const items = DEMO_PRODUCTS.filter(
1989
2341
  (product) => product.name.toLowerCase().includes(normalized) || product.id.toLowerCase().includes(normalized)
1990
2342
  );
1991
- return withReplyGuidance({ items: [...items] }, SEARCH_PRODUCTS_REPLY_GUIDANCE);
2343
+ return formatToolListResult(
2344
+ "items",
2345
+ items.map((product) => ({ ...product })),
2346
+ {
2347
+ replyGuidance: SEARCH_PRODUCTS_REPLY_GUIDANCE,
2348
+ entity: "product"
2349
+ }
2350
+ );
1992
2351
  }
1993
2352
  });
1994
2353
  }
1995
2354
  var searchProductsTool = defineSearchProductsTool();
1996
2355
 
2356
+ // src/eve/tools/catalog/generate-random-chart.ts
2357
+ import { defineTool as defineTool5 } from "eve/tools";
2358
+ import { z as z11 } from "zod";
2359
+ var GENERATE_RANDOM_CHART_TOOL_NAME = "generate_random_chart";
2360
+ var generateRandomChartInputSchema = z11.object({
2361
+ axis: z11.enum(["time", "category", "random"]).optional().describe(
2362
+ "X-axis style: time (line), category (bar), or random. Defaults to random."
2363
+ ),
2364
+ seriesCount: z11.number().int().min(1).max(3).optional().describe("Number of numeric series (1\u20133). Defaults to a random 1\u20132."),
2365
+ pointCount: z11.number().int().min(4).max(30).optional().describe("Number of data points (4\u201330). Defaults to a random 8\u201314."),
2366
+ seed: z11.number().int().optional().describe("Optional seed for reproducible random data.")
2367
+ });
2368
+ function createRng(seed) {
2369
+ let state = seed === void 0 ? (Math.floor(Math.random() * 2147483647) ^ Date.now()) >>> 0 : seed >>> 0;
2370
+ if (state === 0) {
2371
+ state = 1;
2372
+ }
2373
+ return () => {
2374
+ state ^= state << 13;
2375
+ state ^= state >>> 17;
2376
+ state ^= state << 5;
2377
+ return (state >>> 0) / 4294967296;
2378
+ };
2379
+ }
2380
+ function pick(rng, items) {
2381
+ return items[Math.floor(rng() * items.length)];
2382
+ }
2383
+ function randomInt(rng, min, max) {
2384
+ return min + Math.floor(rng() * (max - min + 1));
2385
+ }
2386
+ function roundMetric(value) {
2387
+ return Math.round(value * 10) / 10;
2388
+ }
2389
+ var TIME_TITLES = [
2390
+ "Task throughput",
2391
+ "Approvals over time",
2392
+ "Inbox volume",
2393
+ "Agent tool calls",
2394
+ "Webhook deliveries"
2395
+ ];
2396
+ var CATEGORY_TITLES = [
2397
+ "Tasks by status",
2398
+ "Approvals by team",
2399
+ "Volume by region",
2400
+ "Spend by category",
2401
+ "Tickets by priority"
2402
+ ];
2403
+ var TIME_SERIES_KEYS = [
2404
+ ["value"],
2405
+ ["created", "handled"],
2406
+ ["open", "handled", "expired"]
2407
+ ];
2408
+ var CATEGORY_SERIES_KEYS = [
2409
+ ["value"],
2410
+ ["revenue", "costs"],
2411
+ ["approved", "rejected", "pending"]
2412
+ ];
2413
+ var CATEGORIES = [
2414
+ ["North", "South", "East", "West", "Central"],
2415
+ ["Finance", "Ops", "Support", "Engineering", "Sales"],
2416
+ ["P0", "P1", "P2", "P3", "P4"],
2417
+ ["Draft", "Open", "Handled", "Expired", "Cancelled"]
2418
+ ];
2419
+ function formatDate(daysAgo) {
2420
+ const date = /* @__PURE__ */ new Date();
2421
+ date.setUTCHours(0, 0, 0, 0);
2422
+ date.setUTCDate(date.getUTCDate() - daysAgo);
2423
+ return date.toISOString().slice(0, 10);
2424
+ }
2425
+ function buildSeriesPoints(args) {
2426
+ const { rng, axis, seriesKeys, pointCount } = args;
2427
+ const baselines = seriesKeys.map(() => 20 + rng() * 80);
2428
+ if (axis === "time") {
2429
+ return Array.from({ length: pointCount }, (_, index) => {
2430
+ const point = {
2431
+ date: formatDate(pointCount - 1 - index)
2432
+ };
2433
+ for (let i = 0; i < seriesKeys.length; i++) {
2434
+ const drift = (rng() - 0.45) * 12;
2435
+ baselines[i] = Math.max(1, baselines[i] + drift);
2436
+ point[seriesKeys[i]] = roundMetric(baselines[i]);
2437
+ }
2438
+ return point;
2439
+ });
2440
+ }
2441
+ const labels = pick(rng, CATEGORIES).slice(0, pointCount);
2442
+ return labels.map((label) => {
2443
+ const point = { category: label };
2444
+ for (let i = 0; i < seriesKeys.length; i++) {
2445
+ point[seriesKeys[i]] = roundMetric(8 + rng() * 120);
2446
+ }
2447
+ return point;
2448
+ });
2449
+ }
2450
+ function buildRandomChartData(input = {}) {
2451
+ const rng = createRng(input.seed);
2452
+ const axis = input.axis === "time" || input.axis === "category" ? input.axis : pick(rng, ["time", "category"]);
2453
+ const seriesCount = input.seriesCount ?? randomInt(rng, 1, 2);
2454
+ const pointCount = input.pointCount ?? (axis === "time" ? randomInt(rng, 8, 14) : randomInt(rng, 4, 6));
2455
+ const keyPool = axis === "time" ? TIME_SERIES_KEYS : CATEGORY_SERIES_KEYS;
2456
+ const seriesKeys = keyPool.find((keys) => keys.length === seriesCount) ?? keyPool[0];
2457
+ const title = pick(rng, axis === "time" ? TIME_TITLES : CATEGORY_TITLES);
2458
+ const series = buildSeriesPoints({
2459
+ rng,
2460
+ axis,
2461
+ seriesKeys,
2462
+ pointCount
2463
+ });
2464
+ return { title, axis, series };
2465
+ }
2466
+ function defineGenerateRandomChartTool() {
2467
+ return defineTool5({
2468
+ description: "Generate random chart-ready demo metrics for testing chat chart UI. Results render as a chart card \u2014 do not restate series values in your reply.",
2469
+ inputSchema: generateRandomChartInputSchema,
2470
+ outputSchema: generateRandomChartOutputSchema,
2471
+ async execute(input) {
2472
+ const data = buildRandomChartData(input);
2473
+ return formatToolObjectResult(data, {
2474
+ replyGuidance: GENERATE_RANDOM_CHART_REPLY_GUIDANCE,
2475
+ uiHint: "chart",
2476
+ ui: {
2477
+ layout: "chart",
2478
+ rowsPath: "series",
2479
+ entity: "metric_point",
2480
+ present: true
2481
+ }
2482
+ });
2483
+ }
2484
+ });
2485
+ }
2486
+ var generateRandomChartTool = defineGenerateRandomChartTool();
2487
+
2488
+ // src/eve/tools/catalog/generate-image.ts
2489
+ import { createOpenRouter } from "@openrouter/ai-sdk-provider";
2490
+ import { createGateway, generateImage } from "ai";
2491
+ import { defineTool as defineTool6 } from "eve/tools";
2492
+ import { z as z12 } from "zod";
2493
+ var GENERATE_IMAGE_TOOL_NAME = "generate_image";
2494
+ var DEFAULT_IMAGE_MODEL = "black-forest-labs/flux.2-klein-4b";
2495
+ var DEFAULT_IMAGE_SIZE = "512";
2496
+ var DEFAULT_IMAGE_ASPECT_RATIO = "1:1";
2497
+ var generateImageInputSchema = z12.object({
2498
+ prompt: z12.string().min(1).describe("Detailed description of the image to generate")
2499
+ });
2500
+ function normalizeEnvValue(value) {
2501
+ if (!value) {
2502
+ return void 0;
2503
+ }
2504
+ return value.replace(/^["']|["']$/g, "");
2505
+ }
2506
+ function isJwtExpired(token, bufferSeconds = 60) {
2507
+ try {
2508
+ const payload = JSON.parse(
2509
+ Buffer.from(token.split(".")[1] ?? "", "base64url").toString("utf8")
2510
+ );
2511
+ return typeof payload.exp !== "number" || Date.now() / 1e3 >= payload.exp - bufferSeconds;
2512
+ } catch {
2513
+ return true;
2514
+ }
2515
+ }
2516
+ function resolveAiImageModel(modelId = normalizeEnvValue(process.env.AI_IMAGE_MODEL) ?? DEFAULT_IMAGE_MODEL) {
2517
+ const openRouterKey = normalizeEnvValue(process.env.OPENROUTER_API_KEY);
2518
+ if (openRouterKey) {
2519
+ const openrouter = createOpenRouter({ apiKey: openRouterKey });
2520
+ return {
2521
+ provider: "openrouter",
2522
+ model: openrouter.imageModel(modelId),
2523
+ modelId
2524
+ };
2525
+ }
2526
+ const gatewayKey = normalizeEnvValue(process.env.AI_GATEWAY_API_KEY);
2527
+ if (gatewayKey) {
2528
+ const gateway2 = createGateway({ apiKey: gatewayKey });
2529
+ return {
2530
+ provider: "ai-gateway-api-key",
2531
+ model: gateway2.imageModel(modelId),
2532
+ modelId
2533
+ };
2534
+ }
2535
+ const oidcToken = normalizeEnvValue(process.env.VERCEL_OIDC_TOKEN);
2536
+ if (!oidcToken) {
2537
+ throw new Error(
2538
+ `No AI provider credentials for image model "${modelId}". Set OPENROUTER_API_KEY (preferred), or AI_GATEWAY_API_KEY / VERCEL_OIDC_TOKEN.`
2539
+ );
2540
+ }
2541
+ if (isJwtExpired(oidcToken)) {
2542
+ throw new Error(
2543
+ "VERCEL_OIDC_TOKEN is expired. Set OPENROUTER_API_KEY instead, or refresh the OIDC token."
2544
+ );
2545
+ }
2546
+ process.env.VERCEL_OIDC_TOKEN = oidcToken;
2547
+ const gateway = createGateway();
2548
+ return {
2549
+ provider: "ai-gateway-oidc",
2550
+ model: gateway.imageModel(modelId),
2551
+ modelId
2552
+ };
2553
+ }
2554
+ function resolveAiImageSize() {
2555
+ return normalizeEnvValue(process.env.AI_IMAGE_SIZE) ?? DEFAULT_IMAGE_SIZE;
2556
+ }
2557
+ function resolveAiImageAspectRatio() {
2558
+ return normalizeEnvValue(process.env.AI_IMAGE_ASPECT_RATIO) ?? DEFAULT_IMAGE_ASPECT_RATIO;
2559
+ }
2560
+ function extensionForMediaType(mediaType) {
2561
+ const normalized = mediaType.toLowerCase();
2562
+ if (normalized.includes("jpeg") || normalized.includes("jpg")) return "jpg";
2563
+ if (normalized.includes("webp")) return "webp";
2564
+ if (normalized.includes("gif")) return "gif";
2565
+ return "png";
2566
+ }
2567
+ function filenameFromImagePrompt(prompt, mediaType) {
2568
+ const slug = prompt.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
2569
+ return `${slug || "generated-image"}.${extensionForMediaType(mediaType)}`;
2570
+ }
2571
+ async function generateImageBytes(input, options) {
2572
+ const { model, modelId } = resolveAiImageModel();
2573
+ const size = resolveAiImageSize();
2574
+ const aspectRatio = resolveAiImageAspectRatio();
2575
+ try {
2576
+ const { image } = await generateImage({
2577
+ model,
2578
+ prompt: input.prompt,
2579
+ aspectRatio,
2580
+ abortSignal: options?.abortSignal,
2581
+ size
2582
+ });
2583
+ if (!image.base64) {
2584
+ throw new Error(`Image model "${modelId}" returned no image data.`);
2585
+ }
2586
+ return {
2587
+ prompt: input.prompt,
2588
+ mediaType: image.mediaType || "image/png",
2589
+ model: modelId,
2590
+ base64: image.base64
2591
+ };
2592
+ } catch (error) {
2593
+ const message = error instanceof Error ? error.message : "Image generation failed.";
2594
+ throw new Error(`Image generation failed (${modelId}): ${message}`);
2595
+ }
2596
+ }
2597
+ function defineGenerateImageTool() {
2598
+ return defineTool6({
2599
+ description: "Generate an image from a text prompt using a cheap/fast image model. Use when the user asks to draw, create, or generate a picture or illustration. The image renders in chat UI \u2014 do not describe the pixels in your reply.",
2600
+ inputSchema: generateImageInputSchema,
2601
+ outputSchema: generateImageOutputSchema,
2602
+ toModelOutput(output) {
2603
+ return {
2604
+ type: "text",
2605
+ value: `Generated an image for: "${output.prompt}" (model: ${output.model}).`
2606
+ };
2607
+ },
2608
+ async execute(input, ctx) {
2609
+ const caller = tryResolveTenantCaller(ctx);
2610
+ const chatId = caller?.chatId?.trim();
2611
+ if (!chatId) {
2612
+ throw new Error(
2613
+ "generate_image requires a dashboard chat session (missing chatId)."
2614
+ );
2615
+ }
2616
+ const client = tryCreateBoundRobotRockClient(ctx);
2617
+ if (!client) {
2618
+ throw new Error(
2619
+ "RobotRock auth is unset. Configure ROBOTROCK_AGENT_SERVICE_TOKEN for hosted agents or ROBOTROCK_API_KEY for self-hosted deployments."
2620
+ );
2621
+ }
2622
+ const generated = await generateImageBytes(input, {
2623
+ abortSignal: ctx?.abortSignal
2624
+ });
2625
+ const uploaded = await client.chats.uploadImage({
2626
+ mediaType: generated.mediaType,
2627
+ base64: generated.base64,
2628
+ chatId,
2629
+ source: GENERATE_IMAGE_TOOL_NAME,
2630
+ filename: filenameFromImagePrompt(generated.prompt, generated.mediaType),
2631
+ description: generated.prompt,
2632
+ tags: [GENERATE_IMAGE_TOOL_NAME]
2633
+ });
2634
+ return formatToolObjectResult(
2635
+ {
2636
+ prompt: generated.prompt,
2637
+ mediaType: uploaded.mediaType || generated.mediaType,
2638
+ model: generated.model,
2639
+ storageId: uploaded.storageId,
2640
+ url: uploaded.url
2641
+ },
2642
+ {
2643
+ replyGuidance: GENERATE_IMAGE_REPLY_GUIDANCE,
2644
+ ui: {
2645
+ present: true,
2646
+ entity: "generated_image"
2647
+ }
2648
+ }
2649
+ );
2650
+ }
2651
+ });
2652
+ }
2653
+ var generateImageTool = defineGenerateImageTool();
2654
+
1997
2655
  // src/agent-admin.ts
1998
2656
  async function agentAdminFetch(config, path, init) {
1999
2657
  const baseUrl = (config.baseUrl?.trim() || getRobotRockApiBaseUrl()).replace(
@@ -2022,6 +2680,9 @@ async function agentAdminFetch(config, path, init) {
2022
2680
  }
2023
2681
  function createAgentAdminApi(config) {
2024
2682
  return {
2683
+ usage: {
2684
+ get: () => agentAdminFetch(config, "/usage")
2685
+ },
2025
2686
  members: {
2026
2687
  list: () => agentAdminFetch(config, "/members"),
2027
2688
  get: (memberRef) => agentAdminFetch(config, `/members/${encodeURIComponent(memberRef)}`),
@@ -2170,7 +2831,8 @@ function serializeMemberRow(member) {
2170
2831
  name: member.user.name,
2171
2832
  email: member.user.email,
2172
2833
  role: member.role,
2173
- membershipKind: member.membershipKind
2834
+ membershipKind: member.membershipKind,
2835
+ profilePictureUrl: member.user.profilePictureUrl ?? null
2174
2836
  };
2175
2837
  }
2176
2838
  function formatTeamMembersListResult(members) {
@@ -2178,29 +2840,31 @@ function formatTeamMembersListResult(members) {
2178
2840
  "members",
2179
2841
  members.map(serializeMemberRow),
2180
2842
  {
2181
- replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE
2843
+ replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE,
2844
+ entity: "member"
2182
2845
  }
2183
2846
  );
2184
2847
  }
2185
2848
  function formatTeamMemberDetailResult(member) {
2186
2849
  return formatToolObjectResult(serializeMemberRow(member), {
2187
- replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE
2850
+ replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE,
2851
+ ui: { entity: "member" }
2188
2852
  });
2189
2853
  }
2190
2854
 
2191
2855
  // src/eve/tools/admin/manage-team-members.ts
2192
- import { defineTool as defineTool5 } from "eve/tools";
2193
- import { z as z10 } from "zod";
2856
+ import { defineTool as defineTool7 } from "eve/tools";
2857
+ import { z as z13 } from "zod";
2194
2858
  var MANAGE_TEAM_MEMBERS_TOOL_NAME = "manage_team_members";
2195
- var manageTeamMembersInputSchema = z10.object({
2196
- action: z10.enum(["list", "get", "invite", "update_role", "remove"]),
2197
- userId: z10.string().min(1).optional().describe(
2859
+ var manageTeamMembersInputSchema = z13.object({
2860
+ action: z13.enum(["list", "get", "invite", "update_role", "remove"]),
2861
+ userId: z13.string().min(1).optional().describe(
2198
2862
  "Convex users table id for get, update_role, and remove. Prefer email when the member list only shows email."
2199
2863
  ),
2200
- email: z10.string().email().optional().describe(
2864
+ email: z13.string().email().optional().describe(
2201
2865
  "Member email for get, update_role, and remove; invitee email for invite."
2202
2866
  ),
2203
- role: z10.enum(["admin", "member"]).optional().describe("Role for invite and update_role.")
2867
+ role: z13.enum(["admin", "member"]).optional().describe("Role for invite and update_role.")
2204
2868
  }).superRefine((input, ctx) => {
2205
2869
  const requireField = (field, message) => {
2206
2870
  if (!input[field]) {
@@ -2241,9 +2905,10 @@ function formatMemberMutationResult(payload) {
2241
2905
  });
2242
2906
  }
2243
2907
  function defineManageTeamMembersTool() {
2244
- return defineTool5({
2245
- description: "Tenant-admin tool for workspace team members: list, get, invite, change role, or remove. 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 member email from list results for get, update_role, and remove \u2014 internal ids are optional. Results render as chat UI cards \u2014 do not restate member names, emails, or roles in your reply.",
2908
+ return defineTool7({
2909
+ description: "Tenant-admin tool for workspace team members: list, get, invite, change role, or remove. 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 member email from list results for get, update_role, and remove \u2014 internal ids are optional. Results render as chat UI cards \u2014 do not restate member names, emails, or roles in your reply.",
2246
2910
  inputSchema: manageTeamMembersInputSchema,
2911
+ outputSchema: manageTeamMembersOutputSchema,
2247
2912
  async execute(input, ctx) {
2248
2913
  const api = requireBoundAgentAdminClient(ctx);
2249
2914
  try {
@@ -2306,53 +2971,59 @@ function defineManageTeamMembersTool() {
2306
2971
  var manageTeamMembersTool = defineManageTeamMembersTool();
2307
2972
 
2308
2973
  // src/eve/tools/admin/manage-groups.ts
2309
- import { defineTool as defineTool6 } from "eve/tools";
2310
- import { z as z11 } from "zod";
2974
+ import { defineTool as defineTool8 } from "eve/tools";
2975
+ import { z as z14 } from "zod";
2311
2976
 
2312
2977
  // src/eve/tools/admin/format-groups-list.ts
2313
- function serializeGroupRow(group) {
2978
+ function serializeGroupRow(group, tenantSlug) {
2314
2979
  return {
2315
2980
  name: group.name,
2316
2981
  slug: group.slug,
2317
2982
  description: group.description,
2318
- memberCount: group.memberCount ?? null
2983
+ memberCount: group.memberCount ?? null,
2984
+ url: buildTenantGroupUrl(tenantSlug, group.slug)
2319
2985
  };
2320
2986
  }
2321
- function formatGroupsListResult(groups) {
2987
+ function formatGroupsListResult(groups, options) {
2322
2988
  return formatToolListResult(
2323
2989
  "groups",
2324
- groups.map(serializeGroupRow),
2990
+ groups.map((group) => serializeGroupRow(group, options.tenantSlug)),
2325
2991
  {
2326
- replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE
2992
+ replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE,
2993
+ entity: "group"
2327
2994
  }
2328
2995
  );
2329
2996
  }
2330
- function formatGroupDetailResult(group) {
2997
+ function formatGroupDetailResult(group, options) {
2331
2998
  return formatToolObjectResult(
2332
2999
  {
2333
3000
  name: group.name,
2334
3001
  slug: group.slug,
2335
3002
  description: group.description,
3003
+ url: buildTenantGroupUrl(options.tenantSlug, group.slug),
2336
3004
  members: group.members.map((member) => ({
2337
3005
  name: member.user.name,
2338
- email: member.user.email
3006
+ email: member.user.email,
3007
+ profilePictureUrl: member.user.profilePictureUrl ?? null
2339
3008
  }))
2340
3009
  },
2341
3010
  {
2342
- replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
3011
+ replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
3012
+ ui: { entity: "group" }
2343
3013
  }
2344
3014
  );
2345
3015
  }
2346
- function formatGroupSummaryResult(group) {
2347
- return formatToolObjectResult(serializeGroupRow(group), {
2348
- replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
3016
+ function formatGroupSummaryResult(group, options) {
3017
+ return formatToolObjectResult(serializeGroupRow(group, options.tenantSlug), {
3018
+ replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
3019
+ ui: { entity: "group" }
2349
3020
  });
2350
3021
  }
2351
3022
 
2352
3023
  // src/eve/tools/admin/manage-groups.ts
2353
3024
  var MANAGE_GROUPS_TOOL_NAME = "manage_groups";
2354
- var manageGroupsInputSchema = z11.object({
2355
- action: z11.enum([
3025
+ var manageGroupsInputSchema = z14.object({
3026
+ action: z14.enum([
2356
3027
  "list",
2357
3028
  "get",
2358
3029
  "create",
@@ -2361,18 +3032,18 @@ var manageGroupsInputSchema = z11.object({
2361
3032
  "add_member",
2362
3033
  "remove_member"
2363
3034
  ]),
2364
- groupId: z11.string().min(1).optional().describe(
3035
+ groupId: z14.string().min(1).optional().describe(
2365
3036
  "Convex group id for get, update, delete, and membership actions. Prefer slug when the group list only shows slug."
2366
3037
  ),
2367
- slug: z11.string().min(1).optional().describe(
3038
+ slug: z14.string().min(1).optional().describe(
2368
3039
  "Group slug (e.g. finance) for get, update, delete, and membership actions."
2369
3040
  ),
2370
- userId: z11.string().min(1).optional().describe(
3041
+ userId: z14.string().min(1).optional().describe(
2371
3042
  "User id for add_member and remove_member. Prefer email when the member list only shows email."
2372
3043
  ),
2373
- email: z11.string().email().optional().describe("Member email for add_member and remove_member."),
2374
- name: z11.string().min(1).optional().describe("Group name for create and update."),
2375
- description: z11.string().optional().describe("Group description for create and update.")
3044
+ email: z14.string().email().optional().describe("Member email for add_member and remove_member."),
3045
+ name: z14.string().min(1).optional().describe("Group name for create and update."),
3046
+ description: z14.string().optional().describe("Group description for create and update.")
2376
3047
  }).superRefine((input, ctx) => {
2377
3048
  const requireField = (field, message) => {
2378
3049
  if (!input[field]) {
@@ -2425,34 +3096,46 @@ function resolveMemberRef2(input) {
2425
3096
  return input.userId ?? input.email;
2426
3097
  }
2427
3098
  function defineManageGroupsTool() {
2428
- return defineTool6({
2429
- 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.",
3099
+ return defineTool8({
3100
+ 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.",
2430
3101
  inputSchema: manageGroupsInputSchema,
3102
+ outputSchema: manageGroupsOutputSchema,
2431
3103
  async execute(input, ctx) {
3104
+ const caller = requireAdminCaller(ctx);
2432
3105
  const api = requireBoundAgentAdminClient(ctx);
3106
+ const tenantSlug = caller.tenantSlug;
2433
3107
  try {
2434
3108
  switch (input.action) {
2435
3109
  case "list": {
2436
3110
  const result = await api.groups.list();
2437
- return formatGroupsListResult(result.groups);
3111
+ return formatGroupsListResult(result.groups, {
3112
+ tenantSlug
3113
+ });
2438
3114
  }
2439
3115
  case "get": {
2440
3116
  const result = await api.groups.get(resolveGroupRef(input));
2441
- return formatGroupDetailResult(result.group);
3117
+ return formatGroupDetailResult(
3118
+ result.group,
3119
+ { tenantSlug }
3120
+ );
2442
3121
  }
2443
3122
  case "create": {
2444
3123
  const result = await api.groups.create({
2445
3124
  name: input.name,
2446
3125
  description: input.description
2447
3126
  });
2448
- return formatGroupSummaryResult(result.group);
3127
+ return formatGroupSummaryResult(result.group, {
3128
+ tenantSlug
3129
+ });
2449
3130
  }
2450
3131
  case "update": {
2451
3132
  const result = await api.groups.update(resolveGroupRef(input), {
2452
3133
  name: input.name,
2453
3134
  description: input.description
2454
3135
  });
2455
- return formatGroupSummaryResult(result.group);
3136
+ return formatGroupSummaryResult(result.group, {
3137
+ tenantSlug
3138
+ });
2456
3139
  }
2457
3140
  case "delete": {
2458
3141
  const result = await api.groups.delete(resolveGroupRef(input));
@@ -2496,83 +3179,101 @@ function defineManageGroupsTool() {
2496
3179
  var manageGroupsTool = defineManageGroupsTool();
2497
3180
 
2498
3181
  // src/eve/tools/admin/query-tasks.ts
2499
- import { defineTool as defineTool7 } from "eve/tools";
2500
- import { z as z12 } from "zod";
3182
+ import { defineTool as defineTool9 } from "eve/tools";
3183
+ import { z as z15 } from "zod";
2501
3184
 
2502
3185
  // src/eve/tools/admin/format-tasks-list.ts
2503
3186
  function resolveTaskCardLabel(task) {
2504
3187
  return task.name?.trim() || task.description?.trim() || task.type?.trim() || task.id?.trim() || "Untitled task";
2505
3188
  }
3189
+ function serializeTaskRow(task, tenantSlug) {
3190
+ return {
3191
+ id: task.id,
3192
+ name: resolveTaskCardLabel(task),
3193
+ status: task.status,
3194
+ type: task.type,
3195
+ description: task.description,
3196
+ validUntil: task.validUntil,
3197
+ createdAt: task.createdAt,
3198
+ threadPriority: task.threadPriority,
3199
+ url: buildTenantTaskUrl(tenantSlug, {
3200
+ id: task.id,
3201
+ type: task.type
3202
+ })
3203
+ };
3204
+ }
2506
3205
  function formatTasksListResult(items, options) {
2507
3206
  const payload = {
2508
- items: items.map((task) => ({
2509
- id: task.id,
2510
- name: resolveTaskCardLabel(task),
2511
- status: task.status,
2512
- type: task.type,
2513
- description: task.description
2514
- }))
3207
+ items: items.map((task) => serializeTaskRow(task, options.tenantSlug))
2515
3208
  };
2516
- if (options?.nextCursor) {
3209
+ if (options.nextCursor) {
2517
3210
  payload.nextCursor = options.nextCursor;
2518
3211
  }
2519
3212
  return formatToolObjectResult(payload, {
2520
- replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE
3213
+ replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE,
3214
+ ui: { layout: "list", entity: "task", rowsPath: "items" }
2521
3215
  });
2522
3216
  }
2523
- function formatTaskSearchResult(items) {
2524
- return formatTasksListResult(items);
3217
+ function formatTaskSearchResult(items, options) {
3218
+ return formatTasksListResult(items, options);
2525
3219
  }
2526
- function formatTaskDetailResult(task) {
3220
+ function formatTaskDetailResult(task, options) {
3221
+ const id = typeof task.id === "string" ? task.id : null;
3222
+ const type = typeof task.type === "string" ? task.type : null;
3223
+ const url = id !== null ? buildTenantTaskUrl(options.tenantSlug, { id, type }) : null;
2527
3224
  return formatToolObjectResult(
2528
3225
  {
2529
- id: task.id ?? null,
2530
- status: task.status ?? null,
2531
- type: task.type ?? null,
2532
- name: task.name ?? null,
2533
- description: task.description ?? null,
2534
- validUntil: task.validUntil ?? null,
2535
- createdAt: task.createdAt ?? null
3226
+ id,
3227
+ status: typeof task.status === "string" ? task.status : null,
3228
+ type,
3229
+ name: typeof task.name === "string" ? task.name : null,
3230
+ description: typeof task.description === "string" ? task.description : null,
3231
+ validUntil: typeof task.validUntil === "number" ? task.validUntil : null,
3232
+ createdAt: typeof task.createdAt === "number" ? task.createdAt : null,
3233
+ url
2536
3234
  },
2537
3235
  {
2538
- replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE
3236
+ replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE,
3237
+ ui: { entity: "task" }
2539
3238
  }
2540
3239
  );
2541
3240
  }
2542
- function formatAssignTasksResult(results, _assignTo) {
2543
- return formatToolListResult(
2544
- "results",
2545
- results.map((row) => ({
3241
+ function formatAssignTasksResult(results, _assignTo, options) {
3242
+ const rows = results.map((row) => ({
3243
+ id: row.taskId,
3244
+ name: resolveTaskCardLabel({
3245
+ name: row.name,
3246
+ description: row.description,
3247
+ type: row.type,
3248
+ id: row.taskId
3249
+ }),
3250
+ type: row.type ?? null,
3251
+ description: row.description ?? null,
3252
+ status: row.success ? "reassigned" : "failed",
3253
+ url: buildTenantTaskUrl(options.tenantSlug, {
2546
3254
  id: row.taskId,
2547
- name: resolveTaskCardLabel({
2548
- name: row.name,
2549
- description: row.description,
2550
- type: row.type,
2551
- id: row.taskId
2552
- }),
2553
- type: row.type ?? null,
2554
- description: row.description ?? null,
2555
- status: row.success ? "reassigned" : "failed"
2556
- })),
2557
- {
2558
- replyGuidance: ASSIGN_TASKS_REPLY_GUIDANCE
2559
- }
2560
- );
3255
+ type: row.type
3256
+ })
3257
+ }));
3258
+ return formatToolListResult("results", rows, {
3259
+ replyGuidance: ASSIGN_TASKS_REPLY_GUIDANCE,
3260
+ entity: "status"
3261
+ });
2561
3262
  }
2562
3263
 
2563
3264
  // src/eve/tools/admin/query-tasks.ts
2564
3265
  var QUERY_TASKS_TOOL_NAME = "query_tasks";
2565
- var queryTasksInputSchema = z12.object({
2566
- action: z12.enum(["list", "get", "search"]),
2567
- statusFilter: z12.enum(["all", "open", "handled", "expired"]).optional().describe("Filter by task status for list."),
2568
- typeFilter: z12.string().optional(),
2569
- appFilter: z12.string().optional(),
2570
- sortField: z12.enum(["type", "date", "status", "validUntil"]).optional(),
2571
- sortDirection: z12.enum(["asc", "desc"]).optional(),
2572
- limit: z12.number().int().positive().max(100).optional(),
2573
- cursor: z12.string().optional(),
2574
- taskId: z12.string().min(1).optional().describe("Public task id or Convex tasks table id for get."),
2575
- query: z12.string().min(1).optional().describe("Search type, name, description, or id for search.")
3266
+ var queryTasksInputSchema = z15.object({
3267
+ action: z15.enum(["list", "get", "search"]),
3268
+ statusFilter: z15.enum(["all", "open", "handled", "expired"]).optional().describe("Filter by task status for list."),
3269
+ typeFilter: z15.string().optional(),
3270
+ appFilter: z15.string().optional(),
3271
+ sortField: z15.enum(["type", "date", "status", "validUntil"]).optional(),
3272
+ sortDirection: z15.enum(["asc", "desc"]).optional(),
3273
+ limit: z15.number().int().positive().max(100).optional(),
3274
+ cursor: z15.string().optional(),
3275
+ taskId: z15.string().min(1).optional().describe("Public task id or Convex tasks table id for get."),
3276
+ query: z15.string().min(1).optional().describe("Search type, name, description, or id for search.")
2576
3277
  }).superRefine((input, ctx) => {
2577
3278
  switch (input.action) {
2578
3279
  case "get":
@@ -2596,11 +3297,14 @@ var queryTasksInputSchema = z12.object({
2596
3297
  }
2597
3298
  });
2598
3299
  function defineQueryTasksTool() {
2599
- return defineTool7({
2600
- description: "Tenant-admin tool to list, fetch detail, or search inbox tasks in the workspace. 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). Results render as chat UI cards \u2014 do not restate task names, ids, or statuses in your reply.",
3300
+ return defineTool9({
3301
+ description: "Tenant-admin tool to list, fetch detail, or search inbox tasks in the workspace. 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). Results render as chat UI cards \u2014 do not restate task names, ids, or statuses in your reply.",
2601
3302
  inputSchema: queryTasksInputSchema,
3303
+ outputSchema: queryTasksOutputSchema,
2602
3304
  async execute(input, ctx) {
3305
+ const caller = requireAdminCaller(ctx);
2603
3306
  const api = requireBoundAgentAdminClient(ctx);
3307
+ const tenantSlug = caller.tenantSlug;
2604
3308
  try {
2605
3309
  switch (input.action) {
2606
3310
  case "list": {
@@ -2614,17 +3318,22 @@ function defineQueryTasksTool() {
2614
3318
  cursor: input.cursor
2615
3319
  });
2616
3320
  return formatTasksListResult(result.items, {
3321
+ tenantSlug,
2617
3322
  nextCursor: result.nextCursor
2618
3323
  });
2619
3324
  }
2620
3325
  case "get": {
2621
3326
  const result = await api.tasks.get(input.taskId);
2622
- return formatTaskDetailResult(result.task);
3327
+ return formatTaskDetailResult(
3328
+ result.task,
3329
+ { tenantSlug }
3330
+ );
2623
3331
  }
2624
3332
  case "search": {
2625
3333
  const result = await api.tasks.search(input.query, input.limit);
2626
3334
  return formatTaskSearchResult(
2627
- result.items
3335
+ result.items,
3336
+ { tenantSlug }
2628
3337
  );
2629
3338
  }
2630
3339
  }
@@ -2645,11 +3354,11 @@ function defineQueryTasksTool() {
2645
3354
  var queryTasksTool = defineQueryTasksTool();
2646
3355
 
2647
3356
  // src/eve/tools/admin/assign-tasks.ts
2648
- import { defineTool as defineTool8 } from "eve/tools";
2649
- import { z as z13 } from "zod";
3357
+ import { defineTool as defineTool10 } from "eve/tools";
3358
+ import { z as z16 } from "zod";
2650
3359
  var ASSIGN_TASKS_TOOL_NAME = "assign_tasks";
2651
- var assignTasksInputSchema = z13.object({
2652
- taskIds: z13.array(z13.string().min(1)).min(1).max(100).describe(
3360
+ var assignTasksInputSchema = z16.object({
3361
+ taskIds: z16.array(z16.string().min(1)).min(1).max(100).describe(
2653
3362
  "Public task ids or Convex tasks table ids to reassign. Use query_tasks search/get to resolve ids first."
2654
3363
  ),
2655
3364
  assignTo: assignToSchema.refine(
@@ -2660,17 +3369,21 @@ var assignTasksInputSchema = z13.object({
2660
3369
  )
2661
3370
  });
2662
3371
  function defineAssignTasksTool() {
2663
- return defineTool8({
3372
+ return defineTool10({
2664
3373
  description: "Reassign existing inbox tasks to users or groups. Requires access to each task (tenant admins can reassign any task; others only tasks they can see). Use query_tasks to find task ids when needed. Results render as chat UI \u2014 do not restate task ids or assignees in your reply.",
2665
3374
  inputSchema: assignTasksInputSchema,
3375
+ outputSchema: assignTasksOutputSchema,
2666
3376
  async execute(input, ctx) {
3377
+ const caller = requireTenantCaller(ctx);
2667
3378
  const api = createBoundAgentAdminClient(ctx);
2668
3379
  try {
2669
3380
  const result = await api.tasks.assign({
2670
3381
  taskIds: input.taskIds,
2671
3382
  assignTo: input.assignTo
2672
3383
  });
2673
- return formatAssignTasksResult(result.results, input.assignTo);
3384
+ return formatAssignTasksResult(result.results, input.assignTo, {
3385
+ tenantSlug: caller.tenantSlug
3386
+ });
2674
3387
  } catch (error) {
2675
3388
  if (error instanceof RobotRockError) {
2676
3389
  return {
@@ -2687,6 +3400,72 @@ function defineAssignTasksTool() {
2687
3400
  }
2688
3401
  var assignTasksTool = defineAssignTasksTool();
2689
3402
 
3403
+ // src/eve/tools/admin/get-workspace-usage.ts
3404
+ import { defineTool as defineTool11 } from "eve/tools";
3405
+ import { z as z17 } from "zod";
3406
+
3407
+ // src/eve/tools/admin/format-workspace-usage.ts
3408
+ function formatLimit(current, max) {
3409
+ return max === null ? `${current} / unlimited` : `${current} / ${max}`;
3410
+ }
3411
+ function formatWorkspaceUsageResult(usage) {
3412
+ const tasksLimit = usage.maxTasksPerDay === null ? `${usage.tasksToday} / unlimited` : `${usage.tasksToday} / ${usage.maxTasksPerDay}`;
3413
+ return formatToolObjectResult(
3414
+ {
3415
+ usage: {
3416
+ workspace: usage.workspace,
3417
+ plan: usage.planName,
3418
+ planType: usage.planType,
3419
+ trialState: usage.trialState,
3420
+ daysRemaining: usage.daysRemaining,
3421
+ isPaidPro: usage.isPaidPro,
3422
+ subscriptionStatus: usage.subscriptionStatus ?? "\u2014",
3423
+ tasksToday: tasksLimit,
3424
+ tasksResetAt: new Date(usage.tasksResetAt).toISOString(),
3425
+ openTasks: usage.openTasks,
3426
+ totalTasks: usage.totalTasks,
3427
+ seats: formatLimit(usage.seatsCurrent, usage.seatsMax),
3428
+ groups: formatLimit(usage.groupsCurrent, usage.groupsMax),
3429
+ apiKeys: formatLimit(usage.apiKeysCurrent, usage.apiKeysMax),
3430
+ rateLimitPerSecond: usage.rateLimitPerSecond
3431
+ }
3432
+ },
3433
+ {
3434
+ replyGuidance: GET_WORKSPACE_USAGE_REPLY_GUIDANCE,
3435
+ ui: { entity: "usage" }
3436
+ }
3437
+ );
3438
+ }
3439
+
3440
+ // src/eve/tools/admin/get-workspace-usage.ts
3441
+ var GET_WORKSPACE_USAGE_TOOL_NAME = "get_workspace_usage";
3442
+ var getWorkspaceUsageInputSchema = z17.object({});
3443
+ function defineGetWorkspaceUsageTool() {
3444
+ return defineTool11({
3445
+ description: "Tenant-admin tool for workspace plan, limits, and usage (tasks today, seats, groups, API keys, rate limits). Does not include LLM token counts or dollar spend \u2014 those are not tracked. Requires tenant admin access. Call get_my_access in the same turn before this tool. Results render as a chat UI card \u2014 do not restate plan or usage numbers in your reply.",
3446
+ inputSchema: getWorkspaceUsageInputSchema,
3447
+ outputSchema: getWorkspaceUsageOutputSchema,
3448
+ async execute(_input, ctx) {
3449
+ const api = requireBoundAgentAdminClient(ctx);
3450
+ try {
3451
+ const result = await api.usage.get();
3452
+ return formatWorkspaceUsageResult(result.usage);
3453
+ } catch (error) {
3454
+ if (error instanceof RobotRockError) {
3455
+ return {
3456
+ ok: false,
3457
+ status: error.statusCode,
3458
+ message: error.message,
3459
+ response: error.response
3460
+ };
3461
+ }
3462
+ throw error;
3463
+ }
3464
+ }
3465
+ });
3466
+ }
3467
+ var getWorkspaceUsageTool = defineGetWorkspaceUsageTool();
3468
+
2690
3469
  // src/eve/tools/index.ts
2691
3470
  function createRobotrockTools(options) {
2692
3471
  const tools = {};
@@ -2704,6 +3483,9 @@ function createRobotrockTools(options) {
2704
3483
  export {
2705
3484
  ASSIGN_TASKS_TOOL_NAME,
2706
3485
  CREATE_INBOX_TASK_TOOL_NAME,
3486
+ GENERATE_IMAGE_TOOL_NAME,
3487
+ GENERATE_RANDOM_CHART_TOOL_NAME,
3488
+ GET_WORKSPACE_USAGE_TOOL_NAME,
2707
3489
  MANAGE_GROUPS_TOOL_NAME,
2708
3490
  MANAGE_TEAM_MEMBERS_TOOL_NAME,
2709
3491
  MY_ACCESS_TOOL_NAME,
@@ -2712,17 +3494,28 @@ export {
2712
3494
  WHOAMI_TOOL_NAME,
2713
3495
  assignTasksInputSchema,
2714
3496
  assignTasksTool,
3497
+ buildRandomChartData,
2715
3498
  createInboxTaskInputSchema,
2716
3499
  createInboxTaskTool,
2717
3500
  createRobotrockTools,
2718
3501
  defineAssignTasksTool,
2719
3502
  defineCreateInboxTaskTool,
3503
+ defineGenerateImageTool,
3504
+ defineGenerateRandomChartTool,
3505
+ defineGetWorkspaceUsageTool,
2720
3506
  defineManageGroupsTool,
2721
3507
  defineManageTeamMembersTool,
2722
3508
  defineMyAccessTool,
2723
3509
  defineQueryTasksTool,
2724
3510
  defineSearchProductsTool,
2725
3511
  defineWhoamiTool,
3512
+ generateImageBytes,
3513
+ generateImageInputSchema,
3514
+ generateImageTool,
3515
+ generateRandomChartInputSchema,
3516
+ generateRandomChartTool,
3517
+ getWorkspaceUsageInputSchema,
3518
+ getWorkspaceUsageTool,
2726
3519
  manageGroupsTool,
2727
3520
  manageTeamMembersTool,
2728
3521
  myAccessInputSchema,