robotrock 1.3.3 → 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.
- package/README.md +32 -0
- package/dist/agent-admin.d.ts +5 -0
- package/dist/agent-admin.js +75 -2
- package/dist/agent-admin.js.map +1 -1
- package/dist/ai/index.d.ts +5 -5
- package/dist/ai/index.js +128 -4
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/trigger.d.ts +3 -3
- package/dist/ai/trigger.js +128 -4
- package/dist/ai/trigger.js.map +1 -1
- package/dist/ai/workflow.d.ts +3 -3
- package/dist/ai/workflow.js +128 -4
- package/dist/ai/workflow.js.map +1 -1
- package/dist/{client-CZ5eWH5v.d.ts → client-BxbxttFH.d.ts} +19 -1
- package/dist/eve/agent/index.d.ts +4 -3
- package/dist/eve/agent/index.js +736 -414
- package/dist/eve/agent/index.js.map +1 -1
- package/dist/eve/index.d.ts +4 -3
- package/dist/eve/index.js +437 -45
- package/dist/eve/index.js.map +1 -1
- package/dist/eve/tools/admin/assign-tasks.d.ts +40 -8
- package/dist/eve/tools/admin/assign-tasks.js +328 -66
- package/dist/eve/tools/admin/assign-tasks.js.map +1 -1
- package/dist/eve/tools/admin/get-workspace-usage.d.ts +71 -0
- package/dist/eve/tools/admin/get-workspace-usage.js +1353 -0
- package/dist/eve/tools/admin/get-workspace-usage.js.map +1 -0
- package/dist/eve/tools/admin/manage-groups.d.ts +122 -8
- package/dist/eve/tools/admin/manage-groups.js +348 -94
- package/dist/eve/tools/admin/manage-groups.js.map +1 -1
- package/dist/eve/tools/admin/manage-team-members.d.ts +86 -8
- package/dist/eve/tools/admin/manage-team-members.js +318 -72
- package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
- package/dist/eve/tools/admin/query-tasks.d.ts +82 -8
- package/dist/eve/tools/admin/query-tasks.js +360 -113
- package/dist/eve/tools/admin/query-tasks.js.map +1 -1
- package/dist/eve/tools/catalog/generate-image.d.ts +64 -0
- package/dist/eve/tools/catalog/generate-image.js +2065 -0
- package/dist/eve/tools/catalog/generate-image.js.map +1 -0
- package/dist/eve/tools/catalog/generate-random-chart.d.ts +71 -0
- package/dist/eve/tools/catalog/generate-random-chart.js +372 -0
- package/dist/eve/tools/catalog/generate-random-chart.js.map +1 -0
- package/dist/eve/tools/catalog/search-products.d.ts +36 -44
- package/dist/eve/tools/catalog/search-products.js +237 -33
- package/dist/eve/tools/catalog/search-products.js.map +1 -1
- package/dist/eve/tools/identity/index.d.ts +2 -2
- package/dist/eve/tools/identity/index.js +35 -44
- package/dist/eve/tools/identity/index.js.map +1 -1
- package/dist/eve/tools/identity/my-access.d.ts +90 -6
- package/dist/eve/tools/identity/my-access.js +35 -44
- package/dist/eve/tools/identity/my-access.js.map +1 -1
- package/dist/eve/tools/identity/whoami.d.ts +1 -1
- package/dist/eve/tools/identity/whoami.js.map +1 -1
- package/dist/eve/tools/inbox/create-task.d.ts +1 -1
- package/dist/eve/tools/inbox/create-task.js +119 -2
- package/dist/eve/tools/inbox/create-task.js.map +1 -1
- package/dist/eve/tools/inbox/index.d.ts +1 -1
- package/dist/eve/tools/inbox/index.js +119 -2
- package/dist/eve/tools/inbox/index.js.map +1 -1
- package/dist/eve/tools/index.d.ts +5 -2
- package/dist/eve/tools/index.js +932 -288
- package/dist/eve/tools/index.js.map +1 -1
- package/dist/index-Drj0Rzf_.d.ts +905 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +335 -20
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.js +67 -1
- package/dist/schemas/index.js.map +1 -1
- package/dist/{tool-approval-bridge-DnGaRES4.d.ts → tool-approval-bridge-Cz7qQUpw.d.ts} +1 -1
- package/dist/{tool-reply-guidance-C3qrT1In.d.ts → tool-reply-guidance-CJko9liH.d.ts} +5 -2
- package/dist/tool-result-ui-meta-KT0VafEO.d.ts +52 -0
- package/dist/trigger/index.d.ts +1 -1
- package/dist/trigger/index.js +118 -2
- package/dist/trigger/index.js.map +1 -1
- package/dist/{trigger--qTIK0s6.d.ts → trigger-C1ooSegc.d.ts} +2 -2
- package/dist/workflow/index.d.ts +1 -1
- package/dist/workflow/index.js +118 -2
- package/dist/workflow/index.js.map +1 -1
- package/package.json +21 -4
- package/dist/index-DePyAbTI.d.ts +0 -203
package/dist/eve/tools/index.js
CHANGED
|
@@ -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 {
|
|
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
|
});
|
|
@@ -1710,12 +1827,38 @@ async function postRobotRockLinkChatTask(ctx, input) {
|
|
|
1710
1827
|
}
|
|
1711
1828
|
}
|
|
1712
1829
|
|
|
1830
|
+
// src/eve/tool-ui-hint.ts
|
|
1831
|
+
var TOOL_UI_HINT_FIELD = "uiHint";
|
|
1832
|
+
function withUiHint(result, hint) {
|
|
1833
|
+
return {
|
|
1834
|
+
...result,
|
|
1835
|
+
[TOOL_UI_HINT_FIELD]: hint
|
|
1836
|
+
};
|
|
1837
|
+
}
|
|
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
|
+
|
|
1713
1853
|
// src/eve/tool-reply-guidance.ts
|
|
1714
1854
|
var TOOL_REPLY_GUIDANCE_FIELD = "replyGuidance";
|
|
1715
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).";
|
|
1716
|
-
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,
|
|
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.";
|
|
1717
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.";
|
|
1718
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.";
|
|
1719
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).";
|
|
1720
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.";
|
|
1721
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.";
|
|
@@ -1824,69 +1967,38 @@ var createInboxTaskTool = defineCreateInboxTaskTool();
|
|
|
1824
1967
|
import { defineTool as defineTool2 } from "eve/tools";
|
|
1825
1968
|
import { z as z7 } from "zod";
|
|
1826
1969
|
|
|
1827
|
-
// src/eve/tool-result-display.ts
|
|
1828
|
-
function toolDisplayResult(data, options) {
|
|
1829
|
-
const display = options?.widget || options?.title || options?.description ? {
|
|
1830
|
-
...options.widget ? { widget: options.widget } : {},
|
|
1831
|
-
...options.title ? { title: options.title } : {},
|
|
1832
|
-
...options.description ? { description: options.description } : {}
|
|
1833
|
-
} : void 0;
|
|
1834
|
-
return {
|
|
1835
|
-
...display ? { display } : {},
|
|
1836
|
-
data,
|
|
1837
|
-
...options?.ui ? { ui: options.ui } : {}
|
|
1838
|
-
};
|
|
1839
|
-
}
|
|
1840
|
-
|
|
1841
1970
|
// src/eve/tool-display-format.ts
|
|
1842
1971
|
function formatToolObjectResult(data, options) {
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
title: options.title,
|
|
1846
|
-
description: options.description,
|
|
1847
|
-
ui: options.ui
|
|
1848
|
-
}),
|
|
1972
|
+
let result = withReplyGuidance(
|
|
1973
|
+
data,
|
|
1849
1974
|
options.replyGuidance
|
|
1850
1975
|
);
|
|
1976
|
+
if (options.ui) {
|
|
1977
|
+
result = withToolUi(result, options.ui);
|
|
1978
|
+
}
|
|
1979
|
+
if (options.uiHint) {
|
|
1980
|
+
result = withUiHint(result, options.uiHint);
|
|
1981
|
+
}
|
|
1982
|
+
return result;
|
|
1851
1983
|
}
|
|
1852
1984
|
function formatToolListResult(listKey, items, options) {
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
}
|
|
1859
|
-
} : {
|
|
1860
|
-
"ui:widget": "table",
|
|
1861
|
-
...options.itemUi ? { items: options.itemUi } : {}
|
|
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 } : {}
|
|
1862
1991
|
};
|
|
1863
|
-
return
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
},
|
|
1870
|
-
replyGuidance: options.replyGuidance
|
|
1871
|
-
}
|
|
1992
|
+
return withUiHint(
|
|
1993
|
+
withToolUi(
|
|
1994
|
+
withReplyGuidance({ [listKey]: items }, options.replyGuidance),
|
|
1995
|
+
ui
|
|
1996
|
+
),
|
|
1997
|
+
"list"
|
|
1872
1998
|
);
|
|
1873
1999
|
}
|
|
1874
2000
|
|
|
1875
2001
|
// src/eve/tools/identity/format-my-access.ts
|
|
1876
|
-
var ACCESS_FIELD_UI = {
|
|
1877
|
-
workspace: { "ui:title": "Workspace" },
|
|
1878
|
-
role: { "ui:title": "Role" },
|
|
1879
|
-
tenantAdmin: { "ui:title": "Tenant admin", "ui:widget": "boolean" },
|
|
1880
|
-
groups: { "ui:title": "Groups" },
|
|
1881
|
-
manageSettings: { "ui:title": "Manage settings", "ui:widget": "boolean" },
|
|
1882
|
-
manageBilling: { "ui:title": "Manage billing", "ui:widget": "boolean" },
|
|
1883
|
-
manageTeam: { "ui:title": "Manage team", "ui:widget": "boolean" },
|
|
1884
|
-
manageIntegrations: {
|
|
1885
|
-
"ui:title": "Manage integrations",
|
|
1886
|
-
"ui:widget": "boolean"
|
|
1887
|
-
},
|
|
1888
|
-
email: { "ui:title": "Email" }
|
|
1889
|
-
};
|
|
1890
2002
|
function formatMyAccessResult(input) {
|
|
1891
2003
|
return formatToolObjectResult(
|
|
1892
2004
|
{
|
|
@@ -1903,14 +2015,8 @@ function formatMyAccessResult(input) {
|
|
|
1903
2015
|
}
|
|
1904
2016
|
},
|
|
1905
2017
|
{
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
"ui:widget": "access",
|
|
1909
|
-
"ui:title": "Your access",
|
|
1910
|
-
items: ACCESS_FIELD_UI
|
|
1911
|
-
}
|
|
1912
|
-
},
|
|
1913
|
-
replyGuidance: MY_ACCESS_REPLY_GUIDANCE
|
|
2018
|
+
replyGuidance: MY_ACCESS_REPLY_GUIDANCE,
|
|
2019
|
+
ui: { entity: "access" }
|
|
1914
2020
|
}
|
|
1915
2021
|
);
|
|
1916
2022
|
}
|
|
@@ -1928,7 +2034,7 @@ function tenantCapabilities(isAdmin) {
|
|
|
1928
2034
|
}
|
|
1929
2035
|
function defineMyAccessTool() {
|
|
1930
2036
|
return defineTool2({
|
|
1931
|
-
description: "Check the authenticated user's tenant role, group memberships, and admin capabilities in RobotRock. Results render as
|
|
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.",
|
|
1932
2038
|
inputSchema: myAccessInputSchema,
|
|
1933
2039
|
async execute(_input, ctx) {
|
|
1934
2040
|
const caller = tryResolveTenantCaller(ctx);
|
|
@@ -1996,10 +2102,207 @@ var whoamiTool = defineWhoamiTool();
|
|
|
1996
2102
|
|
|
1997
2103
|
// src/eve/tools/catalog/search-products.ts
|
|
1998
2104
|
import { defineTool as defineTool4 } from "eve/tools";
|
|
2105
|
+
import { z as z10 } from "zod";
|
|
2106
|
+
|
|
2107
|
+
// src/eve/entity-schemas.ts
|
|
1999
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
|
|
2000
2303
|
var SEARCH_PRODUCTS_TOOL_NAME = "search_products";
|
|
2001
|
-
var searchProductsInputSchema =
|
|
2002
|
-
query:
|
|
2304
|
+
var searchProductsInputSchema = z10.object({
|
|
2305
|
+
query: z10.string().min(1).describe("Product name or SKU to search for.")
|
|
2003
2306
|
});
|
|
2004
2307
|
var DEMO_PRODUCTS = [
|
|
2005
2308
|
{
|
|
@@ -2007,55 +2310,348 @@ var DEMO_PRODUCTS = [
|
|
|
2007
2310
|
name: "Wireless Keyboard",
|
|
2008
2311
|
price: 79.99,
|
|
2009
2312
|
currency: "USD",
|
|
2010
|
-
inStock: true
|
|
2313
|
+
inStock: true,
|
|
2314
|
+
url: "https://shop.example.com/products/sku-1001"
|
|
2011
2315
|
},
|
|
2012
2316
|
{
|
|
2013
2317
|
id: "sku-2042",
|
|
2014
2318
|
name: "USB-C Hub",
|
|
2015
2319
|
price: 45.99,
|
|
2016
2320
|
currency: "USD",
|
|
2017
|
-
inStock: true
|
|
2321
|
+
inStock: true,
|
|
2322
|
+
url: "https://shop.example.com/products/sku-2042"
|
|
2018
2323
|
},
|
|
2019
2324
|
{
|
|
2020
2325
|
id: "sku-3308",
|
|
2021
2326
|
name: "Monitor Stand",
|
|
2022
2327
|
price: 129.99,
|
|
2023
2328
|
currency: "USD",
|
|
2024
|
-
inStock: false
|
|
2329
|
+
inStock: false,
|
|
2330
|
+
url: "https://shop.example.com/products/sku-3308"
|
|
2025
2331
|
}
|
|
2026
2332
|
];
|
|
2027
2333
|
function defineSearchProductsTool() {
|
|
2028
2334
|
return defineTool4({
|
|
2029
|
-
description: "Search the product catalog and return matching items
|
|
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.",
|
|
2030
2336
|
inputSchema: searchProductsInputSchema,
|
|
2337
|
+
outputSchema: searchProductsOutputSchema,
|
|
2031
2338
|
async execute({ query }) {
|
|
2032
2339
|
const normalized = query.trim().toLowerCase();
|
|
2033
2340
|
const items = DEMO_PRODUCTS.filter(
|
|
2034
2341
|
(product) => product.name.toLowerCase().includes(normalized) || product.id.toLowerCase().includes(normalized)
|
|
2035
2342
|
);
|
|
2036
|
-
return
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
"ui:widget": "list",
|
|
2044
|
-
"ui:title": "Results",
|
|
2045
|
-
items: {
|
|
2046
|
-
"ui:widget": "productInfo"
|
|
2047
|
-
}
|
|
2048
|
-
}
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
),
|
|
2052
|
-
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
|
+
}
|
|
2053
2350
|
);
|
|
2054
2351
|
}
|
|
2055
2352
|
});
|
|
2056
2353
|
}
|
|
2057
2354
|
var searchProductsTool = defineSearchProductsTool();
|
|
2058
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
|
+
|
|
2059
2655
|
// src/agent-admin.ts
|
|
2060
2656
|
async function agentAdminFetch(config, path, init) {
|
|
2061
2657
|
const baseUrl = (config.baseUrl?.trim() || getRobotRockApiBaseUrl()).replace(
|
|
@@ -2084,6 +2680,9 @@ async function agentAdminFetch(config, path, init) {
|
|
|
2084
2680
|
}
|
|
2085
2681
|
function createAgentAdminApi(config) {
|
|
2086
2682
|
return {
|
|
2683
|
+
usage: {
|
|
2684
|
+
get: () => agentAdminFetch(config, "/usage")
|
|
2685
|
+
},
|
|
2087
2686
|
members: {
|
|
2088
2687
|
list: () => agentAdminFetch(config, "/members"),
|
|
2089
2688
|
get: (memberRef) => agentAdminFetch(config, `/members/${encodeURIComponent(memberRef)}`),
|
|
@@ -2227,53 +2826,45 @@ function requireBoundAgentAdminClient(ctx) {
|
|
|
2227
2826
|
}
|
|
2228
2827
|
|
|
2229
2828
|
// src/eve/tools/admin/format-team-members-list.ts
|
|
2230
|
-
var MEMBER_DETAIL_UI = {
|
|
2231
|
-
name: { "ui:title": "Name" },
|
|
2232
|
-
email: { "ui:title": "Email" },
|
|
2233
|
-
role: { "ui:title": "Role" },
|
|
2234
|
-
membershipKind: { "ui:title": "Membership" }
|
|
2235
|
-
};
|
|
2236
2829
|
function serializeMemberRow(member) {
|
|
2237
2830
|
return {
|
|
2238
2831
|
name: member.user.name,
|
|
2239
2832
|
email: member.user.email,
|
|
2240
2833
|
role: member.role,
|
|
2241
|
-
membershipKind: member.membershipKind
|
|
2834
|
+
membershipKind: member.membershipKind,
|
|
2835
|
+
profilePictureUrl: member.user.profilePictureUrl ?? null
|
|
2242
2836
|
};
|
|
2243
2837
|
}
|
|
2244
2838
|
function formatTeamMembersListResult(members) {
|
|
2245
|
-
const countLabel = members.length === 1 ? "1 team member" : `${members.length} team members`;
|
|
2246
2839
|
return formatToolListResult(
|
|
2247
2840
|
"members",
|
|
2248
2841
|
members.map(serializeMemberRow),
|
|
2249
2842
|
{
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE
|
|
2843
|
+
replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE,
|
|
2844
|
+
entity: "member"
|
|
2253
2845
|
}
|
|
2254
2846
|
);
|
|
2255
2847
|
}
|
|
2256
|
-
function formatTeamMemberDetailResult(member
|
|
2848
|
+
function formatTeamMemberDetailResult(member) {
|
|
2257
2849
|
return formatToolObjectResult(serializeMemberRow(member), {
|
|
2258
|
-
|
|
2259
|
-
ui:
|
|
2260
|
-
replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE
|
|
2850
|
+
replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE,
|
|
2851
|
+
ui: { entity: "member" }
|
|
2261
2852
|
});
|
|
2262
2853
|
}
|
|
2263
2854
|
|
|
2264
2855
|
// src/eve/tools/admin/manage-team-members.ts
|
|
2265
|
-
import { defineTool as
|
|
2266
|
-
import { z as
|
|
2856
|
+
import { defineTool as defineTool7 } from "eve/tools";
|
|
2857
|
+
import { z as z13 } from "zod";
|
|
2267
2858
|
var MANAGE_TEAM_MEMBERS_TOOL_NAME = "manage_team_members";
|
|
2268
|
-
var manageTeamMembersInputSchema =
|
|
2269
|
-
action:
|
|
2270
|
-
userId:
|
|
2859
|
+
var manageTeamMembersInputSchema = z13.object({
|
|
2860
|
+
action: z13.enum(["list", "get", "invite", "update_role", "remove"]),
|
|
2861
|
+
userId: z13.string().min(1).optional().describe(
|
|
2271
2862
|
"Convex users table id for get, update_role, and remove. Prefer email when the member list only shows email."
|
|
2272
2863
|
),
|
|
2273
|
-
email:
|
|
2864
|
+
email: z13.string().email().optional().describe(
|
|
2274
2865
|
"Member email for get, update_role, and remove; invitee email for invite."
|
|
2275
2866
|
),
|
|
2276
|
-
role:
|
|
2867
|
+
role: z13.enum(["admin", "member"]).optional().describe("Role for invite and update_role.")
|
|
2277
2868
|
}).superRefine((input, ctx) => {
|
|
2278
2869
|
const requireField = (field, message) => {
|
|
2279
2870
|
if (!input[field]) {
|
|
@@ -2308,20 +2899,16 @@ var manageTeamMembersInputSchema = z10.object({
|
|
|
2308
2899
|
function resolveMemberRef(input) {
|
|
2309
2900
|
return input.userId ?? input.email;
|
|
2310
2901
|
}
|
|
2311
|
-
function formatMemberMutationResult(payload
|
|
2902
|
+
function formatMemberMutationResult(payload) {
|
|
2312
2903
|
return formatToolObjectResult(payload, {
|
|
2313
|
-
title,
|
|
2314
|
-
ui: {
|
|
2315
|
-
success: { "ui:title": "Success", "ui:widget": "boolean" },
|
|
2316
|
-
promoted: { "ui:title": "Promoted existing user", "ui:widget": "boolean" }
|
|
2317
|
-
},
|
|
2318
2904
|
replyGuidance: ADMIN_MUTATION_REPLY_GUIDANCE
|
|
2319
2905
|
});
|
|
2320
2906
|
}
|
|
2321
2907
|
function defineManageTeamMembersTool() {
|
|
2322
|
-
return
|
|
2323
|
-
description: "Tenant-admin tool for workspace team members: list, get, invite, change role, or remove. Requires tenant admin access. 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.",
|
|
2324
2910
|
inputSchema: manageTeamMembersInputSchema,
|
|
2911
|
+
outputSchema: manageTeamMembersOutputSchema,
|
|
2325
2912
|
async execute(input, ctx) {
|
|
2326
2913
|
const api = requireBoundAgentAdminClient(ctx);
|
|
2327
2914
|
try {
|
|
@@ -2343,13 +2930,11 @@ function defineManageTeamMembersTool() {
|
|
|
2343
2930
|
});
|
|
2344
2931
|
if (result.member) {
|
|
2345
2932
|
return formatTeamMemberDetailResult(
|
|
2346
|
-
result.member
|
|
2347
|
-
{ title: "Member invited" }
|
|
2933
|
+
result.member
|
|
2348
2934
|
);
|
|
2349
2935
|
}
|
|
2350
2936
|
return formatMemberMutationResult(
|
|
2351
|
-
result
|
|
2352
|
-
"Invitation sent"
|
|
2937
|
+
result
|
|
2353
2938
|
);
|
|
2354
2939
|
}
|
|
2355
2940
|
case "update_role": {
|
|
@@ -2358,16 +2943,14 @@ function defineManageTeamMembersTool() {
|
|
|
2358
2943
|
input.role
|
|
2359
2944
|
);
|
|
2360
2945
|
return formatMemberMutationResult(
|
|
2361
|
-
result
|
|
2362
|
-
"Member role updated"
|
|
2946
|
+
result
|
|
2363
2947
|
);
|
|
2364
2948
|
}
|
|
2365
2949
|
case "remove": {
|
|
2366
2950
|
const memberId = resolveMemberRef(input);
|
|
2367
2951
|
const result = await api.members.remove(memberId);
|
|
2368
2952
|
return formatMemberMutationResult(
|
|
2369
|
-
result
|
|
2370
|
-
"Member removed"
|
|
2953
|
+
result
|
|
2371
2954
|
);
|
|
2372
2955
|
}
|
|
2373
2956
|
}
|
|
@@ -2388,78 +2971,59 @@ function defineManageTeamMembersTool() {
|
|
|
2388
2971
|
var manageTeamMembersTool = defineManageTeamMembersTool();
|
|
2389
2972
|
|
|
2390
2973
|
// src/eve/tools/admin/manage-groups.ts
|
|
2391
|
-
import { defineTool as
|
|
2392
|
-
import { z as
|
|
2974
|
+
import { defineTool as defineTool8 } from "eve/tools";
|
|
2975
|
+
import { z as z14 } from "zod";
|
|
2393
2976
|
|
|
2394
2977
|
// src/eve/tools/admin/format-groups-list.ts
|
|
2395
|
-
|
|
2396
|
-
name: { "ui:title": "Name" },
|
|
2397
|
-
slug: { "ui:title": "Slug" },
|
|
2398
|
-
description: { "ui:title": "Description" },
|
|
2399
|
-
memberCount: { "ui:title": "Members", "ui:widget": "number" }
|
|
2400
|
-
};
|
|
2401
|
-
function serializeGroupRow(group) {
|
|
2978
|
+
function serializeGroupRow(group, tenantSlug) {
|
|
2402
2979
|
return {
|
|
2403
2980
|
name: group.name,
|
|
2404
2981
|
slug: group.slug,
|
|
2405
2982
|
description: group.description,
|
|
2406
|
-
memberCount: group.memberCount ?? null
|
|
2983
|
+
memberCount: group.memberCount ?? null,
|
|
2984
|
+
url: buildTenantGroupUrl(tenantSlug, group.slug)
|
|
2407
2985
|
};
|
|
2408
2986
|
}
|
|
2409
|
-
function formatGroupsListResult(groups) {
|
|
2410
|
-
const countLabel = groups.length === 1 ? "1 group" : `${groups.length} groups`;
|
|
2987
|
+
function formatGroupsListResult(groups, options) {
|
|
2411
2988
|
return formatToolListResult(
|
|
2412
2989
|
"groups",
|
|
2413
|
-
groups.map(serializeGroupRow),
|
|
2990
|
+
groups.map((group) => serializeGroupRow(group, options.tenantSlug)),
|
|
2414
2991
|
{
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE
|
|
2992
|
+
replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE,
|
|
2993
|
+
entity: "group"
|
|
2418
2994
|
}
|
|
2419
2995
|
);
|
|
2420
2996
|
}
|
|
2421
|
-
function formatGroupDetailResult(group) {
|
|
2997
|
+
function formatGroupDetailResult(group, options) {
|
|
2422
2998
|
return formatToolObjectResult(
|
|
2423
2999
|
{
|
|
2424
3000
|
name: group.name,
|
|
2425
3001
|
slug: group.slug,
|
|
2426
3002
|
description: group.description,
|
|
3003
|
+
url: buildTenantGroupUrl(options.tenantSlug, group.slug),
|
|
2427
3004
|
members: group.members.map((member) => ({
|
|
2428
3005
|
name: member.user.name,
|
|
2429
|
-
email: member.user.email
|
|
3006
|
+
email: member.user.email,
|
|
3007
|
+
profilePictureUrl: member.user.profilePictureUrl ?? null
|
|
2430
3008
|
}))
|
|
2431
3009
|
},
|
|
2432
3010
|
{
|
|
2433
|
-
|
|
2434
|
-
ui: {
|
|
2435
|
-
name: { "ui:title": "Name" },
|
|
2436
|
-
slug: { "ui:title": "Slug" },
|
|
2437
|
-
description: { "ui:title": "Description" },
|
|
2438
|
-
members: {
|
|
2439
|
-
"ui:widget": "list",
|
|
2440
|
-
"ui:title": "Members",
|
|
2441
|
-
items: {
|
|
2442
|
-
name: { "ui:title": "Name" },
|
|
2443
|
-
email: { "ui:title": "Email" }
|
|
2444
|
-
}
|
|
2445
|
-
}
|
|
2446
|
-
},
|
|
2447
|
-
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
|
|
3011
|
+
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
|
|
3012
|
+
ui: { entity: "group" }
|
|
2448
3013
|
}
|
|
2449
3014
|
);
|
|
2450
3015
|
}
|
|
2451
|
-
function formatGroupSummaryResult(group) {
|
|
2452
|
-
return formatToolObjectResult(serializeGroupRow(group), {
|
|
2453
|
-
|
|
2454
|
-
ui:
|
|
2455
|
-
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" }
|
|
2456
3020
|
});
|
|
2457
3021
|
}
|
|
2458
3022
|
|
|
2459
3023
|
// src/eve/tools/admin/manage-groups.ts
|
|
2460
3024
|
var MANAGE_GROUPS_TOOL_NAME = "manage_groups";
|
|
2461
|
-
var manageGroupsInputSchema =
|
|
2462
|
-
action:
|
|
3025
|
+
var manageGroupsInputSchema = z14.object({
|
|
3026
|
+
action: z14.enum([
|
|
2463
3027
|
"list",
|
|
2464
3028
|
"get",
|
|
2465
3029
|
"create",
|
|
@@ -2468,18 +3032,18 @@ var manageGroupsInputSchema = z11.object({
|
|
|
2468
3032
|
"add_member",
|
|
2469
3033
|
"remove_member"
|
|
2470
3034
|
]),
|
|
2471
|
-
groupId:
|
|
3035
|
+
groupId: z14.string().min(1).optional().describe(
|
|
2472
3036
|
"Convex group id for get, update, delete, and membership actions. Prefer slug when the group list only shows slug."
|
|
2473
3037
|
),
|
|
2474
|
-
slug:
|
|
3038
|
+
slug: z14.string().min(1).optional().describe(
|
|
2475
3039
|
"Group slug (e.g. finance) for get, update, delete, and membership actions."
|
|
2476
3040
|
),
|
|
2477
|
-
userId:
|
|
3041
|
+
userId: z14.string().min(1).optional().describe(
|
|
2478
3042
|
"User id for add_member and remove_member. Prefer email when the member list only shows email."
|
|
2479
3043
|
),
|
|
2480
|
-
email:
|
|
2481
|
-
name:
|
|
2482
|
-
description:
|
|
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.")
|
|
2483
3047
|
}).superRefine((input, ctx) => {
|
|
2484
3048
|
const requireField = (field, message) => {
|
|
2485
3049
|
if (!input[field]) {
|
|
@@ -2520,9 +3084,8 @@ var manageGroupsInputSchema = z11.object({
|
|
|
2520
3084
|
break;
|
|
2521
3085
|
}
|
|
2522
3086
|
});
|
|
2523
|
-
function formatGroupMutationResult(payload
|
|
3087
|
+
function formatGroupMutationResult(payload) {
|
|
2524
3088
|
return formatToolObjectResult(payload, {
|
|
2525
|
-
title,
|
|
2526
3089
|
replyGuidance: ADMIN_MUTATION_REPLY_GUIDANCE
|
|
2527
3090
|
});
|
|
2528
3091
|
}
|
|
@@ -2533,40 +3096,51 @@ function resolveMemberRef2(input) {
|
|
|
2533
3096
|
return input.userId ?? input.email;
|
|
2534
3097
|
}
|
|
2535
3098
|
function defineManageGroupsTool() {
|
|
2536
|
-
return
|
|
2537
|
-
description: "Tenant-admin tool for workspace groups: list, get, create, update, delete, and manage group membership. Requires tenant admin access. 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.",
|
|
2538
3101
|
inputSchema: manageGroupsInputSchema,
|
|
3102
|
+
outputSchema: manageGroupsOutputSchema,
|
|
2539
3103
|
async execute(input, ctx) {
|
|
3104
|
+
const caller = requireAdminCaller(ctx);
|
|
2540
3105
|
const api = requireBoundAgentAdminClient(ctx);
|
|
3106
|
+
const tenantSlug = caller.tenantSlug;
|
|
2541
3107
|
try {
|
|
2542
3108
|
switch (input.action) {
|
|
2543
3109
|
case "list": {
|
|
2544
3110
|
const result = await api.groups.list();
|
|
2545
|
-
return formatGroupsListResult(result.groups
|
|
3111
|
+
return formatGroupsListResult(result.groups, {
|
|
3112
|
+
tenantSlug
|
|
3113
|
+
});
|
|
2546
3114
|
}
|
|
2547
3115
|
case "get": {
|
|
2548
3116
|
const result = await api.groups.get(resolveGroupRef(input));
|
|
2549
|
-
return formatGroupDetailResult(
|
|
3117
|
+
return formatGroupDetailResult(
|
|
3118
|
+
result.group,
|
|
3119
|
+
{ tenantSlug }
|
|
3120
|
+
);
|
|
2550
3121
|
}
|
|
2551
3122
|
case "create": {
|
|
2552
3123
|
const result = await api.groups.create({
|
|
2553
3124
|
name: input.name,
|
|
2554
3125
|
description: input.description
|
|
2555
3126
|
});
|
|
2556
|
-
return formatGroupSummaryResult(result.group
|
|
3127
|
+
return formatGroupSummaryResult(result.group, {
|
|
3128
|
+
tenantSlug
|
|
3129
|
+
});
|
|
2557
3130
|
}
|
|
2558
3131
|
case "update": {
|
|
2559
3132
|
const result = await api.groups.update(resolveGroupRef(input), {
|
|
2560
3133
|
name: input.name,
|
|
2561
3134
|
description: input.description
|
|
2562
3135
|
});
|
|
2563
|
-
return formatGroupSummaryResult(result.group
|
|
3136
|
+
return formatGroupSummaryResult(result.group, {
|
|
3137
|
+
tenantSlug
|
|
3138
|
+
});
|
|
2564
3139
|
}
|
|
2565
3140
|
case "delete": {
|
|
2566
3141
|
const result = await api.groups.delete(resolveGroupRef(input));
|
|
2567
3142
|
return formatGroupMutationResult(
|
|
2568
|
-
result
|
|
2569
|
-
"Group deleted"
|
|
3143
|
+
result
|
|
2570
3144
|
);
|
|
2571
3145
|
}
|
|
2572
3146
|
case "add_member": {
|
|
@@ -2575,8 +3149,7 @@ function defineManageGroupsTool() {
|
|
|
2575
3149
|
resolveMemberRef2(input)
|
|
2576
3150
|
);
|
|
2577
3151
|
return formatGroupMutationResult(
|
|
2578
|
-
result
|
|
2579
|
-
"Group member added"
|
|
3152
|
+
result
|
|
2580
3153
|
);
|
|
2581
3154
|
}
|
|
2582
3155
|
case "remove_member": {
|
|
@@ -2585,8 +3158,7 @@ function defineManageGroupsTool() {
|
|
|
2585
3158
|
resolveMemberRef2(input)
|
|
2586
3159
|
);
|
|
2587
3160
|
return formatGroupMutationResult(
|
|
2588
|
-
result
|
|
2589
|
-
"Group member removed"
|
|
3161
|
+
result
|
|
2590
3162
|
);
|
|
2591
3163
|
}
|
|
2592
3164
|
}
|
|
@@ -2607,120 +3179,101 @@ function defineManageGroupsTool() {
|
|
|
2607
3179
|
var manageGroupsTool = defineManageGroupsTool();
|
|
2608
3180
|
|
|
2609
3181
|
// src/eve/tools/admin/query-tasks.ts
|
|
2610
|
-
import { defineTool as
|
|
2611
|
-
import { z as
|
|
3182
|
+
import { defineTool as defineTool9 } from "eve/tools";
|
|
3183
|
+
import { z as z15 } from "zod";
|
|
2612
3184
|
|
|
2613
3185
|
// src/eve/tools/admin/format-tasks-list.ts
|
|
2614
3186
|
function resolveTaskCardLabel(task) {
|
|
2615
3187
|
return task.name?.trim() || task.description?.trim() || task.type?.trim() || task.id?.trim() || "Untitled task";
|
|
2616
3188
|
}
|
|
2617
|
-
function
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
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, {
|
|
2622
3200
|
id: task.id,
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
description: task.description
|
|
2627
|
-
})),
|
|
2628
|
-
{
|
|
2629
|
-
title,
|
|
2630
|
-
itemWidget: "tenantTask",
|
|
2631
|
-
replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE
|
|
2632
|
-
}
|
|
2633
|
-
);
|
|
2634
|
-
if (options?.nextCursor) {
|
|
2635
|
-
return {
|
|
2636
|
-
...result,
|
|
2637
|
-
data: {
|
|
2638
|
-
...result.data,
|
|
2639
|
-
nextCursor: options.nextCursor
|
|
2640
|
-
},
|
|
2641
|
-
display: {
|
|
2642
|
-
...result.display,
|
|
2643
|
-
description: "More tasks available \u2014 pass nextCursor to list again."
|
|
2644
|
-
}
|
|
2645
|
-
};
|
|
2646
|
-
}
|
|
2647
|
-
return result;
|
|
3201
|
+
type: task.type
|
|
3202
|
+
})
|
|
3203
|
+
};
|
|
2648
3204
|
}
|
|
2649
|
-
function
|
|
2650
|
-
|
|
2651
|
-
|
|
3205
|
+
function formatTasksListResult(items, options) {
|
|
3206
|
+
const payload = {
|
|
3207
|
+
items: items.map((task) => serializeTaskRow(task, options.tenantSlug))
|
|
3208
|
+
};
|
|
3209
|
+
if (options.nextCursor) {
|
|
3210
|
+
payload.nextCursor = options.nextCursor;
|
|
3211
|
+
}
|
|
3212
|
+
return formatToolObjectResult(payload, {
|
|
3213
|
+
replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE,
|
|
3214
|
+
ui: { layout: "list", entity: "task", rowsPath: "items" }
|
|
2652
3215
|
});
|
|
2653
3216
|
}
|
|
2654
|
-
function
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
});
|
|
3217
|
+
function formatTaskSearchResult(items, options) {
|
|
3218
|
+
return formatTasksListResult(items, options);
|
|
3219
|
+
}
|
|
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;
|
|
2661
3224
|
return formatToolObjectResult(
|
|
2662
3225
|
{
|
|
2663
|
-
id
|
|
2664
|
-
status: task.status
|
|
2665
|
-
type
|
|
2666
|
-
name: task.name
|
|
2667
|
-
description: task.description
|
|
2668
|
-
validUntil: task.validUntil
|
|
2669
|
-
createdAt: task.createdAt
|
|
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
|
|
2670
3234
|
},
|
|
2671
3235
|
{
|
|
2672
|
-
|
|
2673
|
-
ui: {
|
|
2674
|
-
id: { "ui:title": "Task ID" },
|
|
2675
|
-
status: { "ui:title": "Status" },
|
|
2676
|
-
type: { "ui:title": "Type" },
|
|
2677
|
-
name: { "ui:title": "Name" },
|
|
2678
|
-
description: { "ui:title": "Description" },
|
|
2679
|
-
validUntil: { "ui:title": "Valid until", "ui:widget": "date" },
|
|
2680
|
-
createdAt: { "ui:title": "Created", "ui:widget": "date" }
|
|
2681
|
-
},
|
|
2682
|
-
replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE
|
|
3236
|
+
replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE,
|
|
3237
|
+
ui: { entity: "task" }
|
|
2683
3238
|
}
|
|
2684
3239
|
);
|
|
2685
3240
|
}
|
|
2686
|
-
function formatAssignTasksResult(results, _assignTo) {
|
|
2687
|
-
const
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
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, {
|
|
2692
3254
|
id: row.taskId,
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
description: row.description ?? null,
|
|
2701
|
-
status: row.success ? "reassigned" : "failed"
|
|
2702
|
-
})),
|
|
2703
|
-
{
|
|
2704
|
-
title,
|
|
2705
|
-
itemWidget: "tenantTask",
|
|
2706
|
-
replyGuidance: ASSIGN_TASKS_REPLY_GUIDANCE
|
|
2707
|
-
}
|
|
2708
|
-
);
|
|
3255
|
+
type: row.type
|
|
3256
|
+
})
|
|
3257
|
+
}));
|
|
3258
|
+
return formatToolListResult("results", rows, {
|
|
3259
|
+
replyGuidance: ASSIGN_TASKS_REPLY_GUIDANCE,
|
|
3260
|
+
entity: "status"
|
|
3261
|
+
});
|
|
2709
3262
|
}
|
|
2710
3263
|
|
|
2711
3264
|
// src/eve/tools/admin/query-tasks.ts
|
|
2712
3265
|
var QUERY_TASKS_TOOL_NAME = "query_tasks";
|
|
2713
|
-
var queryTasksInputSchema =
|
|
2714
|
-
action:
|
|
2715
|
-
statusFilter:
|
|
2716
|
-
typeFilter:
|
|
2717
|
-
appFilter:
|
|
2718
|
-
sortField:
|
|
2719
|
-
sortDirection:
|
|
2720
|
-
limit:
|
|
2721
|
-
cursor:
|
|
2722
|
-
taskId:
|
|
2723
|
-
query:
|
|
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.")
|
|
2724
3277
|
}).superRefine((input, ctx) => {
|
|
2725
3278
|
switch (input.action) {
|
|
2726
3279
|
case "get":
|
|
@@ -2744,11 +3297,14 @@ var queryTasksInputSchema = z12.object({
|
|
|
2744
3297
|
}
|
|
2745
3298
|
});
|
|
2746
3299
|
function defineQueryTasksTool() {
|
|
2747
|
-
return
|
|
2748
|
-
description: "Tenant-admin tool to list, fetch detail, or search inbox tasks in the workspace. Requires tenant admin access. 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.",
|
|
2749
3302
|
inputSchema: queryTasksInputSchema,
|
|
3303
|
+
outputSchema: queryTasksOutputSchema,
|
|
2750
3304
|
async execute(input, ctx) {
|
|
3305
|
+
const caller = requireAdminCaller(ctx);
|
|
2751
3306
|
const api = requireBoundAgentAdminClient(ctx);
|
|
3307
|
+
const tenantSlug = caller.tenantSlug;
|
|
2752
3308
|
try {
|
|
2753
3309
|
switch (input.action) {
|
|
2754
3310
|
case "list": {
|
|
@@ -2762,18 +3318,22 @@ function defineQueryTasksTool() {
|
|
|
2762
3318
|
cursor: input.cursor
|
|
2763
3319
|
});
|
|
2764
3320
|
return formatTasksListResult(result.items, {
|
|
3321
|
+
tenantSlug,
|
|
2765
3322
|
nextCursor: result.nextCursor
|
|
2766
3323
|
});
|
|
2767
3324
|
}
|
|
2768
3325
|
case "get": {
|
|
2769
3326
|
const result = await api.tasks.get(input.taskId);
|
|
2770
|
-
return formatTaskDetailResult(
|
|
3327
|
+
return formatTaskDetailResult(
|
|
3328
|
+
result.task,
|
|
3329
|
+
{ tenantSlug }
|
|
3330
|
+
);
|
|
2771
3331
|
}
|
|
2772
3332
|
case "search": {
|
|
2773
3333
|
const result = await api.tasks.search(input.query, input.limit);
|
|
2774
3334
|
return formatTaskSearchResult(
|
|
2775
3335
|
result.items,
|
|
2776
|
-
|
|
3336
|
+
{ tenantSlug }
|
|
2777
3337
|
);
|
|
2778
3338
|
}
|
|
2779
3339
|
}
|
|
@@ -2794,11 +3354,11 @@ function defineQueryTasksTool() {
|
|
|
2794
3354
|
var queryTasksTool = defineQueryTasksTool();
|
|
2795
3355
|
|
|
2796
3356
|
// src/eve/tools/admin/assign-tasks.ts
|
|
2797
|
-
import { defineTool as
|
|
2798
|
-
import { z as
|
|
3357
|
+
import { defineTool as defineTool10 } from "eve/tools";
|
|
3358
|
+
import { z as z16 } from "zod";
|
|
2799
3359
|
var ASSIGN_TASKS_TOOL_NAME = "assign_tasks";
|
|
2800
|
-
var assignTasksInputSchema =
|
|
2801
|
-
taskIds:
|
|
3360
|
+
var assignTasksInputSchema = z16.object({
|
|
3361
|
+
taskIds: z16.array(z16.string().min(1)).min(1).max(100).describe(
|
|
2802
3362
|
"Public task ids or Convex tasks table ids to reassign. Use query_tasks search/get to resolve ids first."
|
|
2803
3363
|
),
|
|
2804
3364
|
assignTo: assignToSchema.refine(
|
|
@@ -2809,17 +3369,21 @@ var assignTasksInputSchema = z13.object({
|
|
|
2809
3369
|
)
|
|
2810
3370
|
});
|
|
2811
3371
|
function defineAssignTasksTool() {
|
|
2812
|
-
return
|
|
3372
|
+
return defineTool10({
|
|
2813
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.",
|
|
2814
3374
|
inputSchema: assignTasksInputSchema,
|
|
3375
|
+
outputSchema: assignTasksOutputSchema,
|
|
2815
3376
|
async execute(input, ctx) {
|
|
3377
|
+
const caller = requireTenantCaller(ctx);
|
|
2816
3378
|
const api = createBoundAgentAdminClient(ctx);
|
|
2817
3379
|
try {
|
|
2818
3380
|
const result = await api.tasks.assign({
|
|
2819
3381
|
taskIds: input.taskIds,
|
|
2820
3382
|
assignTo: input.assignTo
|
|
2821
3383
|
});
|
|
2822
|
-
return formatAssignTasksResult(result.results, input.assignTo
|
|
3384
|
+
return formatAssignTasksResult(result.results, input.assignTo, {
|
|
3385
|
+
tenantSlug: caller.tenantSlug
|
|
3386
|
+
});
|
|
2823
3387
|
} catch (error) {
|
|
2824
3388
|
if (error instanceof RobotRockError) {
|
|
2825
3389
|
return {
|
|
@@ -2836,6 +3400,72 @@ function defineAssignTasksTool() {
|
|
|
2836
3400
|
}
|
|
2837
3401
|
var assignTasksTool = defineAssignTasksTool();
|
|
2838
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
|
+
|
|
2839
3469
|
// src/eve/tools/index.ts
|
|
2840
3470
|
function createRobotrockTools(options) {
|
|
2841
3471
|
const tools = {};
|
|
@@ -2853,6 +3483,9 @@ function createRobotrockTools(options) {
|
|
|
2853
3483
|
export {
|
|
2854
3484
|
ASSIGN_TASKS_TOOL_NAME,
|
|
2855
3485
|
CREATE_INBOX_TASK_TOOL_NAME,
|
|
3486
|
+
GENERATE_IMAGE_TOOL_NAME,
|
|
3487
|
+
GENERATE_RANDOM_CHART_TOOL_NAME,
|
|
3488
|
+
GET_WORKSPACE_USAGE_TOOL_NAME,
|
|
2856
3489
|
MANAGE_GROUPS_TOOL_NAME,
|
|
2857
3490
|
MANAGE_TEAM_MEMBERS_TOOL_NAME,
|
|
2858
3491
|
MY_ACCESS_TOOL_NAME,
|
|
@@ -2861,17 +3494,28 @@ export {
|
|
|
2861
3494
|
WHOAMI_TOOL_NAME,
|
|
2862
3495
|
assignTasksInputSchema,
|
|
2863
3496
|
assignTasksTool,
|
|
3497
|
+
buildRandomChartData,
|
|
2864
3498
|
createInboxTaskInputSchema,
|
|
2865
3499
|
createInboxTaskTool,
|
|
2866
3500
|
createRobotrockTools,
|
|
2867
3501
|
defineAssignTasksTool,
|
|
2868
3502
|
defineCreateInboxTaskTool,
|
|
3503
|
+
defineGenerateImageTool,
|
|
3504
|
+
defineGenerateRandomChartTool,
|
|
3505
|
+
defineGetWorkspaceUsageTool,
|
|
2869
3506
|
defineManageGroupsTool,
|
|
2870
3507
|
defineManageTeamMembersTool,
|
|
2871
3508
|
defineMyAccessTool,
|
|
2872
3509
|
defineQueryTasksTool,
|
|
2873
3510
|
defineSearchProductsTool,
|
|
2874
3511
|
defineWhoamiTool,
|
|
3512
|
+
generateImageBytes,
|
|
3513
|
+
generateImageInputSchema,
|
|
3514
|
+
generateImageTool,
|
|
3515
|
+
generateRandomChartInputSchema,
|
|
3516
|
+
generateRandomChartTool,
|
|
3517
|
+
getWorkspaceUsageInputSchema,
|
|
3518
|
+
getWorkspaceUsageTool,
|
|
2875
3519
|
manageGroupsTool,
|
|
2876
3520
|
manageTeamMembersTool,
|
|
2877
3521
|
myAccessInputSchema,
|