robotrock 1.3.4 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +565 -261
- package/dist/eve/agent/index.js.map +1 -1
- package/dist/eve/index.d.ts +4 -4
- package/dist/eve/index.js +384 -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 +322 -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 +1353 -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 +338 -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 +306 -16
- package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
- package/dist/eve/tools/admin/query-tasks.d.ts +85 -10
- package/dist/eve/tools/admin/query-tasks.js +351 -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 +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 -43
- package/dist/eve/tools/catalog/search-products.js +241 -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 +90 -5
- 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 +908 -115
- package/dist/eve/tools/index.js.map +1 -1
- package/dist/index-Drj0Rzf_.d.ts +905 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.js +316 -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,207 @@ var whoamiTool = defineWhoamiTool();
|
|
|
1951
2102
|
|
|
1952
2103
|
// src/eve/tools/catalog/search-products.ts
|
|
1953
2104
|
import { defineTool as defineTool4 } from "eve/tools";
|
|
2105
|
+
import { z as z10 } from "zod";
|
|
2106
|
+
|
|
2107
|
+
// src/eve/entity-schemas.ts
|
|
1954
2108
|
import { z as z9 } from "zod";
|
|
2109
|
+
function buildTenantTaskUrl(tenantSlug, task) {
|
|
2110
|
+
const q = new URLSearchParams();
|
|
2111
|
+
if (task.app && task.app !== "default") {
|
|
2112
|
+
q.set("app", task.app);
|
|
2113
|
+
}
|
|
2114
|
+
if (task.type?.trim()) {
|
|
2115
|
+
q.set("type", task.type.trim());
|
|
2116
|
+
}
|
|
2117
|
+
q.set("selected", task.id);
|
|
2118
|
+
return `/${tenantSlug}/inbox?${q.toString()}`;
|
|
2119
|
+
}
|
|
2120
|
+
function buildTenantGroupUrl(tenantSlug, slug) {
|
|
2121
|
+
return `/${tenantSlug}/team/groups/${slug}`;
|
|
2122
|
+
}
|
|
2123
|
+
var toolResultUiMetaSchema = z9.object({
|
|
2124
|
+
present: z9.boolean().optional(),
|
|
2125
|
+
entity: z9.string().regex(TOOL_RESULT_UI_ENTITY_ID_RE).optional(),
|
|
2126
|
+
rowsPath: z9.string().min(1).optional(),
|
|
2127
|
+
layout: z9.enum(["list", "chart", "table"]).optional()
|
|
2128
|
+
}).strict();
|
|
2129
|
+
var agentOnlyFields = {
|
|
2130
|
+
replyGuidance: z9.string().optional(),
|
|
2131
|
+
ui: toolResultUiMetaSchema.optional(),
|
|
2132
|
+
uiHint: z9.enum(["list", "chart", "table"]).optional()
|
|
2133
|
+
};
|
|
2134
|
+
function withAgentOnlyFields(shape) {
|
|
2135
|
+
return z9.object({
|
|
2136
|
+
...shape,
|
|
2137
|
+
...agentOnlyFields
|
|
2138
|
+
});
|
|
2139
|
+
}
|
|
2140
|
+
var productEntityRowSchema = z9.object({
|
|
2141
|
+
id: z9.string().min(1),
|
|
2142
|
+
name: z9.string().min(1),
|
|
2143
|
+
price: z9.number(),
|
|
2144
|
+
currency: z9.string().min(1),
|
|
2145
|
+
inStock: z9.boolean(),
|
|
2146
|
+
url: z9.string().min(1)
|
|
2147
|
+
});
|
|
2148
|
+
var metricPointEntityRowSchema = z9.object({
|
|
2149
|
+
date: z9.string().optional(),
|
|
2150
|
+
category: z9.string().optional(),
|
|
2151
|
+
label: z9.string().optional()
|
|
2152
|
+
}).catchall(z9.union([z9.string(), z9.number()]));
|
|
2153
|
+
var memberEntityRowSchema = z9.object({
|
|
2154
|
+
name: z9.string(),
|
|
2155
|
+
email: z9.string(),
|
|
2156
|
+
role: z9.string(),
|
|
2157
|
+
membershipKind: z9.string(),
|
|
2158
|
+
profilePictureUrl: z9.string().nullable()
|
|
2159
|
+
});
|
|
2160
|
+
var taskEntityRowSchema = z9.object({
|
|
2161
|
+
id: z9.string().min(1),
|
|
2162
|
+
name: z9.string().min(1),
|
|
2163
|
+
status: z9.string().min(1),
|
|
2164
|
+
type: z9.string().nullable(),
|
|
2165
|
+
description: z9.string().nullable(),
|
|
2166
|
+
validUntil: z9.number(),
|
|
2167
|
+
createdAt: z9.number(),
|
|
2168
|
+
url: z9.string().min(1),
|
|
2169
|
+
threadPriority: z9.string().nullable().optional()
|
|
2170
|
+
});
|
|
2171
|
+
var groupEntityRowSchema = z9.object({
|
|
2172
|
+
name: z9.string().min(1),
|
|
2173
|
+
slug: z9.string().min(1),
|
|
2174
|
+
description: z9.string().nullable(),
|
|
2175
|
+
memberCount: z9.number().nullable(),
|
|
2176
|
+
url: z9.string().min(1)
|
|
2177
|
+
});
|
|
2178
|
+
var groupDetailEntitySchema = z9.object({
|
|
2179
|
+
name: z9.string().min(1),
|
|
2180
|
+
slug: z9.string().min(1),
|
|
2181
|
+
description: z9.string().nullable(),
|
|
2182
|
+
url: z9.string().min(1),
|
|
2183
|
+
members: z9.array(
|
|
2184
|
+
z9.object({
|
|
2185
|
+
name: z9.string(),
|
|
2186
|
+
email: z9.string(),
|
|
2187
|
+
profilePictureUrl: z9.string().nullable()
|
|
2188
|
+
})
|
|
2189
|
+
)
|
|
2190
|
+
});
|
|
2191
|
+
var statusEntityRowSchema = z9.object({
|
|
2192
|
+
id: z9.string().min(1),
|
|
2193
|
+
name: z9.string().min(1),
|
|
2194
|
+
status: z9.string().min(1),
|
|
2195
|
+
url: z9.string().min(1),
|
|
2196
|
+
type: z9.string().nullable().optional(),
|
|
2197
|
+
description: z9.string().nullable().optional()
|
|
2198
|
+
});
|
|
2199
|
+
var agentAdminErrorResultSchema = z9.object({
|
|
2200
|
+
ok: z9.literal(false),
|
|
2201
|
+
status: z9.number().optional(),
|
|
2202
|
+
message: z9.string(),
|
|
2203
|
+
response: z9.unknown().optional()
|
|
2204
|
+
});
|
|
2205
|
+
var agentAdminMutationResultSchema = z9.object({
|
|
2206
|
+
...agentOnlyFields
|
|
2207
|
+
}).passthrough();
|
|
2208
|
+
var searchProductsOutputSchema = withAgentOnlyFields({
|
|
2209
|
+
items: z9.array(productEntityRowSchema)
|
|
2210
|
+
});
|
|
2211
|
+
var generateRandomChartOutputSchema = withAgentOnlyFields({
|
|
2212
|
+
title: z9.string().min(1),
|
|
2213
|
+
axis: z9.enum(["time", "category"]),
|
|
2214
|
+
series: z9.array(metricPointEntityRowSchema)
|
|
2215
|
+
});
|
|
2216
|
+
var generateImageOutputSchema = withAgentOnlyFields({
|
|
2217
|
+
prompt: z9.string().min(1),
|
|
2218
|
+
mediaType: z9.string().min(1),
|
|
2219
|
+
model: z9.string().min(1),
|
|
2220
|
+
storageId: z9.string().min(1),
|
|
2221
|
+
url: z9.string().min(1),
|
|
2222
|
+
/** @deprecated Legacy sessions only — prefer storageId/url. */
|
|
2223
|
+
base64: z9.string().min(1).optional()
|
|
2224
|
+
});
|
|
2225
|
+
var manageTeamMembersListOutputSchema = withAgentOnlyFields({
|
|
2226
|
+
members: z9.array(memberEntityRowSchema)
|
|
2227
|
+
});
|
|
2228
|
+
var manageTeamMembersDetailOutputSchema = withAgentOnlyFields(
|
|
2229
|
+
memberEntityRowSchema.shape
|
|
2230
|
+
);
|
|
2231
|
+
var manageTeamMembersOutputSchema = z9.union([
|
|
2232
|
+
manageTeamMembersListOutputSchema,
|
|
2233
|
+
manageTeamMembersDetailOutputSchema,
|
|
2234
|
+
agentAdminMutationResultSchema,
|
|
2235
|
+
agentAdminErrorResultSchema
|
|
2236
|
+
]);
|
|
2237
|
+
var manageGroupsListOutputSchema = withAgentOnlyFields({
|
|
2238
|
+
groups: z9.array(groupEntityRowSchema)
|
|
2239
|
+
});
|
|
2240
|
+
var manageGroupsDetailOutputSchema = withAgentOnlyFields(
|
|
2241
|
+
groupDetailEntitySchema.shape
|
|
2242
|
+
);
|
|
2243
|
+
var manageGroupsSummaryOutputSchema = withAgentOnlyFields(
|
|
2244
|
+
groupEntityRowSchema.shape
|
|
2245
|
+
);
|
|
2246
|
+
var manageGroupsOutputSchema = z9.union([
|
|
2247
|
+
manageGroupsListOutputSchema,
|
|
2248
|
+
manageGroupsDetailOutputSchema,
|
|
2249
|
+
manageGroupsSummaryOutputSchema,
|
|
2250
|
+
agentAdminMutationResultSchema,
|
|
2251
|
+
agentAdminErrorResultSchema
|
|
2252
|
+
]);
|
|
2253
|
+
var queryTasksListOutputSchema = withAgentOnlyFields({
|
|
2254
|
+
items: z9.array(taskEntityRowSchema),
|
|
2255
|
+
nextCursor: z9.string().nullable().optional()
|
|
2256
|
+
});
|
|
2257
|
+
var queryTasksDetailOutputSchema = withAgentOnlyFields({
|
|
2258
|
+
id: z9.string().nullable(),
|
|
2259
|
+
status: z9.string().nullable(),
|
|
2260
|
+
type: z9.string().nullable(),
|
|
2261
|
+
name: z9.string().nullable(),
|
|
2262
|
+
description: z9.string().nullable(),
|
|
2263
|
+
validUntil: z9.number().nullable(),
|
|
2264
|
+
createdAt: z9.number().nullable(),
|
|
2265
|
+
url: z9.string().min(1).nullable()
|
|
2266
|
+
});
|
|
2267
|
+
var queryTasksOutputSchema = z9.union([
|
|
2268
|
+
queryTasksListOutputSchema,
|
|
2269
|
+
queryTasksDetailOutputSchema,
|
|
2270
|
+
agentAdminErrorResultSchema
|
|
2271
|
+
]);
|
|
2272
|
+
var assignTasksOutputSchema = z9.union([
|
|
2273
|
+
withAgentOnlyFields({
|
|
2274
|
+
results: z9.array(statusEntityRowSchema)
|
|
2275
|
+
}),
|
|
2276
|
+
agentAdminErrorResultSchema
|
|
2277
|
+
]);
|
|
2278
|
+
var workspaceUsageEntitySchema = z9.object({
|
|
2279
|
+
workspace: z9.string(),
|
|
2280
|
+
plan: z9.string(),
|
|
2281
|
+
planType: z9.string(),
|
|
2282
|
+
trialState: z9.string(),
|
|
2283
|
+
daysRemaining: z9.number().nullable(),
|
|
2284
|
+
isPaidPro: z9.boolean(),
|
|
2285
|
+
subscriptionStatus: z9.string(),
|
|
2286
|
+
tasksToday: z9.string(),
|
|
2287
|
+
tasksResetAt: z9.string(),
|
|
2288
|
+
openTasks: z9.number(),
|
|
2289
|
+
totalTasks: z9.number(),
|
|
2290
|
+
seats: z9.string(),
|
|
2291
|
+
groups: z9.string(),
|
|
2292
|
+
apiKeys: z9.string(),
|
|
2293
|
+
rateLimitPerSecond: z9.number()
|
|
2294
|
+
});
|
|
2295
|
+
var getWorkspaceUsageOutputSchema = z9.union([
|
|
2296
|
+
withAgentOnlyFields({
|
|
2297
|
+
usage: workspaceUsageEntitySchema
|
|
2298
|
+
}),
|
|
2299
|
+
agentAdminErrorResultSchema
|
|
2300
|
+
]);
|
|
2301
|
+
|
|
2302
|
+
// src/eve/tools/catalog/search-products.ts
|
|
1955
2303
|
var SEARCH_PRODUCTS_TOOL_NAME = "search_products";
|
|
1956
|
-
var searchProductsInputSchema =
|
|
1957
|
-
query:
|
|
2304
|
+
var searchProductsInputSchema = z10.object({
|
|
2305
|
+
query: z10.string().min(1).describe("Product name or SKU to search for.")
|
|
1958
2306
|
});
|
|
1959
2307
|
var DEMO_PRODUCTS = [
|
|
1960
2308
|
{
|
|
@@ -1962,38 +2310,348 @@ var DEMO_PRODUCTS = [
|
|
|
1962
2310
|
name: "Wireless Keyboard",
|
|
1963
2311
|
price: 79.99,
|
|
1964
2312
|
currency: "USD",
|
|
1965
|
-
inStock: true
|
|
2313
|
+
inStock: true,
|
|
2314
|
+
url: "https://shop.example.com/products/sku-1001"
|
|
1966
2315
|
},
|
|
1967
2316
|
{
|
|
1968
2317
|
id: "sku-2042",
|
|
1969
2318
|
name: "USB-C Hub",
|
|
1970
2319
|
price: 45.99,
|
|
1971
2320
|
currency: "USD",
|
|
1972
|
-
inStock: true
|
|
2321
|
+
inStock: true,
|
|
2322
|
+
url: "https://shop.example.com/products/sku-2042"
|
|
1973
2323
|
},
|
|
1974
2324
|
{
|
|
1975
2325
|
id: "sku-3308",
|
|
1976
2326
|
name: "Monitor Stand",
|
|
1977
2327
|
price: 129.99,
|
|
1978
2328
|
currency: "USD",
|
|
1979
|
-
inStock: false
|
|
2329
|
+
inStock: false,
|
|
2330
|
+
url: "https://shop.example.com/products/sku-3308"
|
|
1980
2331
|
}
|
|
1981
2332
|
];
|
|
1982
2333
|
function defineSearchProductsTool() {
|
|
1983
2334
|
return defineTool4({
|
|
1984
2335
|
description: "Search the product catalog and return matching items. Results render in chat UI \u2014 do not restate product names, prices, or SKUs in your reply.",
|
|
1985
2336
|
inputSchema: searchProductsInputSchema,
|
|
2337
|
+
outputSchema: searchProductsOutputSchema,
|
|
1986
2338
|
async execute({ query }) {
|
|
1987
2339
|
const normalized = query.trim().toLowerCase();
|
|
1988
2340
|
const items = DEMO_PRODUCTS.filter(
|
|
1989
2341
|
(product) => product.name.toLowerCase().includes(normalized) || product.id.toLowerCase().includes(normalized)
|
|
1990
2342
|
);
|
|
1991
|
-
return
|
|
2343
|
+
return formatToolListResult(
|
|
2344
|
+
"items",
|
|
2345
|
+
items.map((product) => ({ ...product })),
|
|
2346
|
+
{
|
|
2347
|
+
replyGuidance: SEARCH_PRODUCTS_REPLY_GUIDANCE,
|
|
2348
|
+
entity: "product"
|
|
2349
|
+
}
|
|
2350
|
+
);
|
|
1992
2351
|
}
|
|
1993
2352
|
});
|
|
1994
2353
|
}
|
|
1995
2354
|
var searchProductsTool = defineSearchProductsTool();
|
|
1996
2355
|
|
|
2356
|
+
// src/eve/tools/catalog/generate-random-chart.ts
|
|
2357
|
+
import { defineTool as defineTool5 } from "eve/tools";
|
|
2358
|
+
import { z as z11 } from "zod";
|
|
2359
|
+
var GENERATE_RANDOM_CHART_TOOL_NAME = "generate_random_chart";
|
|
2360
|
+
var generateRandomChartInputSchema = z11.object({
|
|
2361
|
+
axis: z11.enum(["time", "category", "random"]).optional().describe(
|
|
2362
|
+
"X-axis style: time (line), category (bar), or random. Defaults to random."
|
|
2363
|
+
),
|
|
2364
|
+
seriesCount: z11.number().int().min(1).max(3).optional().describe("Number of numeric series (1\u20133). Defaults to a random 1\u20132."),
|
|
2365
|
+
pointCount: z11.number().int().min(4).max(30).optional().describe("Number of data points (4\u201330). Defaults to a random 8\u201314."),
|
|
2366
|
+
seed: z11.number().int().optional().describe("Optional seed for reproducible random data.")
|
|
2367
|
+
});
|
|
2368
|
+
function createRng(seed) {
|
|
2369
|
+
let state = seed === void 0 ? (Math.floor(Math.random() * 2147483647) ^ Date.now()) >>> 0 : seed >>> 0;
|
|
2370
|
+
if (state === 0) {
|
|
2371
|
+
state = 1;
|
|
2372
|
+
}
|
|
2373
|
+
return () => {
|
|
2374
|
+
state ^= state << 13;
|
|
2375
|
+
state ^= state >>> 17;
|
|
2376
|
+
state ^= state << 5;
|
|
2377
|
+
return (state >>> 0) / 4294967296;
|
|
2378
|
+
};
|
|
2379
|
+
}
|
|
2380
|
+
function pick(rng, items) {
|
|
2381
|
+
return items[Math.floor(rng() * items.length)];
|
|
2382
|
+
}
|
|
2383
|
+
function randomInt(rng, min, max) {
|
|
2384
|
+
return min + Math.floor(rng() * (max - min + 1));
|
|
2385
|
+
}
|
|
2386
|
+
function roundMetric(value) {
|
|
2387
|
+
return Math.round(value * 10) / 10;
|
|
2388
|
+
}
|
|
2389
|
+
var TIME_TITLES = [
|
|
2390
|
+
"Task throughput",
|
|
2391
|
+
"Approvals over time",
|
|
2392
|
+
"Inbox volume",
|
|
2393
|
+
"Agent tool calls",
|
|
2394
|
+
"Webhook deliveries"
|
|
2395
|
+
];
|
|
2396
|
+
var CATEGORY_TITLES = [
|
|
2397
|
+
"Tasks by status",
|
|
2398
|
+
"Approvals by team",
|
|
2399
|
+
"Volume by region",
|
|
2400
|
+
"Spend by category",
|
|
2401
|
+
"Tickets by priority"
|
|
2402
|
+
];
|
|
2403
|
+
var TIME_SERIES_KEYS = [
|
|
2404
|
+
["value"],
|
|
2405
|
+
["created", "handled"],
|
|
2406
|
+
["open", "handled", "expired"]
|
|
2407
|
+
];
|
|
2408
|
+
var CATEGORY_SERIES_KEYS = [
|
|
2409
|
+
["value"],
|
|
2410
|
+
["revenue", "costs"],
|
|
2411
|
+
["approved", "rejected", "pending"]
|
|
2412
|
+
];
|
|
2413
|
+
var CATEGORIES = [
|
|
2414
|
+
["North", "South", "East", "West", "Central"],
|
|
2415
|
+
["Finance", "Ops", "Support", "Engineering", "Sales"],
|
|
2416
|
+
["P0", "P1", "P2", "P3", "P4"],
|
|
2417
|
+
["Draft", "Open", "Handled", "Expired", "Cancelled"]
|
|
2418
|
+
];
|
|
2419
|
+
function formatDate(daysAgo) {
|
|
2420
|
+
const date = /* @__PURE__ */ new Date();
|
|
2421
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
2422
|
+
date.setUTCDate(date.getUTCDate() - daysAgo);
|
|
2423
|
+
return date.toISOString().slice(0, 10);
|
|
2424
|
+
}
|
|
2425
|
+
function buildSeriesPoints(args) {
|
|
2426
|
+
const { rng, axis, seriesKeys, pointCount } = args;
|
|
2427
|
+
const baselines = seriesKeys.map(() => 20 + rng() * 80);
|
|
2428
|
+
if (axis === "time") {
|
|
2429
|
+
return Array.from({ length: pointCount }, (_, index) => {
|
|
2430
|
+
const point = {
|
|
2431
|
+
date: formatDate(pointCount - 1 - index)
|
|
2432
|
+
};
|
|
2433
|
+
for (let i = 0; i < seriesKeys.length; i++) {
|
|
2434
|
+
const drift = (rng() - 0.45) * 12;
|
|
2435
|
+
baselines[i] = Math.max(1, baselines[i] + drift);
|
|
2436
|
+
point[seriesKeys[i]] = roundMetric(baselines[i]);
|
|
2437
|
+
}
|
|
2438
|
+
return point;
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
const labels = pick(rng, CATEGORIES).slice(0, pointCount);
|
|
2442
|
+
return labels.map((label) => {
|
|
2443
|
+
const point = { category: label };
|
|
2444
|
+
for (let i = 0; i < seriesKeys.length; i++) {
|
|
2445
|
+
point[seriesKeys[i]] = roundMetric(8 + rng() * 120);
|
|
2446
|
+
}
|
|
2447
|
+
return point;
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
function buildRandomChartData(input = {}) {
|
|
2451
|
+
const rng = createRng(input.seed);
|
|
2452
|
+
const axis = input.axis === "time" || input.axis === "category" ? input.axis : pick(rng, ["time", "category"]);
|
|
2453
|
+
const seriesCount = input.seriesCount ?? randomInt(rng, 1, 2);
|
|
2454
|
+
const pointCount = input.pointCount ?? (axis === "time" ? randomInt(rng, 8, 14) : randomInt(rng, 4, 6));
|
|
2455
|
+
const keyPool = axis === "time" ? TIME_SERIES_KEYS : CATEGORY_SERIES_KEYS;
|
|
2456
|
+
const seriesKeys = keyPool.find((keys) => keys.length === seriesCount) ?? keyPool[0];
|
|
2457
|
+
const title = pick(rng, axis === "time" ? TIME_TITLES : CATEGORY_TITLES);
|
|
2458
|
+
const series = buildSeriesPoints({
|
|
2459
|
+
rng,
|
|
2460
|
+
axis,
|
|
2461
|
+
seriesKeys,
|
|
2462
|
+
pointCount
|
|
2463
|
+
});
|
|
2464
|
+
return { title, axis, series };
|
|
2465
|
+
}
|
|
2466
|
+
function defineGenerateRandomChartTool() {
|
|
2467
|
+
return defineTool5({
|
|
2468
|
+
description: "Generate random chart-ready demo metrics for testing chat chart UI. Results render as a chart card \u2014 do not restate series values in your reply.",
|
|
2469
|
+
inputSchema: generateRandomChartInputSchema,
|
|
2470
|
+
outputSchema: generateRandomChartOutputSchema,
|
|
2471
|
+
async execute(input) {
|
|
2472
|
+
const data = buildRandomChartData(input);
|
|
2473
|
+
return formatToolObjectResult(data, {
|
|
2474
|
+
replyGuidance: GENERATE_RANDOM_CHART_REPLY_GUIDANCE,
|
|
2475
|
+
uiHint: "chart",
|
|
2476
|
+
ui: {
|
|
2477
|
+
layout: "chart",
|
|
2478
|
+
rowsPath: "series",
|
|
2479
|
+
entity: "metric_point",
|
|
2480
|
+
present: true
|
|
2481
|
+
}
|
|
2482
|
+
});
|
|
2483
|
+
}
|
|
2484
|
+
});
|
|
2485
|
+
}
|
|
2486
|
+
var generateRandomChartTool = defineGenerateRandomChartTool();
|
|
2487
|
+
|
|
2488
|
+
// src/eve/tools/catalog/generate-image.ts
|
|
2489
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
2490
|
+
import { createGateway, generateImage } from "ai";
|
|
2491
|
+
import { defineTool as defineTool6 } from "eve/tools";
|
|
2492
|
+
import { z as z12 } from "zod";
|
|
2493
|
+
var GENERATE_IMAGE_TOOL_NAME = "generate_image";
|
|
2494
|
+
var DEFAULT_IMAGE_MODEL = "black-forest-labs/flux.2-klein-4b";
|
|
2495
|
+
var DEFAULT_IMAGE_SIZE = "512";
|
|
2496
|
+
var DEFAULT_IMAGE_ASPECT_RATIO = "1:1";
|
|
2497
|
+
var generateImageInputSchema = z12.object({
|
|
2498
|
+
prompt: z12.string().min(1).describe("Detailed description of the image to generate")
|
|
2499
|
+
});
|
|
2500
|
+
function normalizeEnvValue(value) {
|
|
2501
|
+
if (!value) {
|
|
2502
|
+
return void 0;
|
|
2503
|
+
}
|
|
2504
|
+
return value.replace(/^["']|["']$/g, "");
|
|
2505
|
+
}
|
|
2506
|
+
function isJwtExpired(token, bufferSeconds = 60) {
|
|
2507
|
+
try {
|
|
2508
|
+
const payload = JSON.parse(
|
|
2509
|
+
Buffer.from(token.split(".")[1] ?? "", "base64url").toString("utf8")
|
|
2510
|
+
);
|
|
2511
|
+
return typeof payload.exp !== "number" || Date.now() / 1e3 >= payload.exp - bufferSeconds;
|
|
2512
|
+
} catch {
|
|
2513
|
+
return true;
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
function resolveAiImageModel(modelId = normalizeEnvValue(process.env.AI_IMAGE_MODEL) ?? DEFAULT_IMAGE_MODEL) {
|
|
2517
|
+
const openRouterKey = normalizeEnvValue(process.env.OPENROUTER_API_KEY);
|
|
2518
|
+
if (openRouterKey) {
|
|
2519
|
+
const openrouter = createOpenRouter({ apiKey: openRouterKey });
|
|
2520
|
+
return {
|
|
2521
|
+
provider: "openrouter",
|
|
2522
|
+
model: openrouter.imageModel(modelId),
|
|
2523
|
+
modelId
|
|
2524
|
+
};
|
|
2525
|
+
}
|
|
2526
|
+
const gatewayKey = normalizeEnvValue(process.env.AI_GATEWAY_API_KEY);
|
|
2527
|
+
if (gatewayKey) {
|
|
2528
|
+
const gateway2 = createGateway({ apiKey: gatewayKey });
|
|
2529
|
+
return {
|
|
2530
|
+
provider: "ai-gateway-api-key",
|
|
2531
|
+
model: gateway2.imageModel(modelId),
|
|
2532
|
+
modelId
|
|
2533
|
+
};
|
|
2534
|
+
}
|
|
2535
|
+
const oidcToken = normalizeEnvValue(process.env.VERCEL_OIDC_TOKEN);
|
|
2536
|
+
if (!oidcToken) {
|
|
2537
|
+
throw new Error(
|
|
2538
|
+
`No AI provider credentials for image model "${modelId}". Set OPENROUTER_API_KEY (preferred), or AI_GATEWAY_API_KEY / VERCEL_OIDC_TOKEN.`
|
|
2539
|
+
);
|
|
2540
|
+
}
|
|
2541
|
+
if (isJwtExpired(oidcToken)) {
|
|
2542
|
+
throw new Error(
|
|
2543
|
+
"VERCEL_OIDC_TOKEN is expired. Set OPENROUTER_API_KEY instead, or refresh the OIDC token."
|
|
2544
|
+
);
|
|
2545
|
+
}
|
|
2546
|
+
process.env.VERCEL_OIDC_TOKEN = oidcToken;
|
|
2547
|
+
const gateway = createGateway();
|
|
2548
|
+
return {
|
|
2549
|
+
provider: "ai-gateway-oidc",
|
|
2550
|
+
model: gateway.imageModel(modelId),
|
|
2551
|
+
modelId
|
|
2552
|
+
};
|
|
2553
|
+
}
|
|
2554
|
+
function resolveAiImageSize() {
|
|
2555
|
+
return normalizeEnvValue(process.env.AI_IMAGE_SIZE) ?? DEFAULT_IMAGE_SIZE;
|
|
2556
|
+
}
|
|
2557
|
+
function resolveAiImageAspectRatio() {
|
|
2558
|
+
return normalizeEnvValue(process.env.AI_IMAGE_ASPECT_RATIO) ?? DEFAULT_IMAGE_ASPECT_RATIO;
|
|
2559
|
+
}
|
|
2560
|
+
function extensionForMediaType(mediaType) {
|
|
2561
|
+
const normalized = mediaType.toLowerCase();
|
|
2562
|
+
if (normalized.includes("jpeg") || normalized.includes("jpg")) return "jpg";
|
|
2563
|
+
if (normalized.includes("webp")) return "webp";
|
|
2564
|
+
if (normalized.includes("gif")) return "gif";
|
|
2565
|
+
return "png";
|
|
2566
|
+
}
|
|
2567
|
+
function filenameFromImagePrompt(prompt, mediaType) {
|
|
2568
|
+
const slug = prompt.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48);
|
|
2569
|
+
return `${slug || "generated-image"}.${extensionForMediaType(mediaType)}`;
|
|
2570
|
+
}
|
|
2571
|
+
async function generateImageBytes(input, options) {
|
|
2572
|
+
const { model, modelId } = resolveAiImageModel();
|
|
2573
|
+
const size = resolveAiImageSize();
|
|
2574
|
+
const aspectRatio = resolveAiImageAspectRatio();
|
|
2575
|
+
try {
|
|
2576
|
+
const { image } = await generateImage({
|
|
2577
|
+
model,
|
|
2578
|
+
prompt: input.prompt,
|
|
2579
|
+
aspectRatio,
|
|
2580
|
+
abortSignal: options?.abortSignal,
|
|
2581
|
+
size
|
|
2582
|
+
});
|
|
2583
|
+
if (!image.base64) {
|
|
2584
|
+
throw new Error(`Image model "${modelId}" returned no image data.`);
|
|
2585
|
+
}
|
|
2586
|
+
return {
|
|
2587
|
+
prompt: input.prompt,
|
|
2588
|
+
mediaType: image.mediaType || "image/png",
|
|
2589
|
+
model: modelId,
|
|
2590
|
+
base64: image.base64
|
|
2591
|
+
};
|
|
2592
|
+
} catch (error) {
|
|
2593
|
+
const message = error instanceof Error ? error.message : "Image generation failed.";
|
|
2594
|
+
throw new Error(`Image generation failed (${modelId}): ${message}`);
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
function defineGenerateImageTool() {
|
|
2598
|
+
return defineTool6({
|
|
2599
|
+
description: "Generate an image from a text prompt using a cheap/fast image model. Use when the user asks to draw, create, or generate a picture or illustration. The image renders in chat UI \u2014 do not describe the pixels in your reply.",
|
|
2600
|
+
inputSchema: generateImageInputSchema,
|
|
2601
|
+
outputSchema: generateImageOutputSchema,
|
|
2602
|
+
toModelOutput(output) {
|
|
2603
|
+
return {
|
|
2604
|
+
type: "text",
|
|
2605
|
+
value: `Generated an image for: "${output.prompt}" (model: ${output.model}).`
|
|
2606
|
+
};
|
|
2607
|
+
},
|
|
2608
|
+
async execute(input, ctx) {
|
|
2609
|
+
const caller = tryResolveTenantCaller(ctx);
|
|
2610
|
+
const chatId = caller?.chatId?.trim();
|
|
2611
|
+
if (!chatId) {
|
|
2612
|
+
throw new Error(
|
|
2613
|
+
"generate_image requires a dashboard chat session (missing chatId)."
|
|
2614
|
+
);
|
|
2615
|
+
}
|
|
2616
|
+
const client = tryCreateBoundRobotRockClient(ctx);
|
|
2617
|
+
if (!client) {
|
|
2618
|
+
throw new Error(
|
|
2619
|
+
"RobotRock auth is unset. Configure ROBOTROCK_AGENT_SERVICE_TOKEN for hosted agents or ROBOTROCK_API_KEY for self-hosted deployments."
|
|
2620
|
+
);
|
|
2621
|
+
}
|
|
2622
|
+
const generated = await generateImageBytes(input, {
|
|
2623
|
+
abortSignal: ctx?.abortSignal
|
|
2624
|
+
});
|
|
2625
|
+
const uploaded = await client.chats.uploadImage({
|
|
2626
|
+
mediaType: generated.mediaType,
|
|
2627
|
+
base64: generated.base64,
|
|
2628
|
+
chatId,
|
|
2629
|
+
source: GENERATE_IMAGE_TOOL_NAME,
|
|
2630
|
+
filename: filenameFromImagePrompt(generated.prompt, generated.mediaType),
|
|
2631
|
+
description: generated.prompt,
|
|
2632
|
+
tags: [GENERATE_IMAGE_TOOL_NAME]
|
|
2633
|
+
});
|
|
2634
|
+
return formatToolObjectResult(
|
|
2635
|
+
{
|
|
2636
|
+
prompt: generated.prompt,
|
|
2637
|
+
mediaType: uploaded.mediaType || generated.mediaType,
|
|
2638
|
+
model: generated.model,
|
|
2639
|
+
storageId: uploaded.storageId,
|
|
2640
|
+
url: uploaded.url
|
|
2641
|
+
},
|
|
2642
|
+
{
|
|
2643
|
+
replyGuidance: GENERATE_IMAGE_REPLY_GUIDANCE,
|
|
2644
|
+
ui: {
|
|
2645
|
+
present: true,
|
|
2646
|
+
entity: "generated_image"
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
);
|
|
2650
|
+
}
|
|
2651
|
+
});
|
|
2652
|
+
}
|
|
2653
|
+
var generateImageTool = defineGenerateImageTool();
|
|
2654
|
+
|
|
1997
2655
|
// src/agent-admin.ts
|
|
1998
2656
|
async function agentAdminFetch(config, path, init) {
|
|
1999
2657
|
const baseUrl = (config.baseUrl?.trim() || getRobotRockApiBaseUrl()).replace(
|
|
@@ -2022,6 +2680,9 @@ async function agentAdminFetch(config, path, init) {
|
|
|
2022
2680
|
}
|
|
2023
2681
|
function createAgentAdminApi(config) {
|
|
2024
2682
|
return {
|
|
2683
|
+
usage: {
|
|
2684
|
+
get: () => agentAdminFetch(config, "/usage")
|
|
2685
|
+
},
|
|
2025
2686
|
members: {
|
|
2026
2687
|
list: () => agentAdminFetch(config, "/members"),
|
|
2027
2688
|
get: (memberRef) => agentAdminFetch(config, `/members/${encodeURIComponent(memberRef)}`),
|
|
@@ -2170,7 +2831,8 @@ function serializeMemberRow(member) {
|
|
|
2170
2831
|
name: member.user.name,
|
|
2171
2832
|
email: member.user.email,
|
|
2172
2833
|
role: member.role,
|
|
2173
|
-
membershipKind: member.membershipKind
|
|
2834
|
+
membershipKind: member.membershipKind,
|
|
2835
|
+
profilePictureUrl: member.user.profilePictureUrl ?? null
|
|
2174
2836
|
};
|
|
2175
2837
|
}
|
|
2176
2838
|
function formatTeamMembersListResult(members) {
|
|
@@ -2178,29 +2840,31 @@ function formatTeamMembersListResult(members) {
|
|
|
2178
2840
|
"members",
|
|
2179
2841
|
members.map(serializeMemberRow),
|
|
2180
2842
|
{
|
|
2181
|
-
replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE
|
|
2843
|
+
replyGuidance: MANAGE_TEAM_MEMBERS_LIST_REPLY_GUIDANCE,
|
|
2844
|
+
entity: "member"
|
|
2182
2845
|
}
|
|
2183
2846
|
);
|
|
2184
2847
|
}
|
|
2185
2848
|
function formatTeamMemberDetailResult(member) {
|
|
2186
2849
|
return formatToolObjectResult(serializeMemberRow(member), {
|
|
2187
|
-
replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE
|
|
2850
|
+
replyGuidance: MANAGE_TEAM_MEMBERS_DETAIL_REPLY_GUIDANCE,
|
|
2851
|
+
ui: { entity: "member" }
|
|
2188
2852
|
});
|
|
2189
2853
|
}
|
|
2190
2854
|
|
|
2191
2855
|
// src/eve/tools/admin/manage-team-members.ts
|
|
2192
|
-
import { defineTool as
|
|
2193
|
-
import { z as
|
|
2856
|
+
import { defineTool as defineTool7 } from "eve/tools";
|
|
2857
|
+
import { z as z13 } from "zod";
|
|
2194
2858
|
var MANAGE_TEAM_MEMBERS_TOOL_NAME = "manage_team_members";
|
|
2195
|
-
var manageTeamMembersInputSchema =
|
|
2196
|
-
action:
|
|
2197
|
-
userId:
|
|
2859
|
+
var manageTeamMembersInputSchema = z13.object({
|
|
2860
|
+
action: z13.enum(["list", "get", "invite", "update_role", "remove"]),
|
|
2861
|
+
userId: z13.string().min(1).optional().describe(
|
|
2198
2862
|
"Convex users table id for get, update_role, and remove. Prefer email when the member list only shows email."
|
|
2199
2863
|
),
|
|
2200
|
-
email:
|
|
2864
|
+
email: z13.string().email().optional().describe(
|
|
2201
2865
|
"Member email for get, update_role, and remove; invitee email for invite."
|
|
2202
2866
|
),
|
|
2203
|
-
role:
|
|
2867
|
+
role: z13.enum(["admin", "member"]).optional().describe("Role for invite and update_role.")
|
|
2204
2868
|
}).superRefine((input, ctx) => {
|
|
2205
2869
|
const requireField = (field, message) => {
|
|
2206
2870
|
if (!input[field]) {
|
|
@@ -2241,9 +2905,10 @@ function formatMemberMutationResult(payload) {
|
|
|
2241
2905
|
});
|
|
2242
2906
|
}
|
|
2243
2907
|
function defineManageTeamMembersTool() {
|
|
2244
|
-
return
|
|
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
|
|
2908
|
+
return defineTool7({
|
|
2909
|
+
description: "Tenant-admin tool for workspace team members: list, get, invite, change role, or remove. Requires tenant admin access. Call get_my_access in the same turn before this tool to verify admin access (the check stays a compact success marker unless it is the only presentable result). Use member email from list results for get, update_role, and remove \u2014 internal ids are optional. Results render as chat UI cards \u2014 do not restate member names, emails, or roles in your reply.",
|
|
2246
2910
|
inputSchema: manageTeamMembersInputSchema,
|
|
2911
|
+
outputSchema: manageTeamMembersOutputSchema,
|
|
2247
2912
|
async execute(input, ctx) {
|
|
2248
2913
|
const api = requireBoundAgentAdminClient(ctx);
|
|
2249
2914
|
try {
|
|
@@ -2306,53 +2971,59 @@ function defineManageTeamMembersTool() {
|
|
|
2306
2971
|
var manageTeamMembersTool = defineManageTeamMembersTool();
|
|
2307
2972
|
|
|
2308
2973
|
// src/eve/tools/admin/manage-groups.ts
|
|
2309
|
-
import { defineTool as
|
|
2310
|
-
import { z as
|
|
2974
|
+
import { defineTool as defineTool8 } from "eve/tools";
|
|
2975
|
+
import { z as z14 } from "zod";
|
|
2311
2976
|
|
|
2312
2977
|
// src/eve/tools/admin/format-groups-list.ts
|
|
2313
|
-
function serializeGroupRow(group) {
|
|
2978
|
+
function serializeGroupRow(group, tenantSlug) {
|
|
2314
2979
|
return {
|
|
2315
2980
|
name: group.name,
|
|
2316
2981
|
slug: group.slug,
|
|
2317
2982
|
description: group.description,
|
|
2318
|
-
memberCount: group.memberCount ?? null
|
|
2983
|
+
memberCount: group.memberCount ?? null,
|
|
2984
|
+
url: buildTenantGroupUrl(tenantSlug, group.slug)
|
|
2319
2985
|
};
|
|
2320
2986
|
}
|
|
2321
|
-
function formatGroupsListResult(groups) {
|
|
2987
|
+
function formatGroupsListResult(groups, options) {
|
|
2322
2988
|
return formatToolListResult(
|
|
2323
2989
|
"groups",
|
|
2324
|
-
groups.map(serializeGroupRow),
|
|
2990
|
+
groups.map((group) => serializeGroupRow(group, options.tenantSlug)),
|
|
2325
2991
|
{
|
|
2326
|
-
replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE
|
|
2992
|
+
replyGuidance: MANAGE_GROUPS_LIST_REPLY_GUIDANCE,
|
|
2993
|
+
entity: "group"
|
|
2327
2994
|
}
|
|
2328
2995
|
);
|
|
2329
2996
|
}
|
|
2330
|
-
function formatGroupDetailResult(group) {
|
|
2997
|
+
function formatGroupDetailResult(group, options) {
|
|
2331
2998
|
return formatToolObjectResult(
|
|
2332
2999
|
{
|
|
2333
3000
|
name: group.name,
|
|
2334
3001
|
slug: group.slug,
|
|
2335
3002
|
description: group.description,
|
|
3003
|
+
url: buildTenantGroupUrl(options.tenantSlug, group.slug),
|
|
2336
3004
|
members: group.members.map((member) => ({
|
|
2337
3005
|
name: member.user.name,
|
|
2338
|
-
email: member.user.email
|
|
3006
|
+
email: member.user.email,
|
|
3007
|
+
profilePictureUrl: member.user.profilePictureUrl ?? null
|
|
2339
3008
|
}))
|
|
2340
3009
|
},
|
|
2341
3010
|
{
|
|
2342
|
-
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
|
|
3011
|
+
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
|
|
3012
|
+
ui: { entity: "group" }
|
|
2343
3013
|
}
|
|
2344
3014
|
);
|
|
2345
3015
|
}
|
|
2346
|
-
function formatGroupSummaryResult(group) {
|
|
2347
|
-
return formatToolObjectResult(serializeGroupRow(group), {
|
|
2348
|
-
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE
|
|
3016
|
+
function formatGroupSummaryResult(group, options) {
|
|
3017
|
+
return formatToolObjectResult(serializeGroupRow(group, options.tenantSlug), {
|
|
3018
|
+
replyGuidance: MANAGE_GROUPS_DETAIL_REPLY_GUIDANCE,
|
|
3019
|
+
ui: { entity: "group" }
|
|
2349
3020
|
});
|
|
2350
3021
|
}
|
|
2351
3022
|
|
|
2352
3023
|
// src/eve/tools/admin/manage-groups.ts
|
|
2353
3024
|
var MANAGE_GROUPS_TOOL_NAME = "manage_groups";
|
|
2354
|
-
var manageGroupsInputSchema =
|
|
2355
|
-
action:
|
|
3025
|
+
var manageGroupsInputSchema = z14.object({
|
|
3026
|
+
action: z14.enum([
|
|
2356
3027
|
"list",
|
|
2357
3028
|
"get",
|
|
2358
3029
|
"create",
|
|
@@ -2361,18 +3032,18 @@ var manageGroupsInputSchema = z11.object({
|
|
|
2361
3032
|
"add_member",
|
|
2362
3033
|
"remove_member"
|
|
2363
3034
|
]),
|
|
2364
|
-
groupId:
|
|
3035
|
+
groupId: z14.string().min(1).optional().describe(
|
|
2365
3036
|
"Convex group id for get, update, delete, and membership actions. Prefer slug when the group list only shows slug."
|
|
2366
3037
|
),
|
|
2367
|
-
slug:
|
|
3038
|
+
slug: z14.string().min(1).optional().describe(
|
|
2368
3039
|
"Group slug (e.g. finance) for get, update, delete, and membership actions."
|
|
2369
3040
|
),
|
|
2370
|
-
userId:
|
|
3041
|
+
userId: z14.string().min(1).optional().describe(
|
|
2371
3042
|
"User id for add_member and remove_member. Prefer email when the member list only shows email."
|
|
2372
3043
|
),
|
|
2373
|
-
email:
|
|
2374
|
-
name:
|
|
2375
|
-
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.")
|
|
2376
3047
|
}).superRefine((input, ctx) => {
|
|
2377
3048
|
const requireField = (field, message) => {
|
|
2378
3049
|
if (!input[field]) {
|
|
@@ -2425,34 +3096,46 @@ function resolveMemberRef2(input) {
|
|
|
2425
3096
|
return input.userId ?? input.email;
|
|
2426
3097
|
}
|
|
2427
3098
|
function defineManageGroupsTool() {
|
|
2428
|
-
return
|
|
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
|
|
3099
|
+
return defineTool8({
|
|
3100
|
+
description: "Tenant-admin tool for workspace groups: list, get, create, update, delete, and manage group membership. Requires tenant admin access. Call get_my_access in the same turn before this tool to verify admin access (the check stays a compact success marker unless it is the only presentable result). Use group slug (e.g. finance) from list results for get and membership actions \u2014 internal ids are optional. Use member email for add_member and remove_member when user ids are unknown. Results render as chat UI cards \u2014 do not restate group or member fields in your reply.",
|
|
2430
3101
|
inputSchema: manageGroupsInputSchema,
|
|
3102
|
+
outputSchema: manageGroupsOutputSchema,
|
|
2431
3103
|
async execute(input, ctx) {
|
|
3104
|
+
const caller = requireAdminCaller(ctx);
|
|
2432
3105
|
const api = requireBoundAgentAdminClient(ctx);
|
|
3106
|
+
const tenantSlug = caller.tenantSlug;
|
|
2433
3107
|
try {
|
|
2434
3108
|
switch (input.action) {
|
|
2435
3109
|
case "list": {
|
|
2436
3110
|
const result = await api.groups.list();
|
|
2437
|
-
return formatGroupsListResult(result.groups
|
|
3111
|
+
return formatGroupsListResult(result.groups, {
|
|
3112
|
+
tenantSlug
|
|
3113
|
+
});
|
|
2438
3114
|
}
|
|
2439
3115
|
case "get": {
|
|
2440
3116
|
const result = await api.groups.get(resolveGroupRef(input));
|
|
2441
|
-
return formatGroupDetailResult(
|
|
3117
|
+
return formatGroupDetailResult(
|
|
3118
|
+
result.group,
|
|
3119
|
+
{ tenantSlug }
|
|
3120
|
+
);
|
|
2442
3121
|
}
|
|
2443
3122
|
case "create": {
|
|
2444
3123
|
const result = await api.groups.create({
|
|
2445
3124
|
name: input.name,
|
|
2446
3125
|
description: input.description
|
|
2447
3126
|
});
|
|
2448
|
-
return formatGroupSummaryResult(result.group
|
|
3127
|
+
return formatGroupSummaryResult(result.group, {
|
|
3128
|
+
tenantSlug
|
|
3129
|
+
});
|
|
2449
3130
|
}
|
|
2450
3131
|
case "update": {
|
|
2451
3132
|
const result = await api.groups.update(resolveGroupRef(input), {
|
|
2452
3133
|
name: input.name,
|
|
2453
3134
|
description: input.description
|
|
2454
3135
|
});
|
|
2455
|
-
return formatGroupSummaryResult(result.group
|
|
3136
|
+
return formatGroupSummaryResult(result.group, {
|
|
3137
|
+
tenantSlug
|
|
3138
|
+
});
|
|
2456
3139
|
}
|
|
2457
3140
|
case "delete": {
|
|
2458
3141
|
const result = await api.groups.delete(resolveGroupRef(input));
|
|
@@ -2496,83 +3179,101 @@ function defineManageGroupsTool() {
|
|
|
2496
3179
|
var manageGroupsTool = defineManageGroupsTool();
|
|
2497
3180
|
|
|
2498
3181
|
// src/eve/tools/admin/query-tasks.ts
|
|
2499
|
-
import { defineTool as
|
|
2500
|
-
import { z as
|
|
3182
|
+
import { defineTool as defineTool9 } from "eve/tools";
|
|
3183
|
+
import { z as z15 } from "zod";
|
|
2501
3184
|
|
|
2502
3185
|
// src/eve/tools/admin/format-tasks-list.ts
|
|
2503
3186
|
function resolveTaskCardLabel(task) {
|
|
2504
3187
|
return task.name?.trim() || task.description?.trim() || task.type?.trim() || task.id?.trim() || "Untitled task";
|
|
2505
3188
|
}
|
|
3189
|
+
function serializeTaskRow(task, tenantSlug) {
|
|
3190
|
+
return {
|
|
3191
|
+
id: task.id,
|
|
3192
|
+
name: resolveTaskCardLabel(task),
|
|
3193
|
+
status: task.status,
|
|
3194
|
+
type: task.type,
|
|
3195
|
+
description: task.description,
|
|
3196
|
+
validUntil: task.validUntil,
|
|
3197
|
+
createdAt: task.createdAt,
|
|
3198
|
+
threadPriority: task.threadPriority,
|
|
3199
|
+
url: buildTenantTaskUrl(tenantSlug, {
|
|
3200
|
+
id: task.id,
|
|
3201
|
+
type: task.type
|
|
3202
|
+
})
|
|
3203
|
+
};
|
|
3204
|
+
}
|
|
2506
3205
|
function formatTasksListResult(items, options) {
|
|
2507
3206
|
const payload = {
|
|
2508
|
-
items: items.map((task) => (
|
|
2509
|
-
id: task.id,
|
|
2510
|
-
name: resolveTaskCardLabel(task),
|
|
2511
|
-
status: task.status,
|
|
2512
|
-
type: task.type,
|
|
2513
|
-
description: task.description
|
|
2514
|
-
}))
|
|
3207
|
+
items: items.map((task) => serializeTaskRow(task, options.tenantSlug))
|
|
2515
3208
|
};
|
|
2516
|
-
if (options
|
|
3209
|
+
if (options.nextCursor) {
|
|
2517
3210
|
payload.nextCursor = options.nextCursor;
|
|
2518
3211
|
}
|
|
2519
3212
|
return formatToolObjectResult(payload, {
|
|
2520
|
-
replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE
|
|
3213
|
+
replyGuidance: QUERY_TASKS_LIST_REPLY_GUIDANCE,
|
|
3214
|
+
ui: { layout: "list", entity: "task", rowsPath: "items" }
|
|
2521
3215
|
});
|
|
2522
3216
|
}
|
|
2523
|
-
function formatTaskSearchResult(items) {
|
|
2524
|
-
return formatTasksListResult(items);
|
|
3217
|
+
function formatTaskSearchResult(items, options) {
|
|
3218
|
+
return formatTasksListResult(items, options);
|
|
2525
3219
|
}
|
|
2526
|
-
function formatTaskDetailResult(task) {
|
|
3220
|
+
function formatTaskDetailResult(task, options) {
|
|
3221
|
+
const id = typeof task.id === "string" ? task.id : null;
|
|
3222
|
+
const type = typeof task.type === "string" ? task.type : null;
|
|
3223
|
+
const url = id !== null ? buildTenantTaskUrl(options.tenantSlug, { id, type }) : null;
|
|
2527
3224
|
return formatToolObjectResult(
|
|
2528
3225
|
{
|
|
2529
|
-
id
|
|
2530
|
-
status: task.status
|
|
2531
|
-
type
|
|
2532
|
-
name: task.name
|
|
2533
|
-
description: task.description
|
|
2534
|
-
validUntil: task.validUntil
|
|
2535
|
-
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
|
|
2536
3234
|
},
|
|
2537
3235
|
{
|
|
2538
|
-
replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE
|
|
3236
|
+
replyGuidance: QUERY_TASKS_DETAIL_REPLY_GUIDANCE,
|
|
3237
|
+
ui: { entity: "task" }
|
|
2539
3238
|
}
|
|
2540
3239
|
);
|
|
2541
3240
|
}
|
|
2542
|
-
function formatAssignTasksResult(results, _assignTo) {
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
3241
|
+
function formatAssignTasksResult(results, _assignTo, options) {
|
|
3242
|
+
const rows = results.map((row) => ({
|
|
3243
|
+
id: row.taskId,
|
|
3244
|
+
name: resolveTaskCardLabel({
|
|
3245
|
+
name: row.name,
|
|
3246
|
+
description: row.description,
|
|
3247
|
+
type: row.type,
|
|
3248
|
+
id: row.taskId
|
|
3249
|
+
}),
|
|
3250
|
+
type: row.type ?? null,
|
|
3251
|
+
description: row.description ?? null,
|
|
3252
|
+
status: row.success ? "reassigned" : "failed",
|
|
3253
|
+
url: buildTenantTaskUrl(options.tenantSlug, {
|
|
2546
3254
|
id: row.taskId,
|
|
2547
|
-
|
|
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
|
-
);
|
|
3255
|
+
type: row.type
|
|
3256
|
+
})
|
|
3257
|
+
}));
|
|
3258
|
+
return formatToolListResult("results", rows, {
|
|
3259
|
+
replyGuidance: ASSIGN_TASKS_REPLY_GUIDANCE,
|
|
3260
|
+
entity: "status"
|
|
3261
|
+
});
|
|
2561
3262
|
}
|
|
2562
3263
|
|
|
2563
3264
|
// src/eve/tools/admin/query-tasks.ts
|
|
2564
3265
|
var QUERY_TASKS_TOOL_NAME = "query_tasks";
|
|
2565
|
-
var queryTasksInputSchema =
|
|
2566
|
-
action:
|
|
2567
|
-
statusFilter:
|
|
2568
|
-
typeFilter:
|
|
2569
|
-
appFilter:
|
|
2570
|
-
sortField:
|
|
2571
|
-
sortDirection:
|
|
2572
|
-
limit:
|
|
2573
|
-
cursor:
|
|
2574
|
-
taskId:
|
|
2575
|
-
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.")
|
|
2576
3277
|
}).superRefine((input, ctx) => {
|
|
2577
3278
|
switch (input.action) {
|
|
2578
3279
|
case "get":
|
|
@@ -2596,11 +3297,14 @@ var queryTasksInputSchema = z12.object({
|
|
|
2596
3297
|
}
|
|
2597
3298
|
});
|
|
2598
3299
|
function defineQueryTasksTool() {
|
|
2599
|
-
return
|
|
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
|
|
3300
|
+
return defineTool9({
|
|
3301
|
+
description: "Tenant-admin tool to list, fetch detail, or search inbox tasks in the workspace. Requires tenant admin access. Call get_my_access in the same turn before this tool to verify admin access (the check stays a compact success marker unless it is the only presentable result). Results render as chat UI cards \u2014 do not restate task names, ids, or statuses in your reply.",
|
|
2601
3302
|
inputSchema: queryTasksInputSchema,
|
|
3303
|
+
outputSchema: queryTasksOutputSchema,
|
|
2602
3304
|
async execute(input, ctx) {
|
|
3305
|
+
const caller = requireAdminCaller(ctx);
|
|
2603
3306
|
const api = requireBoundAgentAdminClient(ctx);
|
|
3307
|
+
const tenantSlug = caller.tenantSlug;
|
|
2604
3308
|
try {
|
|
2605
3309
|
switch (input.action) {
|
|
2606
3310
|
case "list": {
|
|
@@ -2614,17 +3318,22 @@ function defineQueryTasksTool() {
|
|
|
2614
3318
|
cursor: input.cursor
|
|
2615
3319
|
});
|
|
2616
3320
|
return formatTasksListResult(result.items, {
|
|
3321
|
+
tenantSlug,
|
|
2617
3322
|
nextCursor: result.nextCursor
|
|
2618
3323
|
});
|
|
2619
3324
|
}
|
|
2620
3325
|
case "get": {
|
|
2621
3326
|
const result = await api.tasks.get(input.taskId);
|
|
2622
|
-
return formatTaskDetailResult(
|
|
3327
|
+
return formatTaskDetailResult(
|
|
3328
|
+
result.task,
|
|
3329
|
+
{ tenantSlug }
|
|
3330
|
+
);
|
|
2623
3331
|
}
|
|
2624
3332
|
case "search": {
|
|
2625
3333
|
const result = await api.tasks.search(input.query, input.limit);
|
|
2626
3334
|
return formatTaskSearchResult(
|
|
2627
|
-
result.items
|
|
3335
|
+
result.items,
|
|
3336
|
+
{ tenantSlug }
|
|
2628
3337
|
);
|
|
2629
3338
|
}
|
|
2630
3339
|
}
|
|
@@ -2645,11 +3354,11 @@ function defineQueryTasksTool() {
|
|
|
2645
3354
|
var queryTasksTool = defineQueryTasksTool();
|
|
2646
3355
|
|
|
2647
3356
|
// src/eve/tools/admin/assign-tasks.ts
|
|
2648
|
-
import { defineTool as
|
|
2649
|
-
import { z as
|
|
3357
|
+
import { defineTool as defineTool10 } from "eve/tools";
|
|
3358
|
+
import { z as z16 } from "zod";
|
|
2650
3359
|
var ASSIGN_TASKS_TOOL_NAME = "assign_tasks";
|
|
2651
|
-
var assignTasksInputSchema =
|
|
2652
|
-
taskIds:
|
|
3360
|
+
var assignTasksInputSchema = z16.object({
|
|
3361
|
+
taskIds: z16.array(z16.string().min(1)).min(1).max(100).describe(
|
|
2653
3362
|
"Public task ids or Convex tasks table ids to reassign. Use query_tasks search/get to resolve ids first."
|
|
2654
3363
|
),
|
|
2655
3364
|
assignTo: assignToSchema.refine(
|
|
@@ -2660,17 +3369,21 @@ var assignTasksInputSchema = z13.object({
|
|
|
2660
3369
|
)
|
|
2661
3370
|
});
|
|
2662
3371
|
function defineAssignTasksTool() {
|
|
2663
|
-
return
|
|
3372
|
+
return defineTool10({
|
|
2664
3373
|
description: "Reassign existing inbox tasks to users or groups. Requires access to each task (tenant admins can reassign any task; others only tasks they can see). Use query_tasks to find task ids when needed. Results render as chat UI \u2014 do not restate task ids or assignees in your reply.",
|
|
2665
3374
|
inputSchema: assignTasksInputSchema,
|
|
3375
|
+
outputSchema: assignTasksOutputSchema,
|
|
2666
3376
|
async execute(input, ctx) {
|
|
3377
|
+
const caller = requireTenantCaller(ctx);
|
|
2667
3378
|
const api = createBoundAgentAdminClient(ctx);
|
|
2668
3379
|
try {
|
|
2669
3380
|
const result = await api.tasks.assign({
|
|
2670
3381
|
taskIds: input.taskIds,
|
|
2671
3382
|
assignTo: input.assignTo
|
|
2672
3383
|
});
|
|
2673
|
-
return formatAssignTasksResult(result.results, input.assignTo
|
|
3384
|
+
return formatAssignTasksResult(result.results, input.assignTo, {
|
|
3385
|
+
tenantSlug: caller.tenantSlug
|
|
3386
|
+
});
|
|
2674
3387
|
} catch (error) {
|
|
2675
3388
|
if (error instanceof RobotRockError) {
|
|
2676
3389
|
return {
|
|
@@ -2687,6 +3400,72 @@ function defineAssignTasksTool() {
|
|
|
2687
3400
|
}
|
|
2688
3401
|
var assignTasksTool = defineAssignTasksTool();
|
|
2689
3402
|
|
|
3403
|
+
// src/eve/tools/admin/get-workspace-usage.ts
|
|
3404
|
+
import { defineTool as defineTool11 } from "eve/tools";
|
|
3405
|
+
import { z as z17 } from "zod";
|
|
3406
|
+
|
|
3407
|
+
// src/eve/tools/admin/format-workspace-usage.ts
|
|
3408
|
+
function formatLimit(current, max) {
|
|
3409
|
+
return max === null ? `${current} / unlimited` : `${current} / ${max}`;
|
|
3410
|
+
}
|
|
3411
|
+
function formatWorkspaceUsageResult(usage) {
|
|
3412
|
+
const tasksLimit = usage.maxTasksPerDay === null ? `${usage.tasksToday} / unlimited` : `${usage.tasksToday} / ${usage.maxTasksPerDay}`;
|
|
3413
|
+
return formatToolObjectResult(
|
|
3414
|
+
{
|
|
3415
|
+
usage: {
|
|
3416
|
+
workspace: usage.workspace,
|
|
3417
|
+
plan: usage.planName,
|
|
3418
|
+
planType: usage.planType,
|
|
3419
|
+
trialState: usage.trialState,
|
|
3420
|
+
daysRemaining: usage.daysRemaining,
|
|
3421
|
+
isPaidPro: usage.isPaidPro,
|
|
3422
|
+
subscriptionStatus: usage.subscriptionStatus ?? "\u2014",
|
|
3423
|
+
tasksToday: tasksLimit,
|
|
3424
|
+
tasksResetAt: new Date(usage.tasksResetAt).toISOString(),
|
|
3425
|
+
openTasks: usage.openTasks,
|
|
3426
|
+
totalTasks: usage.totalTasks,
|
|
3427
|
+
seats: formatLimit(usage.seatsCurrent, usage.seatsMax),
|
|
3428
|
+
groups: formatLimit(usage.groupsCurrent, usage.groupsMax),
|
|
3429
|
+
apiKeys: formatLimit(usage.apiKeysCurrent, usage.apiKeysMax),
|
|
3430
|
+
rateLimitPerSecond: usage.rateLimitPerSecond
|
|
3431
|
+
}
|
|
3432
|
+
},
|
|
3433
|
+
{
|
|
3434
|
+
replyGuidance: GET_WORKSPACE_USAGE_REPLY_GUIDANCE,
|
|
3435
|
+
ui: { entity: "usage" }
|
|
3436
|
+
}
|
|
3437
|
+
);
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3440
|
+
// src/eve/tools/admin/get-workspace-usage.ts
|
|
3441
|
+
var GET_WORKSPACE_USAGE_TOOL_NAME = "get_workspace_usage";
|
|
3442
|
+
var getWorkspaceUsageInputSchema = z17.object({});
|
|
3443
|
+
function defineGetWorkspaceUsageTool() {
|
|
3444
|
+
return defineTool11({
|
|
3445
|
+
description: "Tenant-admin tool for workspace plan, limits, and usage (tasks today, seats, groups, API keys, rate limits). Does not include LLM token counts or dollar spend \u2014 those are not tracked. Requires tenant admin access. Call get_my_access in the same turn before this tool. Results render as a chat UI card \u2014 do not restate plan or usage numbers in your reply.",
|
|
3446
|
+
inputSchema: getWorkspaceUsageInputSchema,
|
|
3447
|
+
outputSchema: getWorkspaceUsageOutputSchema,
|
|
3448
|
+
async execute(_input, ctx) {
|
|
3449
|
+
const api = requireBoundAgentAdminClient(ctx);
|
|
3450
|
+
try {
|
|
3451
|
+
const result = await api.usage.get();
|
|
3452
|
+
return formatWorkspaceUsageResult(result.usage);
|
|
3453
|
+
} catch (error) {
|
|
3454
|
+
if (error instanceof RobotRockError) {
|
|
3455
|
+
return {
|
|
3456
|
+
ok: false,
|
|
3457
|
+
status: error.statusCode,
|
|
3458
|
+
message: error.message,
|
|
3459
|
+
response: error.response
|
|
3460
|
+
};
|
|
3461
|
+
}
|
|
3462
|
+
throw error;
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
});
|
|
3466
|
+
}
|
|
3467
|
+
var getWorkspaceUsageTool = defineGetWorkspaceUsageTool();
|
|
3468
|
+
|
|
2690
3469
|
// src/eve/tools/index.ts
|
|
2691
3470
|
function createRobotrockTools(options) {
|
|
2692
3471
|
const tools = {};
|
|
@@ -2704,6 +3483,9 @@ function createRobotrockTools(options) {
|
|
|
2704
3483
|
export {
|
|
2705
3484
|
ASSIGN_TASKS_TOOL_NAME,
|
|
2706
3485
|
CREATE_INBOX_TASK_TOOL_NAME,
|
|
3486
|
+
GENERATE_IMAGE_TOOL_NAME,
|
|
3487
|
+
GENERATE_RANDOM_CHART_TOOL_NAME,
|
|
3488
|
+
GET_WORKSPACE_USAGE_TOOL_NAME,
|
|
2707
3489
|
MANAGE_GROUPS_TOOL_NAME,
|
|
2708
3490
|
MANAGE_TEAM_MEMBERS_TOOL_NAME,
|
|
2709
3491
|
MY_ACCESS_TOOL_NAME,
|
|
@@ -2712,17 +3494,28 @@ export {
|
|
|
2712
3494
|
WHOAMI_TOOL_NAME,
|
|
2713
3495
|
assignTasksInputSchema,
|
|
2714
3496
|
assignTasksTool,
|
|
3497
|
+
buildRandomChartData,
|
|
2715
3498
|
createInboxTaskInputSchema,
|
|
2716
3499
|
createInboxTaskTool,
|
|
2717
3500
|
createRobotrockTools,
|
|
2718
3501
|
defineAssignTasksTool,
|
|
2719
3502
|
defineCreateInboxTaskTool,
|
|
3503
|
+
defineGenerateImageTool,
|
|
3504
|
+
defineGenerateRandomChartTool,
|
|
3505
|
+
defineGetWorkspaceUsageTool,
|
|
2720
3506
|
defineManageGroupsTool,
|
|
2721
3507
|
defineManageTeamMembersTool,
|
|
2722
3508
|
defineMyAccessTool,
|
|
2723
3509
|
defineQueryTasksTool,
|
|
2724
3510
|
defineSearchProductsTool,
|
|
2725
3511
|
defineWhoamiTool,
|
|
3512
|
+
generateImageBytes,
|
|
3513
|
+
generateImageInputSchema,
|
|
3514
|
+
generateImageTool,
|
|
3515
|
+
generateRandomChartInputSchema,
|
|
3516
|
+
generateRandomChartTool,
|
|
3517
|
+
getWorkspaceUsageInputSchema,
|
|
3518
|
+
getWorkspaceUsageTool,
|
|
2726
3519
|
manageGroupsTool,
|
|
2727
3520
|
manageTeamMembersTool,
|
|
2728
3521
|
myAccessInputSchema,
|