robotrock 1.3.4 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -1
- 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 +120 -4
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/trigger.d.ts +3 -3
- package/dist/ai/trigger.js +120 -4
- package/dist/ai/trigger.js.map +1 -1
- package/dist/ai/workflow.d.ts +3 -3
- package/dist/ai/workflow.js +120 -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 -4
- package/dist/eve/agent/index.js +577 -261
- package/dist/eve/agent/index.js.map +1 -1
- package/dist/eve/index.d.ts +4 -4
- package/dist/eve/index.js +507 -7
- package/dist/eve/index.js.map +1 -1
- package/dist/eve/tools/admin/assign-tasks.d.ts +40 -19
- package/dist/eve/tools/admin/assign-tasks.js +334 -25
- 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 +1365 -0
- package/dist/eve/tools/admin/get-workspace-usage.js.map +1 -0
- package/dist/eve/tools/admin/manage-groups.d.ts +122 -7
- package/dist/eve/tools/admin/manage-groups.js +350 -31
- package/dist/eve/tools/admin/manage-groups.js.map +1 -1
- package/dist/eve/tools/admin/manage-team-members.d.ts +86 -7
- package/dist/eve/tools/admin/manage-team-members.js +318 -16
- package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
- package/dist/eve/tools/admin/query-tasks.d.ts +82 -7
- package/dist/eve/tools/admin/query-tasks.js +363 -40
- 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 +2077 -0
- package/dist/eve/tools/catalog/generate-image.js.map +1 -0
- package/dist/eve/tools/catalog/generate-random-chart.d.ts +77 -0
- package/dist/eve/tools/catalog/generate-random-chart.js +411 -0
- package/dist/eve/tools/catalog/generate-random-chart.js.map +1 -0
- package/dist/eve/tools/catalog/search-products.d.ts +36 -43
- package/dist/eve/tools/catalog/search-products.js +253 -6
- package/dist/eve/tools/catalog/search-products.js.map +1 -1
- package/dist/eve/tools/identity/index.d.ts +2 -1
- package/dist/eve/tools/identity/index.js +26 -6
- package/dist/eve/tools/identity/index.js.map +1 -1
- package/dist/eve/tools/identity/my-access.d.ts +88 -3
- package/dist/eve/tools/identity/my-access.js +26 -6
- 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 +964 -115
- package/dist/eve/tools/index.js.map +1 -1
- package/dist/index-amkHKVGs.d.ts +1054 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +328 -13
- 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-Blq0XoAr.d.ts +0 -204
- package/dist/tool-ui-hint-CMpug5sC.d.ts +0 -13
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
|
});
|
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
1980
|
+
result = withUiHint(result, options.uiHint);
|
|
1841
1981
|
}
|
|
1842
|
-
return
|
|
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
|
-
|
|
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,219 @@ 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().describe("X-axis value when xKey is date/time"),
|
|
2150
|
+
category: z9.string().optional().describe("X-axis value when xKey is category"),
|
|
2151
|
+
label: z9.string().optional().describe("X-axis value when xKey is label")
|
|
2152
|
+
}).catchall(z9.union([z9.string(), z9.number()])).describe(
|
|
2153
|
+
"Wide chart point: x-axis field + numeric columns named by yKeys (one series per column)"
|
|
2154
|
+
);
|
|
2155
|
+
var toolChartResultSchema = withAgentOnlyFields({
|
|
2156
|
+
title: z9.string().min(1).optional().describe("Chart title shown above the plot"),
|
|
2157
|
+
description: z9.string().min(1).optional().describe("Optional short subtitle"),
|
|
2158
|
+
type: z9.enum(["line", "bar", "area"]).describe("TRL/shadcn chart variant (time series \u2192 line, categories \u2192 bar)"),
|
|
2159
|
+
xKey: z9.string().min(1).describe('Field on each series row for the x-axis, e.g. "date" or "category"'),
|
|
2160
|
+
yKeys: z9.array(z9.string().min(1)).min(1).describe(
|
|
2161
|
+
'Numeric series column names on each row, e.g. ["NL","BE"] or ["created","handled"]'
|
|
2162
|
+
),
|
|
2163
|
+
series: z9.array(metricPointEntityRowSchema).describe(
|
|
2164
|
+
"Wide-format points only \u2014 one object per x value with yKeys as numeric fields"
|
|
2165
|
+
)
|
|
2166
|
+
});
|
|
2167
|
+
var memberEntityRowSchema = z9.object({
|
|
2168
|
+
name: z9.string(),
|
|
2169
|
+
email: z9.string(),
|
|
2170
|
+
role: z9.string(),
|
|
2171
|
+
membershipKind: z9.string(),
|
|
2172
|
+
profilePictureUrl: z9.string().nullable()
|
|
2173
|
+
});
|
|
2174
|
+
var taskEntityRowSchema = z9.object({
|
|
2175
|
+
id: z9.string().min(1),
|
|
2176
|
+
name: z9.string().min(1),
|
|
2177
|
+
status: z9.string().min(1),
|
|
2178
|
+
type: z9.string().nullable(),
|
|
2179
|
+
description: z9.string().nullable(),
|
|
2180
|
+
validUntil: z9.number(),
|
|
2181
|
+
createdAt: z9.number(),
|
|
2182
|
+
url: z9.string().min(1),
|
|
2183
|
+
threadPriority: z9.string().nullable().optional()
|
|
2184
|
+
});
|
|
2185
|
+
var groupEntityRowSchema = z9.object({
|
|
2186
|
+
name: z9.string().min(1),
|
|
2187
|
+
slug: z9.string().min(1),
|
|
2188
|
+
description: z9.string().nullable(),
|
|
2189
|
+
memberCount: z9.number().nullable(),
|
|
2190
|
+
url: z9.string().min(1)
|
|
2191
|
+
});
|
|
2192
|
+
var groupDetailEntitySchema = z9.object({
|
|
2193
|
+
name: z9.string().min(1),
|
|
2194
|
+
slug: z9.string().min(1),
|
|
2195
|
+
description: z9.string().nullable(),
|
|
2196
|
+
url: z9.string().min(1),
|
|
2197
|
+
members: z9.array(
|
|
2198
|
+
z9.object({
|
|
2199
|
+
name: z9.string(),
|
|
2200
|
+
email: z9.string(),
|
|
2201
|
+
profilePictureUrl: z9.string().nullable()
|
|
2202
|
+
})
|
|
2203
|
+
)
|
|
2204
|
+
});
|
|
2205
|
+
var statusEntityRowSchema = z9.object({
|
|
2206
|
+
id: z9.string().min(1),
|
|
2207
|
+
name: z9.string().min(1),
|
|
2208
|
+
status: z9.string().min(1),
|
|
2209
|
+
url: z9.string().min(1),
|
|
2210
|
+
type: z9.string().nullable().optional(),
|
|
2211
|
+
description: z9.string().nullable().optional()
|
|
2212
|
+
});
|
|
2213
|
+
var agentAdminErrorResultSchema = z9.object({
|
|
2214
|
+
ok: z9.literal(false),
|
|
2215
|
+
status: z9.number().optional(),
|
|
2216
|
+
message: z9.string(),
|
|
2217
|
+
response: z9.unknown().optional()
|
|
2218
|
+
});
|
|
2219
|
+
var agentAdminMutationResultSchema = z9.object({
|
|
2220
|
+
...agentOnlyFields
|
|
2221
|
+
}).passthrough();
|
|
2222
|
+
var searchProductsOutputSchema = withAgentOnlyFields({
|
|
2223
|
+
items: z9.array(productEntityRowSchema)
|
|
2224
|
+
});
|
|
2225
|
+
var generateRandomChartOutputSchema = toolChartResultSchema.extend({
|
|
2226
|
+
title: z9.string().min(1)
|
|
2227
|
+
});
|
|
2228
|
+
var generateImageOutputSchema = withAgentOnlyFields({
|
|
2229
|
+
prompt: z9.string().min(1),
|
|
2230
|
+
mediaType: z9.string().min(1),
|
|
2231
|
+
model: z9.string().min(1),
|
|
2232
|
+
storageId: z9.string().min(1),
|
|
2233
|
+
url: z9.string().min(1),
|
|
2234
|
+
/** @deprecated Legacy sessions only — prefer storageId/url. */
|
|
2235
|
+
base64: z9.string().min(1).optional()
|
|
2236
|
+
});
|
|
2237
|
+
var manageTeamMembersListOutputSchema = withAgentOnlyFields({
|
|
2238
|
+
members: z9.array(memberEntityRowSchema)
|
|
2239
|
+
});
|
|
2240
|
+
var manageTeamMembersDetailOutputSchema = withAgentOnlyFields(
|
|
2241
|
+
memberEntityRowSchema.shape
|
|
2242
|
+
);
|
|
2243
|
+
var manageTeamMembersOutputSchema = z9.union([
|
|
2244
|
+
manageTeamMembersListOutputSchema,
|
|
2245
|
+
manageTeamMembersDetailOutputSchema,
|
|
2246
|
+
agentAdminMutationResultSchema,
|
|
2247
|
+
agentAdminErrorResultSchema
|
|
2248
|
+
]);
|
|
2249
|
+
var manageGroupsListOutputSchema = withAgentOnlyFields({
|
|
2250
|
+
groups: z9.array(groupEntityRowSchema)
|
|
2251
|
+
});
|
|
2252
|
+
var manageGroupsDetailOutputSchema = withAgentOnlyFields(
|
|
2253
|
+
groupDetailEntitySchema.shape
|
|
2254
|
+
);
|
|
2255
|
+
var manageGroupsSummaryOutputSchema = withAgentOnlyFields(
|
|
2256
|
+
groupEntityRowSchema.shape
|
|
2257
|
+
);
|
|
2258
|
+
var manageGroupsOutputSchema = z9.union([
|
|
2259
|
+
manageGroupsListOutputSchema,
|
|
2260
|
+
manageGroupsDetailOutputSchema,
|
|
2261
|
+
manageGroupsSummaryOutputSchema,
|
|
2262
|
+
agentAdminMutationResultSchema,
|
|
2263
|
+
agentAdminErrorResultSchema
|
|
2264
|
+
]);
|
|
2265
|
+
var queryTasksListOutputSchema = withAgentOnlyFields({
|
|
2266
|
+
items: z9.array(taskEntityRowSchema),
|
|
2267
|
+
nextCursor: z9.string().nullable().optional()
|
|
2268
|
+
});
|
|
2269
|
+
var queryTasksDetailOutputSchema = withAgentOnlyFields({
|
|
2270
|
+
id: z9.string().nullable(),
|
|
2271
|
+
status: z9.string().nullable(),
|
|
2272
|
+
type: z9.string().nullable(),
|
|
2273
|
+
name: z9.string().nullable(),
|
|
2274
|
+
description: z9.string().nullable(),
|
|
2275
|
+
validUntil: z9.number().nullable(),
|
|
2276
|
+
createdAt: z9.number().nullable(),
|
|
2277
|
+
url: z9.string().min(1).nullable()
|
|
2278
|
+
});
|
|
2279
|
+
var queryTasksOutputSchema = z9.union([
|
|
2280
|
+
queryTasksListOutputSchema,
|
|
2281
|
+
queryTasksDetailOutputSchema,
|
|
2282
|
+
agentAdminErrorResultSchema
|
|
2283
|
+
]);
|
|
2284
|
+
var assignTasksOutputSchema = z9.union([
|
|
2285
|
+
withAgentOnlyFields({
|
|
2286
|
+
results: z9.array(statusEntityRowSchema)
|
|
2287
|
+
}),
|
|
2288
|
+
agentAdminErrorResultSchema
|
|
2289
|
+
]);
|
|
2290
|
+
var workspaceUsageEntitySchema = z9.object({
|
|
2291
|
+
workspace: z9.string(),
|
|
2292
|
+
plan: z9.string(),
|
|
2293
|
+
planType: z9.string(),
|
|
2294
|
+
trialState: z9.string(),
|
|
2295
|
+
daysRemaining: z9.number().nullable(),
|
|
2296
|
+
isPaidPro: z9.boolean(),
|
|
2297
|
+
subscriptionStatus: z9.string(),
|
|
2298
|
+
tasksToday: z9.string(),
|
|
2299
|
+
tasksResetAt: z9.string(),
|
|
2300
|
+
openTasks: z9.number(),
|
|
2301
|
+
totalTasks: z9.number(),
|
|
2302
|
+
seats: z9.string(),
|
|
2303
|
+
groups: z9.string(),
|
|
2304
|
+
apiKeys: z9.string(),
|
|
2305
|
+
rateLimitPerSecond: z9.number()
|
|
2306
|
+
});
|
|
2307
|
+
var getWorkspaceUsageOutputSchema = z9.union([
|
|
2308
|
+
withAgentOnlyFields({
|
|
2309
|
+
usage: workspaceUsageEntitySchema
|
|
2310
|
+
}),
|
|
2311
|
+
agentAdminErrorResultSchema
|
|
2312
|
+
]);
|
|
2313
|
+
|
|
2314
|
+
// src/eve/tools/catalog/search-products.ts
|
|
1955
2315
|
var SEARCH_PRODUCTS_TOOL_NAME = "search_products";
|
|
1956
|
-
var searchProductsInputSchema =
|
|
1957
|
-
query:
|
|
2316
|
+
var searchProductsInputSchema = z10.object({
|
|
2317
|
+
query: z10.string().min(1).describe("Product name or SKU to search for.")
|
|
1958
2318
|
});
|
|
1959
2319
|
var DEMO_PRODUCTS = [
|
|
1960
2320
|
{
|
|
@@ -1962,38 +2322,392 @@ var DEMO_PRODUCTS = [
|
|
|
1962
2322
|
name: "Wireless Keyboard",
|
|
1963
2323
|
price: 79.99,
|
|
1964
2324
|
currency: "USD",
|
|
1965
|
-
inStock: true
|
|
2325
|
+
inStock: true,
|
|
2326
|
+
url: "https://shop.example.com/products/sku-1001"
|
|
1966
2327
|
},
|
|
1967
2328
|
{
|
|
1968
2329
|
id: "sku-2042",
|
|
1969
2330
|
name: "USB-C Hub",
|
|
1970
2331
|
price: 45.99,
|
|
1971
2332
|
currency: "USD",
|
|
1972
|
-
inStock: true
|
|
2333
|
+
inStock: true,
|
|
2334
|
+
url: "https://shop.example.com/products/sku-2042"
|
|
1973
2335
|
},
|
|
1974
2336
|
{
|
|
1975
2337
|
id: "sku-3308",
|
|
1976
2338
|
name: "Monitor Stand",
|
|
1977
2339
|
price: 129.99,
|
|
1978
2340
|
currency: "USD",
|
|
1979
|
-
inStock: false
|
|
2341
|
+
inStock: false,
|
|
2342
|
+
url: "https://shop.example.com/products/sku-3308"
|
|
1980
2343
|
}
|
|
1981
2344
|
];
|
|
1982
2345
|
function defineSearchProductsTool() {
|
|
1983
2346
|
return defineTool4({
|
|
1984
2347
|
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
2348
|
inputSchema: searchProductsInputSchema,
|
|
2349
|
+
outputSchema: searchProductsOutputSchema,
|
|
1986
2350
|
async execute({ query }) {
|
|
1987
2351
|
const normalized = query.trim().toLowerCase();
|
|
1988
2352
|
const items = DEMO_PRODUCTS.filter(
|
|
1989
2353
|
(product) => product.name.toLowerCase().includes(normalized) || product.id.toLowerCase().includes(normalized)
|
|
1990
2354
|
);
|
|
1991
|
-
return
|
|
2355
|
+
return formatToolListResult(
|
|
2356
|
+
"items",
|
|
2357
|
+
items.map((product) => ({ ...product })),
|
|
2358
|
+
{
|
|
2359
|
+
replyGuidance: SEARCH_PRODUCTS_REPLY_GUIDANCE,
|
|
2360
|
+
entity: "product"
|
|
2361
|
+
}
|
|
2362
|
+
);
|
|
1992
2363
|
}
|
|
1993
2364
|
});
|
|
1994
2365
|
}
|
|
1995
2366
|
var searchProductsTool = defineSearchProductsTool();
|
|
1996
2367
|
|
|
2368
|
+
// src/eve/tools/catalog/generate-random-chart.ts
|
|
2369
|
+
import { defineTool as defineTool5 } from "eve/tools";
|
|
2370
|
+
import { z as z11 } from "zod";
|
|
2371
|
+
|
|
2372
|
+
// src/eve/tool-chart-format.ts
|
|
2373
|
+
var TIME_X_AXIS_KEY_PATTERN = /^(date|time|timestamp|month|day|week|period)$/i;
|
|
2374
|
+
function inferToolChartType(xKey) {
|
|
2375
|
+
return TIME_X_AXIS_KEY_PATTERN.test(xKey) ? "line" : "bar";
|
|
2376
|
+
}
|
|
2377
|
+
function formatToolChartResult(chart, options) {
|
|
2378
|
+
if (!chart.xKey.trim()) {
|
|
2379
|
+
throw new Error("formatToolChartResult: xKey is required");
|
|
2380
|
+
}
|
|
2381
|
+
const yKeys = chart.yKeys.map((key) => key.trim()).filter((key) => key.length > 0);
|
|
2382
|
+
if (yKeys.length === 0) {
|
|
2383
|
+
throw new Error("formatToolChartResult: yKeys must include at least one series key");
|
|
2384
|
+
}
|
|
2385
|
+
const data = {
|
|
2386
|
+
...chart.title?.trim() ? { title: chart.title.trim() } : {},
|
|
2387
|
+
...chart.description?.trim() ? { description: chart.description.trim() } : {},
|
|
2388
|
+
type: chart.type ?? inferToolChartType(chart.xKey),
|
|
2389
|
+
xKey: chart.xKey.trim(),
|
|
2390
|
+
yKeys,
|
|
2391
|
+
series: chart.series.map((row) => ({ ...row }))
|
|
2392
|
+
};
|
|
2393
|
+
const ui = {
|
|
2394
|
+
...options.ui,
|
|
2395
|
+
layout: "chart",
|
|
2396
|
+
rowsPath: "series",
|
|
2397
|
+
entity: options.entity ?? options.ui?.entity ?? "metric_point",
|
|
2398
|
+
present: options.present ?? options.ui?.present ?? true
|
|
2399
|
+
};
|
|
2400
|
+
return withUiHint(
|
|
2401
|
+
withToolUi(withReplyGuidance(data, options.replyGuidance), ui),
|
|
2402
|
+
"chart"
|
|
2403
|
+
);
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2406
|
+
// src/eve/tools/catalog/generate-random-chart.ts
|
|
2407
|
+
var GENERATE_RANDOM_CHART_TOOL_NAME = "generate_random_chart";
|
|
2408
|
+
var generateRandomChartInputSchema = z11.object({
|
|
2409
|
+
axis: z11.enum(["time", "category", "random"]).optional().describe(
|
|
2410
|
+
"X-axis style: time (line), category (bar), or random. Defaults to random."
|
|
2411
|
+
),
|
|
2412
|
+
seriesCount: z11.number().int().min(1).max(3).optional().describe("Number of numeric series (1\u20133). Defaults to a random 1\u20132."),
|
|
2413
|
+
pointCount: z11.number().int().min(4).max(30).optional().describe("Number of data points (4\u201330). Defaults to a random 8\u201314."),
|
|
2414
|
+
seed: z11.number().int().optional().describe("Optional seed for reproducible random data.")
|
|
2415
|
+
});
|
|
2416
|
+
function createRng(seed) {
|
|
2417
|
+
let state = seed === void 0 ? (Math.floor(Math.random() * 2147483647) ^ Date.now()) >>> 0 : seed >>> 0;
|
|
2418
|
+
if (state === 0) {
|
|
2419
|
+
state = 1;
|
|
2420
|
+
}
|
|
2421
|
+
return () => {
|
|
2422
|
+
state ^= state << 13;
|
|
2423
|
+
state ^= state >>> 17;
|
|
2424
|
+
state ^= state << 5;
|
|
2425
|
+
return (state >>> 0) / 4294967296;
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2428
|
+
function pick(rng, items) {
|
|
2429
|
+
return items[Math.floor(rng() * items.length)];
|
|
2430
|
+
}
|
|
2431
|
+
function randomInt(rng, min, max) {
|
|
2432
|
+
return min + Math.floor(rng() * (max - min + 1));
|
|
2433
|
+
}
|
|
2434
|
+
function roundMetric(value) {
|
|
2435
|
+
return Math.round(value * 10) / 10;
|
|
2436
|
+
}
|
|
2437
|
+
var TIME_TITLES = [
|
|
2438
|
+
"Task throughput",
|
|
2439
|
+
"Approvals over time",
|
|
2440
|
+
"Inbox volume",
|
|
2441
|
+
"Agent tool calls",
|
|
2442
|
+
"Webhook deliveries"
|
|
2443
|
+
];
|
|
2444
|
+
var CATEGORY_TITLES = [
|
|
2445
|
+
"Tasks by status",
|
|
2446
|
+
"Approvals by team",
|
|
2447
|
+
"Volume by region",
|
|
2448
|
+
"Spend by category",
|
|
2449
|
+
"Tickets by priority"
|
|
2450
|
+
];
|
|
2451
|
+
var TIME_SERIES_KEYS = [
|
|
2452
|
+
["value"],
|
|
2453
|
+
["created", "handled"],
|
|
2454
|
+
["open", "handled", "expired"]
|
|
2455
|
+
];
|
|
2456
|
+
var CATEGORY_SERIES_KEYS = [
|
|
2457
|
+
["value"],
|
|
2458
|
+
["revenue", "costs"],
|
|
2459
|
+
["approved", "rejected", "pending"]
|
|
2460
|
+
];
|
|
2461
|
+
var CATEGORIES = [
|
|
2462
|
+
["North", "South", "East", "West", "Central"],
|
|
2463
|
+
["Finance", "Ops", "Support", "Engineering", "Sales"],
|
|
2464
|
+
["P0", "P1", "P2", "P3", "P4"],
|
|
2465
|
+
["Draft", "Open", "Handled", "Expired", "Cancelled"]
|
|
2466
|
+
];
|
|
2467
|
+
function formatDate(daysAgo) {
|
|
2468
|
+
const date = /* @__PURE__ */ new Date();
|
|
2469
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
2470
|
+
date.setUTCDate(date.getUTCDate() - daysAgo);
|
|
2471
|
+
return date.toISOString().slice(0, 10);
|
|
2472
|
+
}
|
|
2473
|
+
function buildSeriesPoints(args) {
|
|
2474
|
+
const { rng, axis, seriesKeys, pointCount } = args;
|
|
2475
|
+
const baselines = seriesKeys.map(() => 20 + rng() * 80);
|
|
2476
|
+
if (axis === "time") {
|
|
2477
|
+
return Array.from({ length: pointCount }, (_, index) => {
|
|
2478
|
+
const point = {
|
|
2479
|
+
date: formatDate(pointCount - 1 - index)
|
|
2480
|
+
};
|
|
2481
|
+
for (let i = 0; i < seriesKeys.length; i++) {
|
|
2482
|
+
const drift = (rng() - 0.45) * 12;
|
|
2483
|
+
baselines[i] = Math.max(1, baselines[i] + drift);
|
|
2484
|
+
point[seriesKeys[i]] = roundMetric(baselines[i]);
|
|
2485
|
+
}
|
|
2486
|
+
return point;
|
|
2487
|
+
});
|
|
2488
|
+
}
|
|
2489
|
+
const labels = pick(rng, CATEGORIES).slice(0, pointCount);
|
|
2490
|
+
return labels.map((label) => {
|
|
2491
|
+
const point = { category: label };
|
|
2492
|
+
for (let i = 0; i < seriesKeys.length; i++) {
|
|
2493
|
+
point[seriesKeys[i]] = roundMetric(8 + rng() * 120);
|
|
2494
|
+
}
|
|
2495
|
+
return point;
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
function buildRandomChartData(input = {}) {
|
|
2499
|
+
const rng = createRng(input.seed);
|
|
2500
|
+
const axis = input.axis === "time" || input.axis === "category" ? input.axis : pick(rng, ["time", "category"]);
|
|
2501
|
+
const seriesCount = input.seriesCount ?? randomInt(rng, 1, 2);
|
|
2502
|
+
const pointCount = input.pointCount ?? (axis === "time" ? randomInt(rng, 8, 14) : randomInt(rng, 4, 6));
|
|
2503
|
+
const keyPool = axis === "time" ? TIME_SERIES_KEYS : CATEGORY_SERIES_KEYS;
|
|
2504
|
+
const seriesKeys = keyPool.find((keys) => keys.length === seriesCount) ?? keyPool[0];
|
|
2505
|
+
const title = pick(rng, axis === "time" ? TIME_TITLES : CATEGORY_TITLES);
|
|
2506
|
+
const series = buildSeriesPoints({
|
|
2507
|
+
rng,
|
|
2508
|
+
axis,
|
|
2509
|
+
seriesKeys,
|
|
2510
|
+
pointCount
|
|
2511
|
+
});
|
|
2512
|
+
return { title, axis, series };
|
|
2513
|
+
}
|
|
2514
|
+
function defineGenerateRandomChartTool() {
|
|
2515
|
+
return defineTool5({
|
|
2516
|
+
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.",
|
|
2517
|
+
inputSchema: generateRandomChartInputSchema,
|
|
2518
|
+
outputSchema: generateRandomChartOutputSchema,
|
|
2519
|
+
async execute(input) {
|
|
2520
|
+
const data = buildRandomChartData(input);
|
|
2521
|
+
const xKey = data.axis === "time" ? "date" : "category";
|
|
2522
|
+
const sample = data.series[0] ?? {};
|
|
2523
|
+
const yKeys = Object.keys(sample).filter((key) => key !== xKey);
|
|
2524
|
+
const result = formatToolChartResult(
|
|
2525
|
+
{
|
|
2526
|
+
title: data.title,
|
|
2527
|
+
type: data.axis === "time" ? "line" : "bar",
|
|
2528
|
+
xKey,
|
|
2529
|
+
yKeys,
|
|
2530
|
+
series: data.series
|
|
2531
|
+
},
|
|
2532
|
+
{
|
|
2533
|
+
replyGuidance: GENERATE_RANDOM_CHART_REPLY_GUIDANCE,
|
|
2534
|
+
entity: "metric_point",
|
|
2535
|
+
present: true
|
|
2536
|
+
}
|
|
2537
|
+
);
|
|
2538
|
+
return { ...result, title: data.title };
|
|
2539
|
+
}
|
|
2540
|
+
});
|
|
2541
|
+
}
|
|
2542
|
+
var generateRandomChartTool = defineGenerateRandomChartTool();
|
|
2543
|
+
|
|
2544
|
+
// src/eve/tools/catalog/generate-image.ts
|
|
2545
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
2546
|
+
import { createGateway, generateImage } from "ai";
|
|
2547
|
+
import { defineTool as defineTool6 } from "eve/tools";
|
|
2548
|
+
import { z as z12 } from "zod";
|
|
2549
|
+
var GENERATE_IMAGE_TOOL_NAME = "generate_image";
|
|
2550
|
+
var DEFAULT_IMAGE_MODEL = "black-forest-labs/flux.2-klein-4b";
|
|
2551
|
+
var DEFAULT_IMAGE_SIZE = "512";
|
|
2552
|
+
var DEFAULT_IMAGE_ASPECT_RATIO = "1:1";
|
|
2553
|
+
var generateImageInputSchema = z12.object({
|
|
2554
|
+
prompt: z12.string().min(1).describe("Detailed description of the image to generate")
|
|
2555
|
+
});
|
|
2556
|
+
function normalizeEnvValue(value) {
|
|
2557
|
+
if (!value) {
|
|
2558
|
+
return void 0;
|
|
2559
|
+
}
|
|
2560
|
+
return value.replace(/^["']|["']$/g, "");
|
|
2561
|
+
}
|
|
2562
|
+
function isJwtExpired(token, bufferSeconds = 60) {
|
|
2563
|
+
try {
|
|
2564
|
+
const payload = JSON.parse(
|
|
2565
|
+
Buffer.from(token.split(".")[1] ?? "", "base64url").toString("utf8")
|
|
2566
|
+
);
|
|
2567
|
+
return typeof payload.exp !== "number" || Date.now() / 1e3 >= payload.exp - bufferSeconds;
|
|
2568
|
+
} catch {
|
|
2569
|
+
return true;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
function resolveAiImageModel(modelId = normalizeEnvValue(process.env.AI_IMAGE_MODEL) ?? DEFAULT_IMAGE_MODEL) {
|
|
2573
|
+
const openRouterKey = normalizeEnvValue(process.env.OPENROUTER_API_KEY);
|
|
2574
|
+
if (openRouterKey) {
|
|
2575
|
+
const openrouter = createOpenRouter({ apiKey: openRouterKey });
|
|
2576
|
+
return {
|
|
2577
|
+
provider: "openrouter",
|
|
2578
|
+
model: openrouter.imageModel(modelId),
|
|
2579
|
+
modelId
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
const gatewayKey = normalizeEnvValue(process.env.AI_GATEWAY_API_KEY);
|
|
2583
|
+
if (gatewayKey) {
|
|
2584
|
+
const gateway2 = createGateway({ apiKey: gatewayKey });
|
|
2585
|
+
return {
|
|
2586
|
+
provider: "ai-gateway-api-key",
|
|
2587
|
+
model: gateway2.imageModel(modelId),
|
|
2588
|
+
modelId
|
|
2589
|
+
};
|
|
2590
|
+
}
|
|
2591
|
+
const oidcToken = normalizeEnvValue(process.env.VERCEL_OIDC_TOKEN);
|
|
2592
|
+
if (!oidcToken) {
|
|
2593
|
+
throw new Error(
|
|
2594
|
+
`No AI provider credentials for image model "${modelId}". Set OPENROUTER_API_KEY (preferred), or AI_GATEWAY_API_KEY / VERCEL_OIDC_TOKEN.`
|
|
2595
|
+
);
|
|
2596
|
+
}
|
|
2597
|
+
if (isJwtExpired(oidcToken)) {
|
|
2598
|
+
throw new Error(
|
|
2599
|
+
"VERCEL_OIDC_TOKEN is expired. Set OPENROUTER_API_KEY instead, or refresh the OIDC token."
|
|
2600
|
+
);
|
|
2601
|
+
}
|
|
2602
|
+
process.env.VERCEL_OIDC_TOKEN = oidcToken;
|
|
2603
|
+
const gateway = createGateway();
|
|
2604
|
+
return {
|
|
2605
|
+
provider: "ai-gateway-oidc",
|
|
2606
|
+
model: gateway.imageModel(modelId),
|
|
2607
|
+
modelId
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
function resolveAiImageSize() {
|
|
2611
|
+
return normalizeEnvValue(process.env.AI_IMAGE_SIZE) ?? DEFAULT_IMAGE_SIZE;
|
|
2612
|
+
}
|
|
2613
|
+
function resolveAiImageAspectRatio() {
|
|
2614
|
+
return normalizeEnvValue(process.env.AI_IMAGE_ASPECT_RATIO) ?? DEFAULT_IMAGE_ASPECT_RATIO;
|
|
2615
|
+
}
|
|
2616
|
+
function extensionForMediaType(mediaType) {
|
|
2617
|
+
const normalized = mediaType.toLowerCase();
|
|
2618
|
+
if (normalized.includes("jpeg") || normalized.includes("jpg")) return "jpg";
|
|
2619
|
+
if (normalized.includes("webp")) return "webp";
|
|
2620
|
+
if (normalized.includes("gif")) return "gif";
|
|
2621
|
+
return "png";
|
|
2622
|
+
}
|
|
2623
|
+
function filenameFromImagePrompt(prompt, mediaType) {
|
|
2624
|
+
const slug = prompt.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
2625
|
+
return `${slug || "generated-image"}.${extensionForMediaType(mediaType)}`;
|
|
2626
|
+
}
|
|
2627
|
+
async function generateImageBytes(input, options) {
|
|
2628
|
+
const { model, modelId } = resolveAiImageModel();
|
|
2629
|
+
const size = resolveAiImageSize();
|
|
2630
|
+
const aspectRatio = resolveAiImageAspectRatio();
|
|
2631
|
+
try {
|
|
2632
|
+
const { image } = await generateImage({
|
|
2633
|
+
model,
|
|
2634
|
+
prompt: input.prompt,
|
|
2635
|
+
aspectRatio,
|
|
2636
|
+
abortSignal: options?.abortSignal,
|
|
2637
|
+
size
|
|
2638
|
+
});
|
|
2639
|
+
if (!image.base64) {
|
|
2640
|
+
throw new Error(`Image model "${modelId}" returned no image data.`);
|
|
2641
|
+
}
|
|
2642
|
+
return {
|
|
2643
|
+
prompt: input.prompt,
|
|
2644
|
+
mediaType: image.mediaType || "image/png",
|
|
2645
|
+
model: modelId,
|
|
2646
|
+
base64: image.base64
|
|
2647
|
+
};
|
|
2648
|
+
} catch (error) {
|
|
2649
|
+
const message = error instanceof Error ? error.message : "Image generation failed.";
|
|
2650
|
+
throw new Error(`Image generation failed (${modelId}): ${message}`);
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
function defineGenerateImageTool() {
|
|
2654
|
+
return defineTool6({
|
|
2655
|
+
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.",
|
|
2656
|
+
inputSchema: generateImageInputSchema,
|
|
2657
|
+
outputSchema: generateImageOutputSchema,
|
|
2658
|
+
toModelOutput(output) {
|
|
2659
|
+
return {
|
|
2660
|
+
type: "text",
|
|
2661
|
+
value: `Generated an image for: "${output.prompt}" (model: ${output.model}).`
|
|
2662
|
+
};
|
|
2663
|
+
},
|
|
2664
|
+
async execute(input, ctx) {
|
|
2665
|
+
const caller = tryResolveTenantCaller(ctx);
|
|
2666
|
+
const chatId = caller?.chatId?.trim();
|
|
2667
|
+
if (!chatId) {
|
|
2668
|
+
throw new Error(
|
|
2669
|
+
"generate_image requires a dashboard chat session (missing chatId)."
|
|
2670
|
+
);
|
|
2671
|
+
}
|
|
2672
|
+
const client = tryCreateBoundRobotRockClient(ctx);
|
|
2673
|
+
if (!client) {
|
|
2674
|
+
throw new Error(
|
|
2675
|
+
"RobotRock auth is unset. Configure ROBOTROCK_AGENT_SERVICE_TOKEN for hosted agents or ROBOTROCK_API_KEY for self-hosted deployments."
|
|
2676
|
+
);
|
|
2677
|
+
}
|
|
2678
|
+
const generated = await generateImageBytes(input, {
|
|
2679
|
+
abortSignal: ctx?.abortSignal
|
|
2680
|
+
});
|
|
2681
|
+
const uploaded = await client.chats.uploadImage({
|
|
2682
|
+
mediaType: generated.mediaType,
|
|
2683
|
+
base64: generated.base64,
|
|
2684
|
+
chatId,
|
|
2685
|
+
source: GENERATE_IMAGE_TOOL_NAME,
|
|
2686
|
+
filename: filenameFromImagePrompt(generated.prompt, generated.mediaType),
|
|
2687
|
+
description: generated.prompt,
|
|
2688
|
+
tags: [GENERATE_IMAGE_TOOL_NAME]
|
|
2689
|
+
});
|
|
2690
|
+
return formatToolObjectResult(
|
|
2691
|
+
{
|
|
2692
|
+
prompt: generated.prompt,
|
|
2693
|
+
mediaType: uploaded.mediaType || generated.mediaType,
|
|
2694
|
+
model: generated.model,
|
|
2695
|
+
storageId: uploaded.storageId,
|
|
2696
|
+
url: uploaded.url
|
|
2697
|
+
},
|
|
2698
|
+
{
|
|
2699
|
+
replyGuidance: GENERATE_IMAGE_REPLY_GUIDANCE,
|
|
2700
|
+
ui: {
|
|
2701
|
+
present: true,
|
|
2702
|
+
entity: "generated_image"
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
);
|
|
2706
|
+
}
|
|
2707
|
+
});
|
|
2708
|
+
}
|
|
2709
|
+
var generateImageTool = defineGenerateImageTool();
|
|
2710
|
+
|
|
1997
2711
|
// src/agent-admin.ts
|
|
1998
2712
|
async function agentAdminFetch(config, path, init) {
|
|
1999
2713
|
const baseUrl = (config.baseUrl?.trim() || getRobotRockApiBaseUrl()).replace(
|
|
@@ -2022,6 +2736,9 @@ async function agentAdminFetch(config, path, init) {
|
|
|
2022
2736
|
}
|
|
2023
2737
|
function createAgentAdminApi(config) {
|
|
2024
2738
|
return {
|
|
2739
|
+
usage: {
|
|
2740
|
+
get: () => agentAdminFetch(config, "/usage")
|
|
2741
|
+
},
|
|
2025
2742
|
members: {
|
|
2026
2743
|
list: () => agentAdminFetch(config, "/members"),
|
|
2027
2744
|
get: (memberRef) => agentAdminFetch(config, `/members/${encodeURIComponent(memberRef)}`),
|
|
@@ -2170,7 +2887,8 @@ function serializeMemberRow(member) {
|
|
|
2170
2887
|
name: member.user.name,
|
|
2171
2888
|
email: member.user.email,
|
|
2172
2889
|
role: member.role,
|
|
2173
|
-
membershipKind: member.membershipKind
|
|
2890
|
+
membershipKind: member.membershipKind,
|
|
2891
|
+
profilePictureUrl: member.user.profilePictureUrl ?? null
|
|
2174
2892
|
};
|
|
2175
2893
|
}
|
|
2176
2894
|
function formatTeamMembersListResult(members) {
|
|
@@ -2178,29 +2896,31 @@ function formatTeamMembersListResult(members) {
|
|
|
2178
2896
|
"members",
|
|
2179
2897
|
members.map(serializeMemberRow),
|
|
2180
2898
|
{
|
|
2181
|
-
replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE
|
|
2899
|
+
replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE,
|
|
2900
|
+
entity: "member"
|
|
2182
2901
|
}
|
|
2183
2902
|
);
|
|
2184
2903
|
}
|
|
2185
2904
|
function formatTeamMemberDetailResult(member) {
|
|
2186
2905
|
return formatToolObjectResult(serializeMemberRow(member), {
|
|
2187
|
-
replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE
|
|
2906
|
+
replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE,
|
|
2907
|
+
ui: { entity: "member" }
|
|
2188
2908
|
});
|
|
2189
2909
|
}
|
|
2190
2910
|
|
|
2191
2911
|
// src/eve/tools/admin/manage-team-members.ts
|
|
2192
|
-
import { defineTool as
|
|
2193
|
-
import { z as
|
|
2912
|
+
import { defineTool as defineTool7 } from "eve/tools";
|
|
2913
|
+
import { z as z13 } from "zod";
|
|
2194
2914
|
var MANAGE_TEAM_MEMBERS_TOOL_NAME = "manage_team_members";
|
|
2195
|
-
var manageTeamMembersInputSchema =
|
|
2196
|
-
action:
|
|
2197
|
-
userId:
|
|
2915
|
+
var manageTeamMembersInputSchema = z13.object({
|
|
2916
|
+
action: z13.enum(["list", "get", "invite", "update_role", "remove"]),
|
|
2917
|
+
userId: z13.string().min(1).optional().describe(
|
|
2198
2918
|
"Convex users table id for get, update_role, and remove. Prefer email when the member list only shows email."
|
|
2199
2919
|
),
|
|
2200
|
-
email:
|
|
2920
|
+
email: z13.string().email().optional().describe(
|
|
2201
2921
|
"Member email for get, update_role, and remove; invitee email for invite."
|
|
2202
2922
|
),
|
|
2203
|
-
role:
|
|
2923
|
+
role: z13.enum(["admin", "member"]).optional().describe("Role for invite and update_role.")
|
|
2204
2924
|
}).superRefine((input, ctx) => {
|
|
2205
2925
|
const requireField = (field, message) => {
|
|
2206
2926
|
if (!input[field]) {
|
|
@@ -2241,9 +2961,10 @@ function formatMemberMutationResult(payload) {
|
|
|
2241
2961
|
});
|
|
2242
2962
|
}
|
|
2243
2963
|
function defineManageTeamMembersTool() {
|
|
2244
|
-
return
|
|
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
|
|
2964
|
+
return defineTool7({
|
|
2965
|
+
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
2966
|
inputSchema: manageTeamMembersInputSchema,
|
|
2967
|
+
outputSchema: manageTeamMembersOutputSchema,
|
|
2247
2968
|
async execute(input, ctx) {
|
|
2248
2969
|
const api = requireBoundAgentAdminClient(ctx);
|
|
2249
2970
|
try {
|
|
@@ -2306,53 +3027,59 @@ function defineManageTeamMembersTool() {
|
|
|
2306
3027
|
var manageTeamMembersTool = defineManageTeamMembersTool();
|
|
2307
3028
|
|
|
2308
3029
|
// src/eve/tools/admin/manage-groups.ts
|
|
2309
|
-
import { defineTool as
|
|
2310
|
-
import { z as
|
|
3030
|
+
import { defineTool as defineTool8 } from "eve/tools";
|
|
3031
|
+
import { z as z14 } from "zod";
|
|
2311
3032
|
|
|
2312
3033
|
// src/eve/tools/admin/format-groups-list.ts
|
|
2313
|
-
function serializeGroupRow(group) {
|
|
3034
|
+
function serializeGroupRow(group, tenantSlug) {
|
|
2314
3035
|
return {
|
|
2315
3036
|
name: group.name,
|
|
2316
3037
|
slug: group.slug,
|
|
2317
3038
|
description: group.description,
|
|
2318
|
-
memberCount: group.memberCount ?? null
|
|
3039
|
+
memberCount: group.memberCount ?? null,
|
|
3040
|
+
url: buildTenantGroupUrl(tenantSlug, group.slug)
|
|
2319
3041
|
};
|
|
2320
3042
|
}
|
|
2321
|
-
function formatGroupsListResult(groups) {
|
|
3043
|
+
function formatGroupsListResult(groups, options) {
|
|
2322
3044
|
return formatToolListResult(
|
|
2323
3045
|
"groups",
|
|
2324
|
-
groups.map(serializeGroupRow),
|
|
3046
|
+
groups.map((group) => serializeGroupRow(group, options.tenantSlug)),
|
|
2325
3047
|
{
|
|
2326
|
-
replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE
|
|
3048
|
+
replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE,
|
|
3049
|
+
entity: "group"
|
|
2327
3050
|
}
|
|
2328
3051
|
);
|
|
2329
3052
|
}
|
|
2330
|
-
function formatGroupDetailResult(group) {
|
|
3053
|
+
function formatGroupDetailResult(group, options) {
|
|
2331
3054
|
return formatToolObjectResult(
|
|
2332
3055
|
{
|
|
2333
3056
|
name: group.name,
|
|
2334
3057
|
slug: group.slug,
|
|
2335
3058
|
description: group.description,
|
|
3059
|
+
url: buildTenantGroupUrl(options.tenantSlug, group.slug),
|
|
2336
3060
|
members: group.members.map((member) => ({
|
|
2337
3061
|
name: member.user.name,
|
|
2338
|
-
email: member.user.email
|
|
3062
|
+
email: member.user.email,
|
|
3063
|
+
profilePictureUrl: member.user.profilePictureUrl ?? null
|
|
2339
3064
|
}))
|
|
2340
3065
|
},
|
|
2341
3066
|
{
|
|
2342
|
-
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
|
|
3067
|
+
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
|
|
3068
|
+
ui: { entity: "group" }
|
|
2343
3069
|
}
|
|
2344
3070
|
);
|
|
2345
3071
|
}
|
|
2346
|
-
function formatGroupSummaryResult(group) {
|
|
2347
|
-
return formatToolObjectResult(serializeGroupRow(group), {
|
|
2348
|
-
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
|
|
3072
|
+
function formatGroupSummaryResult(group, options) {
|
|
3073
|
+
return formatToolObjectResult(serializeGroupRow(group, options.tenantSlug), {
|
|
3074
|
+
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
|
|
3075
|
+
ui: { entity: "group" }
|
|
2349
3076
|
});
|
|
2350
3077
|
}
|
|
2351
3078
|
|
|
2352
3079
|
// src/eve/tools/admin/manage-groups.ts
|
|
2353
3080
|
var MANAGE_GROUPS_TOOL_NAME = "manage_groups";
|
|
2354
|
-
var manageGroupsInputSchema =
|
|
2355
|
-
action:
|
|
3081
|
+
var manageGroupsInputSchema = z14.object({
|
|
3082
|
+
action: z14.enum([
|
|
2356
3083
|
"list",
|
|
2357
3084
|
"get",
|
|
2358
3085
|
"create",
|
|
@@ -2361,18 +3088,18 @@ var manageGroupsInputSchema = z11.object({
|
|
|
2361
3088
|
"add_member",
|
|
2362
3089
|
"remove_member"
|
|
2363
3090
|
]),
|
|
2364
|
-
groupId:
|
|
3091
|
+
groupId: z14.string().min(1).optional().describe(
|
|
2365
3092
|
"Convex group id for get, update, delete, and membership actions. Prefer slug when the group list only shows slug."
|
|
2366
3093
|
),
|
|
2367
|
-
slug:
|
|
3094
|
+
slug: z14.string().min(1).optional().describe(
|
|
2368
3095
|
"Group slug (e.g. finance) for get, update, delete, and membership actions."
|
|
2369
3096
|
),
|
|
2370
|
-
userId:
|
|
3097
|
+
userId: z14.string().min(1).optional().describe(
|
|
2371
3098
|
"User id for add_member and remove_member. Prefer email when the member list only shows email."
|
|
2372
3099
|
),
|
|
2373
|
-
email:
|
|
2374
|
-
name:
|
|
2375
|
-
description:
|
|
3100
|
+
email: z14.string().email().optional().describe("Member email for add_member and remove_member."),
|
|
3101
|
+
name: z14.string().min(1).optional().describe("Group name for create and update."),
|
|
3102
|
+
description: z14.string().optional().describe("Group description for create and update.")
|
|
2376
3103
|
}).superRefine((input, ctx) => {
|
|
2377
3104
|
const requireField = (field, message) => {
|
|
2378
3105
|
if (!input[field]) {
|
|
@@ -2425,34 +3152,46 @@ function resolveMemberRef2(input) {
|
|
|
2425
3152
|
return input.userId ?? input.email;
|
|
2426
3153
|
}
|
|
2427
3154
|
function defineManageGroupsTool() {
|
|
2428
|
-
return
|
|
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
|
|
3155
|
+
return defineTool8({
|
|
3156
|
+
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
3157
|
inputSchema: manageGroupsInputSchema,
|
|
3158
|
+
outputSchema: manageGroupsOutputSchema,
|
|
2431
3159
|
async execute(input, ctx) {
|
|
3160
|
+
const caller = requireAdminCaller(ctx);
|
|
2432
3161
|
const api = requireBoundAgentAdminClient(ctx);
|
|
3162
|
+
const tenantSlug = caller.tenantSlug;
|
|
2433
3163
|
try {
|
|
2434
3164
|
switch (input.action) {
|
|
2435
3165
|
case "list": {
|
|
2436
3166
|
const result = await api.groups.list();
|
|
2437
|
-
return formatGroupsListResult(result.groups
|
|
3167
|
+
return formatGroupsListResult(result.groups, {
|
|
3168
|
+
tenantSlug
|
|
3169
|
+
});
|
|
2438
3170
|
}
|
|
2439
3171
|
case "get": {
|
|
2440
3172
|
const result = await api.groups.get(resolveGroupRef(input));
|
|
2441
|
-
return formatGroupDetailResult(
|
|
3173
|
+
return formatGroupDetailResult(
|
|
3174
|
+
result.group,
|
|
3175
|
+
{ tenantSlug }
|
|
3176
|
+
);
|
|
2442
3177
|
}
|
|
2443
3178
|
case "create": {
|
|
2444
3179
|
const result = await api.groups.create({
|
|
2445
3180
|
name: input.name,
|
|
2446
3181
|
description: input.description
|
|
2447
3182
|
});
|
|
2448
|
-
return formatGroupSummaryResult(result.group
|
|
3183
|
+
return formatGroupSummaryResult(result.group, {
|
|
3184
|
+
tenantSlug
|
|
3185
|
+
});
|
|
2449
3186
|
}
|
|
2450
3187
|
case "update": {
|
|
2451
3188
|
const result = await api.groups.update(resolveGroupRef(input), {
|
|
2452
3189
|
name: input.name,
|
|
2453
3190
|
description: input.description
|
|
2454
3191
|
});
|
|
2455
|
-
return formatGroupSummaryResult(result.group
|
|
3192
|
+
return formatGroupSummaryResult(result.group, {
|
|
3193
|
+
tenantSlug
|
|
3194
|
+
});
|
|
2456
3195
|
}
|
|
2457
3196
|
case "delete": {
|
|
2458
3197
|
const result = await api.groups.delete(resolveGroupRef(input));
|
|
@@ -2496,83 +3235,101 @@ function defineManageGroupsTool() {
|
|
|
2496
3235
|
var manageGroupsTool = defineManageGroupsTool();
|
|
2497
3236
|
|
|
2498
3237
|
// src/eve/tools/admin/query-tasks.ts
|
|
2499
|
-
import { defineTool as
|
|
2500
|
-
import { z as
|
|
3238
|
+
import { defineTool as defineTool9 } from "eve/tools";
|
|
3239
|
+
import { z as z15 } from "zod";
|
|
2501
3240
|
|
|
2502
3241
|
// src/eve/tools/admin/format-tasks-list.ts
|
|
2503
3242
|
function resolveTaskCardLabel(task) {
|
|
2504
3243
|
return task.name?.trim() || task.description?.trim() || task.type?.trim() || task.id?.trim() || "Untitled task";
|
|
2505
3244
|
}
|
|
3245
|
+
function serializeTaskRow(task, tenantSlug) {
|
|
3246
|
+
return {
|
|
3247
|
+
id: task.id,
|
|
3248
|
+
name: resolveTaskCardLabel(task),
|
|
3249
|
+
status: task.status,
|
|
3250
|
+
type: task.type,
|
|
3251
|
+
description: task.description,
|
|
3252
|
+
validUntil: task.validUntil,
|
|
3253
|
+
createdAt: task.createdAt,
|
|
3254
|
+
threadPriority: task.threadPriority,
|
|
3255
|
+
url: buildTenantTaskUrl(tenantSlug, {
|
|
3256
|
+
id: task.id,
|
|
3257
|
+
type: task.type
|
|
3258
|
+
})
|
|
3259
|
+
};
|
|
3260
|
+
}
|
|
2506
3261
|
function formatTasksListResult(items, options) {
|
|
2507
3262
|
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
|
-
}))
|
|
3263
|
+
items: items.map((task) => serializeTaskRow(task, options.tenantSlug))
|
|
2515
3264
|
};
|
|
2516
|
-
if (options
|
|
3265
|
+
if (options.nextCursor) {
|
|
2517
3266
|
payload.nextCursor = options.nextCursor;
|
|
2518
3267
|
}
|
|
2519
3268
|
return formatToolObjectResult(payload, {
|
|
2520
|
-
replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE
|
|
3269
|
+
replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE,
|
|
3270
|
+
ui: { layout: "list", entity: "task", rowsPath: "items" }
|
|
2521
3271
|
});
|
|
2522
3272
|
}
|
|
2523
|
-
function formatTaskSearchResult(items) {
|
|
2524
|
-
return formatTasksListResult(items);
|
|
3273
|
+
function formatTaskSearchResult(items, options) {
|
|
3274
|
+
return formatTasksListResult(items, options);
|
|
2525
3275
|
}
|
|
2526
|
-
function formatTaskDetailResult(task) {
|
|
3276
|
+
function formatTaskDetailResult(task, options) {
|
|
3277
|
+
const id = typeof task.id === "string" ? task.id : null;
|
|
3278
|
+
const type = typeof task.type === "string" ? task.type : null;
|
|
3279
|
+
const url = id !== null ? buildTenantTaskUrl(options.tenantSlug, { id, type }) : null;
|
|
2527
3280
|
return formatToolObjectResult(
|
|
2528
3281
|
{
|
|
2529
|
-
id
|
|
2530
|
-
status: task.status
|
|
2531
|
-
type
|
|
2532
|
-
name: task.name
|
|
2533
|
-
description: task.description
|
|
2534
|
-
validUntil: task.validUntil
|
|
2535
|
-
createdAt: task.createdAt
|
|
3282
|
+
id,
|
|
3283
|
+
status: typeof task.status === "string" ? task.status : null,
|
|
3284
|
+
type,
|
|
3285
|
+
name: typeof task.name === "string" ? task.name : null,
|
|
3286
|
+
description: typeof task.description === "string" ? task.description : null,
|
|
3287
|
+
validUntil: typeof task.validUntil === "number" ? task.validUntil : null,
|
|
3288
|
+
createdAt: typeof task.createdAt === "number" ? task.createdAt : null,
|
|
3289
|
+
url
|
|
2536
3290
|
},
|
|
2537
3291
|
{
|
|
2538
|
-
replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE
|
|
3292
|
+
replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE,
|
|
3293
|
+
ui: { entity: "task" }
|
|
2539
3294
|
}
|
|
2540
3295
|
);
|
|
2541
3296
|
}
|
|
2542
|
-
function formatAssignTasksResult(results, _assignTo) {
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
3297
|
+
function formatAssignTasksResult(results, _assignTo, options) {
|
|
3298
|
+
const rows = results.map((row) => ({
|
|
3299
|
+
id: row.taskId,
|
|
3300
|
+
name: resolveTaskCardLabel({
|
|
3301
|
+
name: row.name,
|
|
3302
|
+
description: row.description,
|
|
3303
|
+
type: row.type,
|
|
3304
|
+
id: row.taskId
|
|
3305
|
+
}),
|
|
3306
|
+
type: row.type ?? null,
|
|
3307
|
+
description: row.description ?? null,
|
|
3308
|
+
status: row.success ? "reassigned" : "failed",
|
|
3309
|
+
url: buildTenantTaskUrl(options.tenantSlug, {
|
|
2546
3310
|
id: row.taskId,
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
description: row.description ?? null,
|
|
2555
|
-
status: row.success ? "reassigned" : "failed"
|
|
2556
|
-
})),
|
|
2557
|
-
{
|
|
2558
|
-
replyGuidance: ASSIGN_TASKS_REPLY_GUIDANCE
|
|
2559
|
-
}
|
|
2560
|
-
);
|
|
3311
|
+
type: row.type
|
|
3312
|
+
})
|
|
3313
|
+
}));
|
|
3314
|
+
return formatToolListResult("results", rows, {
|
|
3315
|
+
replyGuidance: ASSIGN_TASKS_REPLY_GUIDANCE,
|
|
3316
|
+
entity: "status"
|
|
3317
|
+
});
|
|
2561
3318
|
}
|
|
2562
3319
|
|
|
2563
3320
|
// src/eve/tools/admin/query-tasks.ts
|
|
2564
3321
|
var QUERY_TASKS_TOOL_NAME = "query_tasks";
|
|
2565
|
-
var queryTasksInputSchema =
|
|
2566
|
-
action:
|
|
2567
|
-
statusFilter:
|
|
2568
|
-
typeFilter:
|
|
2569
|
-
appFilter:
|
|
2570
|
-
sortField:
|
|
2571
|
-
sortDirection:
|
|
2572
|
-
limit:
|
|
2573
|
-
cursor:
|
|
2574
|
-
taskId:
|
|
2575
|
-
query:
|
|
3322
|
+
var queryTasksInputSchema = z15.object({
|
|
3323
|
+
action: z15.enum(["list", "get", "search"]),
|
|
3324
|
+
statusFilter: z15.enum(["all", "open", "handled", "expired"]).optional().describe("Filter by task status for list."),
|
|
3325
|
+
typeFilter: z15.string().optional(),
|
|
3326
|
+
appFilter: z15.string().optional(),
|
|
3327
|
+
sortField: z15.enum(["type", "date", "status", "validUntil"]).optional(),
|
|
3328
|
+
sortDirection: z15.enum(["asc", "desc"]).optional(),
|
|
3329
|
+
limit: z15.number().int().positive().max(100).optional(),
|
|
3330
|
+
cursor: z15.string().optional(),
|
|
3331
|
+
taskId: z15.string().min(1).optional().describe("Public task id or Convex tasks table id for get."),
|
|
3332
|
+
query: z15.string().min(1).optional().describe("Search type, name, description, or id for search.")
|
|
2576
3333
|
}).superRefine((input, ctx) => {
|
|
2577
3334
|
switch (input.action) {
|
|
2578
3335
|
case "get":
|
|
@@ -2596,11 +3353,14 @@ var queryTasksInputSchema = z12.object({
|
|
|
2596
3353
|
}
|
|
2597
3354
|
});
|
|
2598
3355
|
function defineQueryTasksTool() {
|
|
2599
|
-
return
|
|
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
|
|
3356
|
+
return defineTool9({
|
|
3357
|
+
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
3358
|
inputSchema: queryTasksInputSchema,
|
|
3359
|
+
outputSchema: queryTasksOutputSchema,
|
|
2602
3360
|
async execute(input, ctx) {
|
|
3361
|
+
const caller = requireAdminCaller(ctx);
|
|
2603
3362
|
const api = requireBoundAgentAdminClient(ctx);
|
|
3363
|
+
const tenantSlug = caller.tenantSlug;
|
|
2604
3364
|
try {
|
|
2605
3365
|
switch (input.action) {
|
|
2606
3366
|
case "list": {
|
|
@@ -2614,17 +3374,22 @@ function defineQueryTasksTool() {
|
|
|
2614
3374
|
cursor: input.cursor
|
|
2615
3375
|
});
|
|
2616
3376
|
return formatTasksListResult(result.items, {
|
|
3377
|
+
tenantSlug,
|
|
2617
3378
|
nextCursor: result.nextCursor
|
|
2618
3379
|
});
|
|
2619
3380
|
}
|
|
2620
3381
|
case "get": {
|
|
2621
3382
|
const result = await api.tasks.get(input.taskId);
|
|
2622
|
-
return formatTaskDetailResult(
|
|
3383
|
+
return formatTaskDetailResult(
|
|
3384
|
+
result.task,
|
|
3385
|
+
{ tenantSlug }
|
|
3386
|
+
);
|
|
2623
3387
|
}
|
|
2624
3388
|
case "search": {
|
|
2625
3389
|
const result = await api.tasks.search(input.query, input.limit);
|
|
2626
3390
|
return formatTaskSearchResult(
|
|
2627
|
-
result.items
|
|
3391
|
+
result.items,
|
|
3392
|
+
{ tenantSlug }
|
|
2628
3393
|
);
|
|
2629
3394
|
}
|
|
2630
3395
|
}
|
|
@@ -2645,11 +3410,11 @@ function defineQueryTasksTool() {
|
|
|
2645
3410
|
var queryTasksTool = defineQueryTasksTool();
|
|
2646
3411
|
|
|
2647
3412
|
// src/eve/tools/admin/assign-tasks.ts
|
|
2648
|
-
import { defineTool as
|
|
2649
|
-
import { z as
|
|
3413
|
+
import { defineTool as defineTool10 } from "eve/tools";
|
|
3414
|
+
import { z as z16 } from "zod";
|
|
2650
3415
|
var ASSIGN_TASKS_TOOL_NAME = "assign_tasks";
|
|
2651
|
-
var assignTasksInputSchema =
|
|
2652
|
-
taskIds:
|
|
3416
|
+
var assignTasksInputSchema = z16.object({
|
|
3417
|
+
taskIds: z16.array(z16.string().min(1)).min(1).max(100).describe(
|
|
2653
3418
|
"Public task ids or Convex tasks table ids to reassign. Use query_tasks search/get to resolve ids first."
|
|
2654
3419
|
),
|
|
2655
3420
|
assignTo: assignToSchema.refine(
|
|
@@ -2660,17 +3425,21 @@ var assignTasksInputSchema = z13.object({
|
|
|
2660
3425
|
)
|
|
2661
3426
|
});
|
|
2662
3427
|
function defineAssignTasksTool() {
|
|
2663
|
-
return
|
|
3428
|
+
return defineTool10({
|
|
2664
3429
|
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
3430
|
inputSchema: assignTasksInputSchema,
|
|
3431
|
+
outputSchema: assignTasksOutputSchema,
|
|
2666
3432
|
async execute(input, ctx) {
|
|
3433
|
+
const caller = requireTenantCaller(ctx);
|
|
2667
3434
|
const api = createBoundAgentAdminClient(ctx);
|
|
2668
3435
|
try {
|
|
2669
3436
|
const result = await api.tasks.assign({
|
|
2670
3437
|
taskIds: input.taskIds,
|
|
2671
3438
|
assignTo: input.assignTo
|
|
2672
3439
|
});
|
|
2673
|
-
return formatAssignTasksResult(result.results, input.assignTo
|
|
3440
|
+
return formatAssignTasksResult(result.results, input.assignTo, {
|
|
3441
|
+
tenantSlug: caller.tenantSlug
|
|
3442
|
+
});
|
|
2674
3443
|
} catch (error) {
|
|
2675
3444
|
if (error instanceof RobotRockError) {
|
|
2676
3445
|
return {
|
|
@@ -2687,6 +3456,72 @@ function defineAssignTasksTool() {
|
|
|
2687
3456
|
}
|
|
2688
3457
|
var assignTasksTool = defineAssignTasksTool();
|
|
2689
3458
|
|
|
3459
|
+
// src/eve/tools/admin/get-workspace-usage.ts
|
|
3460
|
+
import { defineTool as defineTool11 } from "eve/tools";
|
|
3461
|
+
import { z as z17 } from "zod";
|
|
3462
|
+
|
|
3463
|
+
// src/eve/tools/admin/format-workspace-usage.ts
|
|
3464
|
+
function formatLimit(current, max) {
|
|
3465
|
+
return max === null ? `${current} / unlimited` : `${current} / ${max}`;
|
|
3466
|
+
}
|
|
3467
|
+
function formatWorkspaceUsageResult(usage) {
|
|
3468
|
+
const tasksLimit = usage.maxTasksPerDay === null ? `${usage.tasksToday} / unlimited` : `${usage.tasksToday} / ${usage.maxTasksPerDay}`;
|
|
3469
|
+
return formatToolObjectResult(
|
|
3470
|
+
{
|
|
3471
|
+
usage: {
|
|
3472
|
+
workspace: usage.workspace,
|
|
3473
|
+
plan: usage.planName,
|
|
3474
|
+
planType: usage.planType,
|
|
3475
|
+
trialState: usage.trialState,
|
|
3476
|
+
daysRemaining: usage.daysRemaining,
|
|
3477
|
+
isPaidPro: usage.isPaidPro,
|
|
3478
|
+
subscriptionStatus: usage.subscriptionStatus ?? "\u2014",
|
|
3479
|
+
tasksToday: tasksLimit,
|
|
3480
|
+
tasksResetAt: new Date(usage.tasksResetAt).toISOString(),
|
|
3481
|
+
openTasks: usage.openTasks,
|
|
3482
|
+
totalTasks: usage.totalTasks,
|
|
3483
|
+
seats: formatLimit(usage.seatsCurrent, usage.seatsMax),
|
|
3484
|
+
groups: formatLimit(usage.groupsCurrent, usage.groupsMax),
|
|
3485
|
+
apiKeys: formatLimit(usage.apiKeysCurrent, usage.apiKeysMax),
|
|
3486
|
+
rateLimitPerSecond: usage.rateLimitPerSecond
|
|
3487
|
+
}
|
|
3488
|
+
},
|
|
3489
|
+
{
|
|
3490
|
+
replyGuidance: GET_WORKSPACE_USAGE_REPLY_GUIDANCE,
|
|
3491
|
+
ui: { entity: "usage" }
|
|
3492
|
+
}
|
|
3493
|
+
);
|
|
3494
|
+
}
|
|
3495
|
+
|
|
3496
|
+
// src/eve/tools/admin/get-workspace-usage.ts
|
|
3497
|
+
var GET_WORKSPACE_USAGE_TOOL_NAME = "get_workspace_usage";
|
|
3498
|
+
var getWorkspaceUsageInputSchema = z17.object({});
|
|
3499
|
+
function defineGetWorkspaceUsageTool() {
|
|
3500
|
+
return defineTool11({
|
|
3501
|
+
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.",
|
|
3502
|
+
inputSchema: getWorkspaceUsageInputSchema,
|
|
3503
|
+
outputSchema: getWorkspaceUsageOutputSchema,
|
|
3504
|
+
async execute(_input, ctx) {
|
|
3505
|
+
const api = requireBoundAgentAdminClient(ctx);
|
|
3506
|
+
try {
|
|
3507
|
+
const result = await api.usage.get();
|
|
3508
|
+
return formatWorkspaceUsageResult(result.usage);
|
|
3509
|
+
} catch (error) {
|
|
3510
|
+
if (error instanceof RobotRockError) {
|
|
3511
|
+
return {
|
|
3512
|
+
ok: false,
|
|
3513
|
+
status: error.statusCode,
|
|
3514
|
+
message: error.message,
|
|
3515
|
+
response: error.response
|
|
3516
|
+
};
|
|
3517
|
+
}
|
|
3518
|
+
throw error;
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
});
|
|
3522
|
+
}
|
|
3523
|
+
var getWorkspaceUsageTool = defineGetWorkspaceUsageTool();
|
|
3524
|
+
|
|
2690
3525
|
// src/eve/tools/index.ts
|
|
2691
3526
|
function createRobotrockTools(options) {
|
|
2692
3527
|
const tools = {};
|
|
@@ -2704,6 +3539,9 @@ function createRobotrockTools(options) {
|
|
|
2704
3539
|
export {
|
|
2705
3540
|
ASSIGN_TASKS_TOOL_NAME,
|
|
2706
3541
|
CREATE_INBOX_TASK_TOOL_NAME,
|
|
3542
|
+
GENERATE_IMAGE_TOOL_NAME,
|
|
3543
|
+
GENERATE_RANDOM_CHART_TOOL_NAME,
|
|
3544
|
+
GET_WORKSPACE_USAGE_TOOL_NAME,
|
|
2707
3545
|
MANAGE_GROUPS_TOOL_NAME,
|
|
2708
3546
|
MANAGE_TEAM_MEMBERS_TOOL_NAME,
|
|
2709
3547
|
MY_ACCESS_TOOL_NAME,
|
|
@@ -2712,17 +3550,28 @@ export {
|
|
|
2712
3550
|
WHOAMI_TOOL_NAME,
|
|
2713
3551
|
assignTasksInputSchema,
|
|
2714
3552
|
assignTasksTool,
|
|
3553
|
+
buildRandomChartData,
|
|
2715
3554
|
createInboxTaskInputSchema,
|
|
2716
3555
|
createInboxTaskTool,
|
|
2717
3556
|
createRobotrockTools,
|
|
2718
3557
|
defineAssignTasksTool,
|
|
2719
3558
|
defineCreateInboxTaskTool,
|
|
3559
|
+
defineGenerateImageTool,
|
|
3560
|
+
defineGenerateRandomChartTool,
|
|
3561
|
+
defineGetWorkspaceUsageTool,
|
|
2720
3562
|
defineManageGroupsTool,
|
|
2721
3563
|
defineManageTeamMembersTool,
|
|
2722
3564
|
defineMyAccessTool,
|
|
2723
3565
|
defineQueryTasksTool,
|
|
2724
3566
|
defineSearchProductsTool,
|
|
2725
3567
|
defineWhoamiTool,
|
|
3568
|
+
generateImageBytes,
|
|
3569
|
+
generateImageInputSchema,
|
|
3570
|
+
generateImageTool,
|
|
3571
|
+
generateRandomChartInputSchema,
|
|
3572
|
+
generateRandomChartTool,
|
|
3573
|
+
getWorkspaceUsageInputSchema,
|
|
3574
|
+
getWorkspaceUsageTool,
|
|
2726
3575
|
manageGroupsTool,
|
|
2727
3576
|
manageTeamMembersTool,
|
|
2728
3577
|
myAccessInputSchema,
|