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
|
@@ -0,0 +1,1365 @@
|
|
|
1
|
+
// src/eve/tools/admin/get-workspace-usage.ts
|
|
2
|
+
import { defineTool } from "eve/tools";
|
|
3
|
+
import { z as z6 } from "zod";
|
|
4
|
+
|
|
5
|
+
// src/http.ts
|
|
6
|
+
var RobotRockError = class extends Error {
|
|
7
|
+
constructor(message, statusCode, response) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.statusCode = statusCode;
|
|
10
|
+
this.response = response;
|
|
11
|
+
this.name = "RobotRockError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
async function parseResponseBody(response) {
|
|
15
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
16
|
+
const bodyText = await response.text();
|
|
17
|
+
if (!bodyText) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
if (contentType.toLowerCase().includes("application/json")) {
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(bodyText);
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(bodyText);
|
|
28
|
+
} catch {
|
|
29
|
+
return bodyText;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function getErrorMessage(data, fallback) {
|
|
33
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
34
|
+
const record = data;
|
|
35
|
+
const maybeMessage = record.message;
|
|
36
|
+
const maybeHint = record.hint;
|
|
37
|
+
if (typeof maybeMessage === "string" && maybeMessage.trim()) {
|
|
38
|
+
if (typeof maybeHint === "string" && maybeHint.trim()) {
|
|
39
|
+
return `${maybeMessage.trim()} ${maybeHint.trim()}`;
|
|
40
|
+
}
|
|
41
|
+
return maybeMessage;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (typeof data === "string" && data.trim()) {
|
|
45
|
+
const compact = data.replace(/\s+/g, " ").trim();
|
|
46
|
+
const snippet = compact.length > 180 ? `${compact.slice(0, 180)}...` : compact;
|
|
47
|
+
return `${fallback}. Server returned non-JSON response: ${snippet}`;
|
|
48
|
+
}
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// ../core/src/schemas/task.ts
|
|
53
|
+
import { z } from "zod";
|
|
54
|
+
|
|
55
|
+
// ../core/src/utils/safe-url.ts
|
|
56
|
+
var BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
57
|
+
"localhost",
|
|
58
|
+
"metadata.google.internal",
|
|
59
|
+
"metadata.goog"
|
|
60
|
+
]);
|
|
61
|
+
function normalizeHostname(hostname) {
|
|
62
|
+
return hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
63
|
+
}
|
|
64
|
+
function isBlockedIpv4(host) {
|
|
65
|
+
const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
|
|
66
|
+
if (!match) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const octets = match.slice(1, 5).map((part) => Number(part));
|
|
70
|
+
if (octets.some((octet) => Number.isNaN(octet) || octet < 0 || octet > 255)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
const [a, b, _c, _d] = octets;
|
|
74
|
+
if (a === void 0 || b === void 0) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
if (a === 127 || a === 0) return true;
|
|
78
|
+
if (a === 10) return true;
|
|
79
|
+
if (a === 169 && b === 254) return true;
|
|
80
|
+
if (a === 192 && b === 168) return true;
|
|
81
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
82
|
+
if (a === 100 && b >= 64 && b <= 127) return true;
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
function ipv4FromNumericHost(host) {
|
|
86
|
+
if (/^\d+$/.test(host)) {
|
|
87
|
+
const num = Number(host);
|
|
88
|
+
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const a = num >>> 24 & 255;
|
|
92
|
+
const b = num >>> 16 & 255;
|
|
93
|
+
const c = num >>> 8 & 255;
|
|
94
|
+
const d = num & 255;
|
|
95
|
+
return `${a}.${b}.${c}.${d}`;
|
|
96
|
+
}
|
|
97
|
+
const hexMatch = /^0x([0-9a-f]{1,8})$/i.exec(host);
|
|
98
|
+
if (hexMatch) {
|
|
99
|
+
const num = Number.parseInt(hexMatch[1], 16);
|
|
100
|
+
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const a = num >>> 24 & 255;
|
|
104
|
+
const b = num >>> 16 & 255;
|
|
105
|
+
const c = num >>> 8 & 255;
|
|
106
|
+
const d = num & 255;
|
|
107
|
+
return `${a}.${b}.${c}.${d}`;
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
function isBlockedIpv4Mapped(host) {
|
|
112
|
+
const mappedDotted = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/i.exec(host);
|
|
113
|
+
if (mappedDotted) {
|
|
114
|
+
return isBlockedIpv4(mappedDotted[1]);
|
|
115
|
+
}
|
|
116
|
+
const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(host);
|
|
117
|
+
if (mappedHex) {
|
|
118
|
+
const high = Number.parseInt(mappedHex[1], 16);
|
|
119
|
+
const low = Number.parseInt(mappedHex[2], 16);
|
|
120
|
+
if (Number.isFinite(high) && Number.isFinite(low)) {
|
|
121
|
+
const a = high >> 8 & 255;
|
|
122
|
+
const b = high & 255;
|
|
123
|
+
const c = low >> 8 & 255;
|
|
124
|
+
const d = low & 255;
|
|
125
|
+
return isBlockedIpv4(`${a}.${b}.${c}.${d}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
function isBlockedIpv6(host) {
|
|
131
|
+
if (host === "::1" || host === "0:0:0:0:0:0:0:1") {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
if (host.startsWith("fc") || host.startsWith("fd")) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
if (host.startsWith("fe80:")) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
if (isBlockedIpv4Mapped(host)) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
function isBlockedHostname(hostname) {
|
|
146
|
+
const host = normalizeHostname(hostname);
|
|
147
|
+
if (!host) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (BLOCKED_HOSTNAMES.has(host)) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
if (host.endsWith(".localhost") || host.endsWith(".local")) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
const numericIpv4 = ipv4FromNumericHost(host);
|
|
157
|
+
if (numericIpv4 && isBlockedIpv4(numericIpv4)) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
return isBlockedIpv4(host) || isBlockedIpv6(host);
|
|
161
|
+
}
|
|
162
|
+
function isLoopbackHandlerUrl(urlString) {
|
|
163
|
+
let url;
|
|
164
|
+
try {
|
|
165
|
+
url = new URL(urlString);
|
|
166
|
+
} catch {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
if (url.username || url.password) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
const host = url.hostname.toLowerCase();
|
|
176
|
+
return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]" || host.endsWith(".localhost");
|
|
177
|
+
}
|
|
178
|
+
function isAllowedHandlerUrl(urlString) {
|
|
179
|
+
return isPublicHttpUrl(urlString) || isLoopbackHandlerUrl(urlString);
|
|
180
|
+
}
|
|
181
|
+
function isPublicHttpUrl(urlString) {
|
|
182
|
+
let url;
|
|
183
|
+
try {
|
|
184
|
+
url = new URL(urlString);
|
|
185
|
+
} catch {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
if (url.username || url.password) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return !isBlockedHostname(url.hostname);
|
|
195
|
+
}
|
|
196
|
+
var PUBLIC_HTTP_URL_ERROR = "URL must be a public http:// or https:// address";
|
|
197
|
+
var HANDLER_URL_ERROR = "Handler URL must be a public or loopback http:// or https:// address";
|
|
198
|
+
|
|
199
|
+
// ../core/src/schemas/context-urls.ts
|
|
200
|
+
function resolveLinkUrl(value) {
|
|
201
|
+
return value.startsWith("http://") || value.startsWith("https://") ? value : `https://${value}`;
|
|
202
|
+
}
|
|
203
|
+
function widgetType(ui, field) {
|
|
204
|
+
const fieldUi = ui?.[field];
|
|
205
|
+
if (typeof fieldUi !== "object" || fieldUi === null) {
|
|
206
|
+
return void 0;
|
|
207
|
+
}
|
|
208
|
+
const widget = fieldUi["ui:widget"];
|
|
209
|
+
return typeof widget === "string" ? widget : void 0;
|
|
210
|
+
}
|
|
211
|
+
function validateUrlValue(value, widget) {
|
|
212
|
+
if (widget === "image" || widget === "link") {
|
|
213
|
+
if (typeof value !== "string") {
|
|
214
|
+
return PUBLIC_HTTP_URL_ERROR;
|
|
215
|
+
}
|
|
216
|
+
const url = widget === "link" ? resolveLinkUrl(value) : value;
|
|
217
|
+
if (!isPublicHttpUrl(url)) {
|
|
218
|
+
return PUBLIC_HTTP_URL_ERROR;
|
|
219
|
+
}
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
if (widget === "attachments" && Array.isArray(value)) {
|
|
223
|
+
for (const item of value) {
|
|
224
|
+
if (typeof item !== "object" || item === null) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const url = item.url;
|
|
228
|
+
if (typeof url === "string" && !isPublicHttpUrl(resolveLinkUrl(url))) {
|
|
229
|
+
return PUBLIC_HTTP_URL_ERROR;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
function validateContextPublicUrls(context) {
|
|
236
|
+
if (!context?.data) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
for (const [field, value] of Object.entries(context.data)) {
|
|
240
|
+
const widget = widgetType(context.ui, field);
|
|
241
|
+
if (!widget) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const error = validateUrlValue(value, widget);
|
|
245
|
+
if (error) {
|
|
246
|
+
return `context.data.${field}: ${error}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ../core/src/schemas/task.ts
|
|
253
|
+
var safeUrlSchema = z.string().refine((url) => isPublicHttpUrl(url), {
|
|
254
|
+
message: PUBLIC_HTTP_URL_ERROR
|
|
255
|
+
});
|
|
256
|
+
var handlerUrlSchema = z.string().refine((url) => isAllowedHandlerUrl(url), {
|
|
257
|
+
message: HANDLER_URL_ERROR
|
|
258
|
+
});
|
|
259
|
+
var jsonSchema7Schema = z.custom(
|
|
260
|
+
(val) => typeof val === "object" && val !== null,
|
|
261
|
+
{ message: "Must be a valid JSON Schema object" }
|
|
262
|
+
);
|
|
263
|
+
var uiSchemaSchema = z.custom((val) => typeof val === "object" && val !== null, {
|
|
264
|
+
message: "Must be a valid UiSchema object"
|
|
265
|
+
});
|
|
266
|
+
var webhookHandlerSchema = z.object({
|
|
267
|
+
type: z.literal("webhook"),
|
|
268
|
+
url: handlerUrlSchema,
|
|
269
|
+
headers: z.record(z.string(), z.string())
|
|
270
|
+
});
|
|
271
|
+
var triggerHandlerSchema = webhookHandlerSchema.extend({
|
|
272
|
+
type: z.literal("trigger"),
|
|
273
|
+
tokenId: z.string().min(1)
|
|
274
|
+
});
|
|
275
|
+
var handlerSchema = z.discriminatedUnion("type", [webhookHandlerSchema, triggerHandlerSchema]);
|
|
276
|
+
var taskActionInputSchema = z.object({
|
|
277
|
+
id: z.string().min(1),
|
|
278
|
+
title: z.string().min(1),
|
|
279
|
+
description: z.string().optional(),
|
|
280
|
+
schema: jsonSchema7Schema.optional(),
|
|
281
|
+
ui: uiSchemaSchema.optional(),
|
|
282
|
+
data: z.record(z.string(), z.unknown()).optional()
|
|
283
|
+
});
|
|
284
|
+
var taskActionSchema = taskActionInputSchema.extend({
|
|
285
|
+
// Optional handlers for this action - if present, must have at least 1
|
|
286
|
+
handlers: z.array(handlerSchema).min(1).optional()
|
|
287
|
+
});
|
|
288
|
+
var uiFieldSchemaSchema = z.object({
|
|
289
|
+
"ui:widget": z.string().optional(),
|
|
290
|
+
"ui:title": z.string().optional(),
|
|
291
|
+
"ui:description": z.string().optional(),
|
|
292
|
+
"ui:options": z.record(z.string(), z.unknown()).optional(),
|
|
293
|
+
items: z.lazy(() => z.record(z.string(), uiFieldSchemaSchema)).optional()
|
|
294
|
+
}).passthrough();
|
|
295
|
+
var contextUiSchema = z.record(z.string(), uiFieldSchemaSchema).optional();
|
|
296
|
+
var contextDataSchema = z.object({
|
|
297
|
+
data: z.record(z.string(), z.unknown()),
|
|
298
|
+
ui: contextUiSchema
|
|
299
|
+
}).optional();
|
|
300
|
+
var TASK_CONTEXT_FORMAT_VERSION = 2;
|
|
301
|
+
var taskContextObjectBaseSchema = z.object({
|
|
302
|
+
/** Source application id; omitted tasks are grouped in the default inbox. */
|
|
303
|
+
app: z.string().min(1).optional(),
|
|
304
|
+
type: z.string().min(1),
|
|
305
|
+
name: z.string().min(1),
|
|
306
|
+
description: z.string().optional(),
|
|
307
|
+
validUntil: z.string().optional(),
|
|
308
|
+
context: contextDataSchema,
|
|
309
|
+
/** Task context wire format version. @default 2 */
|
|
310
|
+
contextVersion: z.literal(2).optional(),
|
|
311
|
+
/** @deprecated Use `contextVersion`. Accepted on ingest only. */
|
|
312
|
+
version: z.literal(2).optional(),
|
|
313
|
+
actions: z.array(taskActionSchema).min(1, "At least one action is required")
|
|
314
|
+
});
|
|
315
|
+
function normalizeTaskContextVersion(data) {
|
|
316
|
+
const { version: legacyVersion, contextVersion, ...rest } = data;
|
|
317
|
+
return {
|
|
318
|
+
...rest,
|
|
319
|
+
contextVersion: contextVersion ?? legacyVersion ?? TASK_CONTEXT_FORMAT_VERSION
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
var taskContextObjectSchema = taskContextObjectBaseSchema.transform(
|
|
323
|
+
normalizeTaskContextVersion
|
|
324
|
+
);
|
|
325
|
+
function refineContextPublicUrls(data, ctx) {
|
|
326
|
+
const error = validateContextPublicUrls(data.context);
|
|
327
|
+
if (error) {
|
|
328
|
+
ctx.addIssue({
|
|
329
|
+
code: z.ZodIssueCode.custom,
|
|
330
|
+
message: error,
|
|
331
|
+
path: ["context"]
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
var taskContextSchema = taskContextObjectSchema.superRefine(
|
|
336
|
+
refineContextPublicUrls
|
|
337
|
+
);
|
|
338
|
+
var assignToSchema = z.object({
|
|
339
|
+
users: z.array(z.string().email()).optional(),
|
|
340
|
+
groups: z.array(z.string().min(1)).optional()
|
|
341
|
+
}).refine(
|
|
342
|
+
(data) => {
|
|
343
|
+
const groups = data.groups ?? [];
|
|
344
|
+
if (groups.includes("all") && groups.length > 1) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
return true;
|
|
348
|
+
},
|
|
349
|
+
{ message: 'Cannot combine "all" with other group slugs' }
|
|
350
|
+
);
|
|
351
|
+
var threadUpdateMessageSchema = z.string().min(1).max(500);
|
|
352
|
+
var threadUpdateStatuses = [
|
|
353
|
+
"info",
|
|
354
|
+
"queued",
|
|
355
|
+
"running",
|
|
356
|
+
"waiting",
|
|
357
|
+
"succeeded",
|
|
358
|
+
"failed",
|
|
359
|
+
"cancelled"
|
|
360
|
+
];
|
|
361
|
+
var threadUpdateStatusSchema = z.enum(threadUpdateStatuses);
|
|
362
|
+
var threadUpdateInputSchema = z.object({
|
|
363
|
+
message: threadUpdateMessageSchema,
|
|
364
|
+
status: threadUpdateStatusSchema.optional()
|
|
365
|
+
});
|
|
366
|
+
var taskPriorities = ["low", "normal", "high", "urgent"];
|
|
367
|
+
var taskPrioritySchema = z.enum(taskPriorities);
|
|
368
|
+
var agentTelemetrySchema = z.object({
|
|
369
|
+
/** Agent or app version (semver, git SHA, deploy tag — caller-defined). */
|
|
370
|
+
version: z.string().min(1)
|
|
371
|
+
});
|
|
372
|
+
var createTaskBodySchema = taskContextObjectBaseSchema.extend({
|
|
373
|
+
assignTo: assignToSchema.optional(),
|
|
374
|
+
/**
|
|
375
|
+
* Groups related tasks together. When omitted, the server generates one and
|
|
376
|
+
* returns it so the caller can reuse it on later tasks in the same thread.
|
|
377
|
+
*/
|
|
378
|
+
threadId: z.string().min(1).optional(),
|
|
379
|
+
/**
|
|
380
|
+
* Optional thread priority. When set, applies to the whole thread and
|
|
381
|
+
* overwrites any previous priority. Omit on later tasks to leave unchanged.
|
|
382
|
+
*/
|
|
383
|
+
priority: taskPrioritySchema.optional(),
|
|
384
|
+
/**
|
|
385
|
+
* Optional initial status update logged against the task's thread. Shows in
|
|
386
|
+
* the inbox status bar and the thread update log.
|
|
387
|
+
*/
|
|
388
|
+
update: threadUpdateInputSchema.optional(),
|
|
389
|
+
/** Agent release version — not shown in inbox UI. */
|
|
390
|
+
agent: agentTelemetrySchema.optional()
|
|
391
|
+
}).transform(normalizeTaskContextVersion).superRefine(refineContextPublicUrls);
|
|
392
|
+
var agentChatSeedActionSchema = z.object({
|
|
393
|
+
/** Stable action id echoed back on submit; auto-derived from title when omitted. */
|
|
394
|
+
id: z.string().min(1).optional(),
|
|
395
|
+
title: z.string().min(1),
|
|
396
|
+
description: z.string().optional(),
|
|
397
|
+
/** JSON Schema object for the form fields. */
|
|
398
|
+
schema: z.record(z.string(), z.unknown()).optional(),
|
|
399
|
+
/** RJSF ui schema overrides (ui:widget, ui:enumNames, etc.). */
|
|
400
|
+
ui: z.record(z.string(), z.unknown()).optional(),
|
|
401
|
+
/** Optional default field values. */
|
|
402
|
+
data: z.record(z.string(), z.unknown()).optional()
|
|
403
|
+
});
|
|
404
|
+
var agentChatSeedMessageSchema = z.object({
|
|
405
|
+
role: z.enum(["user", "assistant"]),
|
|
406
|
+
text: z.string().min(1),
|
|
407
|
+
/** Optional display-name override for the message sender. */
|
|
408
|
+
senderName: z.string().min(1).optional(),
|
|
409
|
+
/**
|
|
410
|
+
* Optional structured input request rendered as a styled RobotRock action
|
|
411
|
+
* widget below the message text. Use this instead of asking the user to reply
|
|
412
|
+
* in plain text so the request is always a proper action form.
|
|
413
|
+
*/
|
|
414
|
+
requestActionInput: z.object({
|
|
415
|
+
prompt: z.string().optional(),
|
|
416
|
+
action: agentChatSeedActionSchema
|
|
417
|
+
}).optional()
|
|
418
|
+
});
|
|
419
|
+
var eveAgentChatTransportSchema = z.object({
|
|
420
|
+
kind: z.literal("eve"),
|
|
421
|
+
chatId: z.string().min(1),
|
|
422
|
+
baseUrl: z.string().url(),
|
|
423
|
+
sessionId: z.string().optional(),
|
|
424
|
+
continuationToken: z.string().optional(),
|
|
425
|
+
streamIndex: z.number().int().nonnegative().optional(),
|
|
426
|
+
isStreaming: z.boolean().optional()
|
|
427
|
+
});
|
|
428
|
+
var createAgentChatBodySchema = z.object({
|
|
429
|
+
/** Agent id (eve agent name). Required unless `parentChatId` is set. */
|
|
430
|
+
agentIdentifier: z.string().min(1).optional(),
|
|
431
|
+
/** Inherit tenant/connection/agent from an existing chat (agent-spawned chats). */
|
|
432
|
+
parentChatId: z.string().min(1).optional(),
|
|
433
|
+
/** Convex tenantEveConnections id; resolved from the tenant when omitted. */
|
|
434
|
+
eveConnectionId: z.string().min(1).optional(),
|
|
435
|
+
/** Source application id; groups the chat under an inbox section. */
|
|
436
|
+
app: z.string().min(1).optional(),
|
|
437
|
+
/** Email of the user who owns the chat. Required unless `parentChatId` is set. */
|
|
438
|
+
ownerEmail: z.string().email().optional(),
|
|
439
|
+
title: z.string().min(1),
|
|
440
|
+
messages: z.array(agentChatSeedMessageSchema).default([]),
|
|
441
|
+
/** Provenance label stored on the session ("cron" | "agent" | ...). */
|
|
442
|
+
source: z.string().min(1).optional()
|
|
443
|
+
}).refine((data) => Boolean(data.agentIdentifier || data.parentChatId), {
|
|
444
|
+
message: "Provide either agentIdentifier or parentChatId"
|
|
445
|
+
}).refine((data) => Boolean(data.ownerEmail || data.parentChatId), {
|
|
446
|
+
message: "Provide ownerEmail unless parentChatId is set"
|
|
447
|
+
});
|
|
448
|
+
var agentChatAuditToolBodySchema = z.object({
|
|
449
|
+
eveSessionId: z.string().min(1),
|
|
450
|
+
userId: z.string().min(1),
|
|
451
|
+
toolCallId: z.string().min(1),
|
|
452
|
+
toolName: z.string().min(1),
|
|
453
|
+
input: z.record(z.string(), z.unknown()).default({}),
|
|
454
|
+
success: z.boolean(),
|
|
455
|
+
status: z.enum(["completed", "failed", "rejected"]),
|
|
456
|
+
error: z.string().optional(),
|
|
457
|
+
idempotencyKey: z.string().optional()
|
|
458
|
+
});
|
|
459
|
+
var agentChatAuditInputBodySchema = z.object({
|
|
460
|
+
eveSessionId: z.string().min(1),
|
|
461
|
+
userId: z.string().min(1),
|
|
462
|
+
actionId: z.string().min(1),
|
|
463
|
+
actionTitle: z.string().optional(),
|
|
464
|
+
prompt: z.string().optional(),
|
|
465
|
+
data: z.record(z.string(), z.unknown()).optional(),
|
|
466
|
+
idempotencyKey: z.string().optional(),
|
|
467
|
+
/** Eve input request id — used to merge staged HITL metadata. */
|
|
468
|
+
requestId: z.string().optional(),
|
|
469
|
+
/** Eve tool call id — fallback lookup for staged HITL metadata. */
|
|
470
|
+
toolCallId: z.string().optional()
|
|
471
|
+
});
|
|
472
|
+
var eveHitlStagedOptionSchema = z.object({
|
|
473
|
+
id: z.string(),
|
|
474
|
+
label: z.string()
|
|
475
|
+
});
|
|
476
|
+
var agentChatStageHitlBodySchema = z.object({
|
|
477
|
+
eveSessionId: z.string().min(1),
|
|
478
|
+
requests: z.array(
|
|
479
|
+
z.object({
|
|
480
|
+
requestId: z.string().min(1),
|
|
481
|
+
toolCallId: z.string().min(1),
|
|
482
|
+
toolName: z.string().min(1),
|
|
483
|
+
prompt: z.string().min(1),
|
|
484
|
+
display: z.enum(["confirmation", "select", "text"]).optional(),
|
|
485
|
+
allowFreeform: z.boolean().optional(),
|
|
486
|
+
options: z.array(eveHitlStagedOptionSchema).optional(),
|
|
487
|
+
toolInput: z.record(z.string(), z.unknown()).optional()
|
|
488
|
+
})
|
|
489
|
+
)
|
|
490
|
+
});
|
|
491
|
+
var agentChatLinkTaskBodySchema = z.object({
|
|
492
|
+
eveSessionId: z.string().min(1),
|
|
493
|
+
publicTaskId: z.string().min(1),
|
|
494
|
+
toolCallId: z.string().min(1)
|
|
495
|
+
});
|
|
496
|
+
var AGENT_FILE_TAGS_MAX = 20;
|
|
497
|
+
var AGENT_FILE_TAG_MAX_LENGTH = 64;
|
|
498
|
+
function normalizeAgentFileTags(tags) {
|
|
499
|
+
if (!tags?.length) return void 0;
|
|
500
|
+
const seen = /* @__PURE__ */ new Set();
|
|
501
|
+
const out = [];
|
|
502
|
+
for (const raw of tags) {
|
|
503
|
+
const tag = raw.trim().toLowerCase().slice(0, AGENT_FILE_TAG_MAX_LENGTH);
|
|
504
|
+
if (!tag || seen.has(tag)) continue;
|
|
505
|
+
seen.add(tag);
|
|
506
|
+
out.push(tag);
|
|
507
|
+
if (out.length >= AGENT_FILE_TAGS_MAX) break;
|
|
508
|
+
}
|
|
509
|
+
return out.length > 0 ? out : void 0;
|
|
510
|
+
}
|
|
511
|
+
var agentChatUploadImageBodySchema = z.object({
|
|
512
|
+
mediaType: z.string().min(1),
|
|
513
|
+
/** Raw base64 (no data: URL prefix). */
|
|
514
|
+
base64: z.string().min(1),
|
|
515
|
+
chatId: z.string().min(1).optional(),
|
|
516
|
+
publicTaskId: z.string().min(1).optional(),
|
|
517
|
+
source: z.string().min(1).optional(),
|
|
518
|
+
/** Display / search name (e.g. `sunset-robot.png`). */
|
|
519
|
+
filename: z.string().min(1).max(255).optional(),
|
|
520
|
+
/** Human-readable description (e.g. generation prompt). */
|
|
521
|
+
description: z.string().min(1).max(2e3).optional(),
|
|
522
|
+
/**
|
|
523
|
+
* Optional labels for later grouping/filtering.
|
|
524
|
+
* Normalized to lowercase trimmed unique strings (max 20, 64 chars each).
|
|
525
|
+
*/
|
|
526
|
+
tags: z.array(z.string().min(1).max(AGENT_FILE_TAG_MAX_LENGTH)).max(AGENT_FILE_TAGS_MAX).optional().transform((tags) => normalizeAgentFileTags(tags))
|
|
527
|
+
}).refine((data) => Boolean(data.chatId || data.publicTaskId), {
|
|
528
|
+
message: "Provide chatId and/or publicTaskId"
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// ../core/src/schemas/tool-result-display.ts
|
|
532
|
+
import { z as z2 } from "zod";
|
|
533
|
+
var toolDisplayMetadataSchema = z2.object({
|
|
534
|
+
widget: z2.string().optional(),
|
|
535
|
+
title: z2.string().optional(),
|
|
536
|
+
description: z2.string().optional()
|
|
537
|
+
});
|
|
538
|
+
var toolDisplayEnvelopeSchema = z2.object({
|
|
539
|
+
display: toolDisplayMetadataSchema.optional(),
|
|
540
|
+
data: z2.record(z2.string(), z2.unknown()),
|
|
541
|
+
ui: z2.record(
|
|
542
|
+
z2.string(),
|
|
543
|
+
z2.object({
|
|
544
|
+
"ui:widget": z2.string().optional(),
|
|
545
|
+
"ui:title": z2.string().optional(),
|
|
546
|
+
"ui:description": z2.string().optional(),
|
|
547
|
+
"ui:options": z2.record(z2.string(), z2.unknown()).optional()
|
|
548
|
+
}).passthrough()
|
|
549
|
+
).optional()
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
// ../core/src/schemas/agent-admin.ts
|
|
553
|
+
import { z as z3 } from "zod";
|
|
554
|
+
var tenantRoleSchema = z3.enum(["admin", "member"]);
|
|
555
|
+
var agentAdminUserSchema = z3.object({
|
|
556
|
+
id: z3.string(),
|
|
557
|
+
email: z3.string().email(),
|
|
558
|
+
name: z3.string(),
|
|
559
|
+
profilePictureUrl: z3.string().nullable().optional()
|
|
560
|
+
});
|
|
561
|
+
var agentAdminMemberSchema = z3.object({
|
|
562
|
+
userId: z3.string(),
|
|
563
|
+
role: z3.string(),
|
|
564
|
+
membershipKind: z3.enum(["team", "assignee"]),
|
|
565
|
+
hasLoggedIn: z3.boolean(),
|
|
566
|
+
user: agentAdminUserSchema
|
|
567
|
+
});
|
|
568
|
+
var agentAdminGroupSchema = z3.object({
|
|
569
|
+
id: z3.string(),
|
|
570
|
+
name: z3.string(),
|
|
571
|
+
slug: z3.string(),
|
|
572
|
+
description: z3.string().nullable(),
|
|
573
|
+
memberCount: z3.number().optional()
|
|
574
|
+
});
|
|
575
|
+
var agentAdminGroupDetailSchema = agentAdminGroupSchema.extend({
|
|
576
|
+
members: z3.array(
|
|
577
|
+
z3.object({
|
|
578
|
+
userId: z3.string(),
|
|
579
|
+
user: agentAdminUserSchema
|
|
580
|
+
})
|
|
581
|
+
)
|
|
582
|
+
});
|
|
583
|
+
var agentAdminTaskSummarySchema = z3.object({
|
|
584
|
+
id: z3.string(),
|
|
585
|
+
convexId: z3.string(),
|
|
586
|
+
status: z3.string(),
|
|
587
|
+
type: z3.string().nullable(),
|
|
588
|
+
name: z3.string().nullable(),
|
|
589
|
+
description: z3.string().nullable(),
|
|
590
|
+
validUntil: z3.number(),
|
|
591
|
+
createdAt: z3.number(),
|
|
592
|
+
threadPriority: z3.string().nullable(),
|
|
593
|
+
handledByUserId: z3.string().nullable()
|
|
594
|
+
});
|
|
595
|
+
var inviteMemberBodySchema = z3.object({
|
|
596
|
+
email: z3.string().email(),
|
|
597
|
+
role: tenantRoleSchema.optional()
|
|
598
|
+
});
|
|
599
|
+
var updateMemberRoleBodySchema = z3.object({
|
|
600
|
+
role: tenantRoleSchema
|
|
601
|
+
});
|
|
602
|
+
var createGroupBodySchema = z3.object({
|
|
603
|
+
name: z3.string().min(1),
|
|
604
|
+
description: z3.string().optional()
|
|
605
|
+
});
|
|
606
|
+
var updateGroupBodySchema = z3.object({
|
|
607
|
+
name: z3.string().min(1).optional(),
|
|
608
|
+
description: z3.string().optional()
|
|
609
|
+
});
|
|
610
|
+
var addGroupMemberBodySchema = z3.object({
|
|
611
|
+
userId: z3.string().min(1).describe("Convex user id or member email.")
|
|
612
|
+
});
|
|
613
|
+
var listTasksQuerySchema = z3.object({
|
|
614
|
+
statusFilter: z3.enum(["all", "open", "handled", "expired"]).optional(),
|
|
615
|
+
typeFilter: z3.string().optional(),
|
|
616
|
+
appFilter: z3.string().optional(),
|
|
617
|
+
sortField: z3.enum(["type", "date", "status", "validUntil"]).optional(),
|
|
618
|
+
sortDirection: z3.enum(["asc", "desc"]).optional(),
|
|
619
|
+
limit: z3.coerce.number().int().positive().max(100).optional(),
|
|
620
|
+
cursor: z3.string().optional()
|
|
621
|
+
});
|
|
622
|
+
var searchTasksQuerySchema = z3.object({
|
|
623
|
+
q: z3.string().min(1),
|
|
624
|
+
limit: z3.coerce.number().int().positive().max(100).optional()
|
|
625
|
+
});
|
|
626
|
+
var assignTasksResultSchema = z3.object({
|
|
627
|
+
taskId: z3.string(),
|
|
628
|
+
success: z3.boolean(),
|
|
629
|
+
message: z3.string().optional(),
|
|
630
|
+
name: z3.string().nullable().optional(),
|
|
631
|
+
description: z3.string().nullable().optional(),
|
|
632
|
+
type: z3.string().nullable().optional()
|
|
633
|
+
});
|
|
634
|
+
var assignTasksResponseSchema = z3.object({
|
|
635
|
+
results: z3.array(assignTasksResultSchema)
|
|
636
|
+
});
|
|
637
|
+
var assignTasksBodySchema = z3.object({
|
|
638
|
+
taskIds: z3.array(z3.string().min(1)).min(1).max(100),
|
|
639
|
+
assignTo: assignToSchema.refine(
|
|
640
|
+
(value) => (value.users?.length ?? 0) > 0 || (value.groups?.length ?? 0) > 0,
|
|
641
|
+
{ message: "assignTo needs at least one user email or group slug." }
|
|
642
|
+
)
|
|
643
|
+
});
|
|
644
|
+
var agentAdminPlanLimitsSchema = z3.object({
|
|
645
|
+
tasksPerDay: z3.number(),
|
|
646
|
+
members: z3.number(),
|
|
647
|
+
apiKeys: z3.number(),
|
|
648
|
+
groups: z3.number(),
|
|
649
|
+
auditLogRetention: z3.number(),
|
|
650
|
+
rateLimitPerSecond: z3.number(),
|
|
651
|
+
taskRetentionDays: z3.number()
|
|
652
|
+
});
|
|
653
|
+
var agentAdminUsageSchema = z3.object({
|
|
654
|
+
workspace: z3.string(),
|
|
655
|
+
planName: z3.string(),
|
|
656
|
+
planType: z3.string(),
|
|
657
|
+
trialState: z3.enum(["none", "active", "expired"]),
|
|
658
|
+
daysRemaining: z3.number().nullable(),
|
|
659
|
+
isPaidPro: z3.boolean(),
|
|
660
|
+
subscriptionStatus: z3.string().nullable(),
|
|
661
|
+
tasksToday: z3.number(),
|
|
662
|
+
maxTasksPerDay: z3.number().nullable(),
|
|
663
|
+
tasksResetAt: z3.number(),
|
|
664
|
+
openTasks: z3.number(),
|
|
665
|
+
totalTasks: z3.number(),
|
|
666
|
+
seatsCurrent: z3.number(),
|
|
667
|
+
seatsMax: z3.number().nullable(),
|
|
668
|
+
groupsCurrent: z3.number(),
|
|
669
|
+
groupsMax: z3.number().nullable(),
|
|
670
|
+
apiKeysCurrent: z3.number(),
|
|
671
|
+
apiKeysMax: z3.number().nullable(),
|
|
672
|
+
rateLimitPerSecond: z3.number(),
|
|
673
|
+
limits: agentAdminPlanLimitsSchema
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
// ../core/src/handler-retry.ts
|
|
677
|
+
var HANDLER_RETRY_DELAYS_MS = [
|
|
678
|
+
6e4,
|
|
679
|
+
// 1m
|
|
680
|
+
3e5,
|
|
681
|
+
// 5m
|
|
682
|
+
18e5,
|
|
683
|
+
// 30m
|
|
684
|
+
36e5,
|
|
685
|
+
// 1h
|
|
686
|
+
216e5,
|
|
687
|
+
// 6h
|
|
688
|
+
864e5,
|
|
689
|
+
// 24h
|
|
690
|
+
1728e5
|
|
691
|
+
// 48h
|
|
692
|
+
];
|
|
693
|
+
var HANDLER_MAX_ATTEMPTS = HANDLER_RETRY_DELAYS_MS.length + 1;
|
|
694
|
+
|
|
695
|
+
// ../core/src/attribution/index.ts
|
|
696
|
+
import { z as z4 } from "zod";
|
|
697
|
+
|
|
698
|
+
// ../core/src/app-url.ts
|
|
699
|
+
var PRODUCTION_APP_URL = "https://app.robotrock.io";
|
|
700
|
+
var PRODUCTION_API_URL = "https://api.robotrock.io/v1";
|
|
701
|
+
var DEV_API_URL = "http://localhost:4001/v1";
|
|
702
|
+
var APP_SIGNUP_URL = `${PRODUCTION_APP_URL}/sign-up`;
|
|
703
|
+
function normalizeRobotRockApiBaseUrl(baseUrl) {
|
|
704
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
705
|
+
if (trimmed.endsWith("/v1")) {
|
|
706
|
+
return trimmed;
|
|
707
|
+
}
|
|
708
|
+
return `${trimmed}/v1`;
|
|
709
|
+
}
|
|
710
|
+
function getRobotRockApiBaseUrl() {
|
|
711
|
+
const explicit = process.env.ROBOTROCK_BASE_URL?.trim() || process.env.ROBOTROCK_API_URL?.trim();
|
|
712
|
+
if (explicit) {
|
|
713
|
+
return normalizeRobotRockApiBaseUrl(explicit);
|
|
714
|
+
}
|
|
715
|
+
if (process.env.NODE_ENV === "production") {
|
|
716
|
+
return PRODUCTION_API_URL;
|
|
717
|
+
}
|
|
718
|
+
return DEV_API_URL;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// ../core/src/attribution/index.ts
|
|
722
|
+
var ATTRIBUTION_COOKIE_MAX_AGE = 60 * 60 * 24 * 90;
|
|
723
|
+
var attributionSchema = z4.object({
|
|
724
|
+
utmSource: z4.string().optional(),
|
|
725
|
+
utmMedium: z4.string().optional(),
|
|
726
|
+
utmCampaign: z4.string().optional(),
|
|
727
|
+
utmContent: z4.string().optional(),
|
|
728
|
+
utmTerm: z4.string().optional(),
|
|
729
|
+
gclid: z4.string().optional(),
|
|
730
|
+
landingUrl: z4.string().optional(),
|
|
731
|
+
referrer: z4.string().optional(),
|
|
732
|
+
capturedAt: z4.number()
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
// src/auth-headers.ts
|
|
736
|
+
var ROBOTROCK_ACTING_USER_ID_HEADER = "x-robotrock-acting-user-id";
|
|
737
|
+
function buildRobotRockAuthHeaders(auth) {
|
|
738
|
+
if (auth.kind === "apiKey") {
|
|
739
|
+
const headers2 = {
|
|
740
|
+
"X-Api-Key": auth.apiKey
|
|
741
|
+
};
|
|
742
|
+
if (auth.actingUserId?.trim()) {
|
|
743
|
+
headers2[ROBOTROCK_ACTING_USER_ID_HEADER] = auth.actingUserId.trim();
|
|
744
|
+
}
|
|
745
|
+
return headers2;
|
|
746
|
+
}
|
|
747
|
+
const headers = {
|
|
748
|
+
Authorization: `Bearer ${auth.token}`,
|
|
749
|
+
"X-RobotRock-Tenant-Slug": auth.tenantSlug,
|
|
750
|
+
"X-RobotRock-Connection-Id": auth.connectionId
|
|
751
|
+
};
|
|
752
|
+
if (auth.actingUserId?.trim()) {
|
|
753
|
+
headers[ROBOTROCK_ACTING_USER_ID_HEADER] = auth.actingUserId.trim();
|
|
754
|
+
}
|
|
755
|
+
return headers;
|
|
756
|
+
}
|
|
757
|
+
function resolveRobotRockAuthConfig(overrides) {
|
|
758
|
+
if (overrides?.agentService) {
|
|
759
|
+
return {
|
|
760
|
+
kind: "agentService",
|
|
761
|
+
...overrides.agentService
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;
|
|
765
|
+
if (!apiKey) {
|
|
766
|
+
throw new Error(
|
|
767
|
+
"RobotRock auth is required. Set ROBOTROCK_API_KEY, ROBOTROCK_AGENT_SERVICE_TOKEN with tenant context, or pass auth when creating the client."
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
return {
|
|
771
|
+
kind: "apiKey",
|
|
772
|
+
apiKey,
|
|
773
|
+
...overrides?.actingUserId?.trim() ? { actingUserId: overrides.actingUserId.trim() } : {}
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// src/eve/agent/attributes.ts
|
|
778
|
+
function readStringAttribute(attributes, key) {
|
|
779
|
+
const value = attributes?.[key];
|
|
780
|
+
if (typeof value === "string" && value.length > 0) {
|
|
781
|
+
return value;
|
|
782
|
+
}
|
|
783
|
+
if (Array.isArray(value) && typeof value[0] === "string" && value[0].length > 0) {
|
|
784
|
+
return value[0];
|
|
785
|
+
}
|
|
786
|
+
return void 0;
|
|
787
|
+
}
|
|
788
|
+
function readStringArrayAttribute(attributes, key) {
|
|
789
|
+
const value = attributes?.[key];
|
|
790
|
+
if (typeof value === "string" && value.length > 0) {
|
|
791
|
+
return [value];
|
|
792
|
+
}
|
|
793
|
+
if (Array.isArray(value)) {
|
|
794
|
+
return value.filter(
|
|
795
|
+
(entry) => typeof entry === "string" && entry.length > 0
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
return [];
|
|
799
|
+
}
|
|
800
|
+
function parseTenantRole(value) {
|
|
801
|
+
if (value === "admin" || value === "member") {
|
|
802
|
+
return value;
|
|
803
|
+
}
|
|
804
|
+
return null;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
// src/eve/agent/tenant.ts
|
|
808
|
+
function tryResolveTenantCaller(ctx) {
|
|
809
|
+
const caller = ctx.session.auth.initiator ?? ctx.session.auth.current;
|
|
810
|
+
if (caller?.principalType !== "user") {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
const email = readStringAttribute(caller.attributes, "email");
|
|
814
|
+
const name = readStringAttribute(caller.attributes, "name");
|
|
815
|
+
const tenantSlug = readStringAttribute(caller.attributes, "tenantSlug") ?? readStringAttribute(caller.attributes, "tenantId");
|
|
816
|
+
const role = parseTenantRole(readStringAttribute(caller.attributes, "role"));
|
|
817
|
+
if (!email || !tenantSlug || !caller.principalId || !role) {
|
|
818
|
+
return null;
|
|
819
|
+
}
|
|
820
|
+
const workosUserId = readStringAttribute(caller.attributes, "workosUserId");
|
|
821
|
+
const connectionId = readStringAttribute(caller.attributes, "connectionId");
|
|
822
|
+
const chatId = readStringAttribute(caller.attributes, "chatId");
|
|
823
|
+
const groups = readStringArrayAttribute(caller.attributes, "groups");
|
|
824
|
+
return {
|
|
825
|
+
userId: caller.principalId,
|
|
826
|
+
email,
|
|
827
|
+
name: name ?? email.split("@")[0] ?? email,
|
|
828
|
+
tenantSlug,
|
|
829
|
+
...connectionId ? { connectionId } : {},
|
|
830
|
+
...chatId ? { chatId } : {},
|
|
831
|
+
role,
|
|
832
|
+
isAdmin: role === "admin",
|
|
833
|
+
groups,
|
|
834
|
+
...workosUserId ? { workosUserId } : {}
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
function requireTenantCaller(ctx) {
|
|
838
|
+
const caller = tryResolveTenantCaller(ctx);
|
|
839
|
+
if (!caller) {
|
|
840
|
+
throw new Error("An authenticated RobotRock tenant user is required.");
|
|
841
|
+
}
|
|
842
|
+
return caller;
|
|
843
|
+
}
|
|
844
|
+
function requireAdminCaller(ctx) {
|
|
845
|
+
const caller = requireTenantCaller(ctx);
|
|
846
|
+
if (!caller.isAdmin) {
|
|
847
|
+
throw new Error("Tenant admin access is required.");
|
|
848
|
+
}
|
|
849
|
+
return caller;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// src/chat-correlation.ts
|
|
853
|
+
var ROBOTROCK_CHAT_ID_HEADER = "x-robotrock-chat-id";
|
|
854
|
+
var ROBOTROCK_EVE_SESSION_ID_HEADER = "x-robotrock-eve-session-id";
|
|
855
|
+
function resolveChatCorrelationFromEnv() {
|
|
856
|
+
const chatId = process.env.ROBOTROCK_CHAT_ID?.trim();
|
|
857
|
+
const eveSessionId = process.env.ROBOTROCK_EVE_SESSION_ID?.trim();
|
|
858
|
+
if (!chatId && !eveSessionId) {
|
|
859
|
+
return void 0;
|
|
860
|
+
}
|
|
861
|
+
return {
|
|
862
|
+
...chatId ? { chatId } : {},
|
|
863
|
+
...eveSessionId ? { eveSessionId } : {}
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
function buildChatCorrelationHeaders(correlation) {
|
|
867
|
+
if (!correlation) {
|
|
868
|
+
return {};
|
|
869
|
+
}
|
|
870
|
+
const headers = {};
|
|
871
|
+
const chatId = correlation.chatId?.trim();
|
|
872
|
+
const eveSessionId = correlation.eveSessionId?.trim();
|
|
873
|
+
if (chatId) {
|
|
874
|
+
headers[ROBOTROCK_CHAT_ID_HEADER] = chatId;
|
|
875
|
+
}
|
|
876
|
+
if (eveSessionId) {
|
|
877
|
+
headers[ROBOTROCK_EVE_SESSION_ID_HEADER] = eveSessionId;
|
|
878
|
+
}
|
|
879
|
+
return headers;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
// src/agent-admin.ts
|
|
883
|
+
async function agentAdminFetch(config, path, init) {
|
|
884
|
+
const baseUrl = (config.baseUrl?.trim() || getRobotRockApiBaseUrl()).replace(
|
|
885
|
+
/\/+$/,
|
|
886
|
+
""
|
|
887
|
+
);
|
|
888
|
+
const url = `${baseUrl}/agent-admin${path}`;
|
|
889
|
+
const response = await fetch(url, {
|
|
890
|
+
...init,
|
|
891
|
+
headers: {
|
|
892
|
+
"Content-Type": "application/json",
|
|
893
|
+
...buildRobotRockAuthHeaders(config.auth),
|
|
894
|
+
...buildChatCorrelationHeaders(config.chatCorrelation),
|
|
895
|
+
...init?.headers ?? {}
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
const data = await parseResponseBody(response);
|
|
899
|
+
if (!response.ok) {
|
|
900
|
+
throw new RobotRockError(
|
|
901
|
+
getErrorMessage(data, `Agent admin request failed (${response.status})`),
|
|
902
|
+
response.status,
|
|
903
|
+
data
|
|
904
|
+
);
|
|
905
|
+
}
|
|
906
|
+
return data;
|
|
907
|
+
}
|
|
908
|
+
function createAgentAdminApi(config) {
|
|
909
|
+
return {
|
|
910
|
+
usage: {
|
|
911
|
+
get: () => agentAdminFetch(config, "/usage")
|
|
912
|
+
},
|
|
913
|
+
members: {
|
|
914
|
+
list: () => agentAdminFetch(config, "/members"),
|
|
915
|
+
get: (memberRef) => agentAdminFetch(config, `/members/${encodeURIComponent(memberRef)}`),
|
|
916
|
+
invite: (body) => agentAdminFetch(config, "/members", {
|
|
917
|
+
method: "POST",
|
|
918
|
+
body: JSON.stringify(body)
|
|
919
|
+
}),
|
|
920
|
+
updateRole: (memberRef, role) => agentAdminFetch(
|
|
921
|
+
config,
|
|
922
|
+
`/members/${encodeURIComponent(memberRef)}/role`,
|
|
923
|
+
{
|
|
924
|
+
method: "PATCH",
|
|
925
|
+
body: JSON.stringify({ role })
|
|
926
|
+
}
|
|
927
|
+
),
|
|
928
|
+
remove: (memberId) => agentAdminFetch(
|
|
929
|
+
config,
|
|
930
|
+
`/members/${encodeURIComponent(memberId)}`,
|
|
931
|
+
{
|
|
932
|
+
method: "DELETE"
|
|
933
|
+
}
|
|
934
|
+
)
|
|
935
|
+
},
|
|
936
|
+
groups: {
|
|
937
|
+
list: () => agentAdminFetch(config, "/groups"),
|
|
938
|
+
get: (groupId) => agentAdminFetch(
|
|
939
|
+
config,
|
|
940
|
+
`/groups/${encodeURIComponent(groupId)}`
|
|
941
|
+
),
|
|
942
|
+
create: (body) => agentAdminFetch(config, "/groups", {
|
|
943
|
+
method: "POST",
|
|
944
|
+
body: JSON.stringify(body)
|
|
945
|
+
}),
|
|
946
|
+
update: (groupId, body) => agentAdminFetch(
|
|
947
|
+
config,
|
|
948
|
+
`/groups/${encodeURIComponent(groupId)}`,
|
|
949
|
+
{
|
|
950
|
+
method: "PATCH",
|
|
951
|
+
body: JSON.stringify(body)
|
|
952
|
+
}
|
|
953
|
+
),
|
|
954
|
+
delete: (groupId) => agentAdminFetch(
|
|
955
|
+
config,
|
|
956
|
+
`/groups/${encodeURIComponent(groupId)}`,
|
|
957
|
+
{
|
|
958
|
+
method: "DELETE"
|
|
959
|
+
}
|
|
960
|
+
),
|
|
961
|
+
addMember: (groupRef, memberRef) => agentAdminFetch(
|
|
962
|
+
config,
|
|
963
|
+
`/groups/${encodeURIComponent(groupRef)}/members`,
|
|
964
|
+
{
|
|
965
|
+
method: "POST",
|
|
966
|
+
body: JSON.stringify({ userId: memberRef })
|
|
967
|
+
}
|
|
968
|
+
),
|
|
969
|
+
removeMember: (groupRef, memberRef) => agentAdminFetch(
|
|
970
|
+
config,
|
|
971
|
+
`/groups/${encodeURIComponent(groupRef)}/members/${encodeURIComponent(memberRef)}`,
|
|
972
|
+
{ method: "DELETE" }
|
|
973
|
+
)
|
|
974
|
+
},
|
|
975
|
+
tasks: {
|
|
976
|
+
list: (query) => {
|
|
977
|
+
const params = new URLSearchParams();
|
|
978
|
+
for (const [key, value] of Object.entries(query ?? {})) {
|
|
979
|
+
if (value !== void 0 && value !== "") {
|
|
980
|
+
params.set(key, String(value));
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
const suffix = params.size > 0 ? `?${params.toString()}` : "";
|
|
984
|
+
return agentAdminFetch(
|
|
985
|
+
config,
|
|
986
|
+
`/tasks${suffix}`
|
|
987
|
+
);
|
|
988
|
+
},
|
|
989
|
+
search: (q, limit) => {
|
|
990
|
+
const params = new URLSearchParams({ q });
|
|
991
|
+
if (limit !== void 0) {
|
|
992
|
+
params.set("limit", String(limit));
|
|
993
|
+
}
|
|
994
|
+
return agentAdminFetch(
|
|
995
|
+
config,
|
|
996
|
+
`/tasks/search?${params.toString()}`
|
|
997
|
+
);
|
|
998
|
+
},
|
|
999
|
+
get: (taskId) => agentAdminFetch(config, `/tasks/${taskId}`),
|
|
1000
|
+
assign: (body) => agentAdminFetch(config, "/tasks/assign", {
|
|
1001
|
+
method: "POST",
|
|
1002
|
+
body: JSON.stringify(body)
|
|
1003
|
+
})
|
|
1004
|
+
}
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
function resolveBoundChatCorrelation(ctx) {
|
|
1008
|
+
const caller = tryResolveTenantCaller(ctx);
|
|
1009
|
+
return {
|
|
1010
|
+
eveSessionId: ctx.session.id,
|
|
1011
|
+
...caller?.chatId ? { chatId: caller.chatId } : {},
|
|
1012
|
+
...resolveChatCorrelationFromEnv()
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
function createBoundAgentAdminClient(ctx) {
|
|
1016
|
+
const caller = requireTenantCaller(ctx);
|
|
1017
|
+
const baseUrl = process.env.ROBOTROCK_BASE_URL?.trim();
|
|
1018
|
+
const serviceToken = process.env.ROBOTROCK_AGENT_SERVICE_TOKEN?.trim();
|
|
1019
|
+
const chatCorrelation = resolveBoundChatCorrelation(ctx);
|
|
1020
|
+
if (caller.connectionId && serviceToken) {
|
|
1021
|
+
return createAgentAdminApi({
|
|
1022
|
+
baseUrl,
|
|
1023
|
+
chatCorrelation,
|
|
1024
|
+
auth: resolveRobotRockAuthConfig({
|
|
1025
|
+
agentService: {
|
|
1026
|
+
token: serviceToken,
|
|
1027
|
+
tenantSlug: caller.tenantSlug,
|
|
1028
|
+
connectionId: caller.connectionId,
|
|
1029
|
+
actingUserId: caller.userId
|
|
1030
|
+
}
|
|
1031
|
+
})
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
const apiKey = process.env.ROBOTROCK_API_KEY?.trim();
|
|
1035
|
+
if (apiKey) {
|
|
1036
|
+
return createAgentAdminApi({
|
|
1037
|
+
baseUrl,
|
|
1038
|
+
chatCorrelation,
|
|
1039
|
+
auth: {
|
|
1040
|
+
kind: "apiKey",
|
|
1041
|
+
apiKey,
|
|
1042
|
+
actingUserId: caller.userId
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
throw new Error(
|
|
1047
|
+
"Agent admin auth is unset. Set ROBOTROCK_AGENT_SERVICE_TOKEN for hosted multi-tenant agents, or ROBOTROCK_API_KEY for self-hosted and localhost deployments."
|
|
1048
|
+
);
|
|
1049
|
+
}
|
|
1050
|
+
function requireBoundAgentAdminClient(ctx) {
|
|
1051
|
+
requireAdminCaller(ctx);
|
|
1052
|
+
return createBoundAgentAdminClient(ctx);
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
// src/eve/entity-schemas.ts
|
|
1056
|
+
import { z as z5 } from "zod";
|
|
1057
|
+
|
|
1058
|
+
// src/eve/tool-ui-hint.ts
|
|
1059
|
+
var TOOL_UI_HINT_FIELD = "uiHint";
|
|
1060
|
+
function withUiHint(result, hint) {
|
|
1061
|
+
return {
|
|
1062
|
+
...result,
|
|
1063
|
+
[TOOL_UI_HINT_FIELD]: hint
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/eve/tool-result-ui-meta.ts
|
|
1068
|
+
var TOOL_UI_FIELD = "ui";
|
|
1069
|
+
var TOOL_RESULT_UI_ENTITY_ID_RE = /^[a-z][a-z0-9_]{0,63}$/;
|
|
1070
|
+
function withToolUi(result, ui) {
|
|
1071
|
+
const existing = typeof result[TOOL_UI_FIELD] === "object" && result[TOOL_UI_FIELD] !== null && !Array.isArray(result[TOOL_UI_FIELD]) ? result[TOOL_UI_FIELD] : {};
|
|
1072
|
+
return {
|
|
1073
|
+
...result,
|
|
1074
|
+
[TOOL_UI_FIELD]: {
|
|
1075
|
+
...existing,
|
|
1076
|
+
...ui
|
|
1077
|
+
}
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
// src/eve/entity-schemas.ts
|
|
1082
|
+
var toolResultUiMetaSchema = z5.object({
|
|
1083
|
+
present: z5.boolean().optional(),
|
|
1084
|
+
entity: z5.string().regex(TOOL_RESULT_UI_ENTITY_ID_RE).optional(),
|
|
1085
|
+
rowsPath: z5.string().min(1).optional(),
|
|
1086
|
+
layout: z5.enum(["list", "chart", "table"]).optional()
|
|
1087
|
+
}).strict();
|
|
1088
|
+
var agentOnlyFields = {
|
|
1089
|
+
replyGuidance: z5.string().optional(),
|
|
1090
|
+
ui: toolResultUiMetaSchema.optional(),
|
|
1091
|
+
uiHint: z5.enum(["list", "chart", "table"]).optional()
|
|
1092
|
+
};
|
|
1093
|
+
function withAgentOnlyFields(shape) {
|
|
1094
|
+
return z5.object({
|
|
1095
|
+
...shape,
|
|
1096
|
+
...agentOnlyFields
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
var productEntityRowSchema = z5.object({
|
|
1100
|
+
id: z5.string().min(1),
|
|
1101
|
+
name: z5.string().min(1),
|
|
1102
|
+
price: z5.number(),
|
|
1103
|
+
currency: z5.string().min(1),
|
|
1104
|
+
inStock: z5.boolean(),
|
|
1105
|
+
url: z5.string().min(1)
|
|
1106
|
+
});
|
|
1107
|
+
var metricPointEntityRowSchema = z5.object({
|
|
1108
|
+
date: z5.string().optional().describe("X-axis value when xKey is date/time"),
|
|
1109
|
+
category: z5.string().optional().describe("X-axis value when xKey is category"),
|
|
1110
|
+
label: z5.string().optional().describe("X-axis value when xKey is label")
|
|
1111
|
+
}).catchall(z5.union([z5.string(), z5.number()])).describe(
|
|
1112
|
+
"Wide chart point: x-axis field + numeric columns named by yKeys (one series per column)"
|
|
1113
|
+
);
|
|
1114
|
+
var toolChartResultSchema = withAgentOnlyFields({
|
|
1115
|
+
title: z5.string().min(1).optional().describe("Chart title shown above the plot"),
|
|
1116
|
+
description: z5.string().min(1).optional().describe("Optional short subtitle"),
|
|
1117
|
+
type: z5.enum(["line", "bar", "area"]).describe("TRL/shadcn chart variant (time series \u2192 line, categories \u2192 bar)"),
|
|
1118
|
+
xKey: z5.string().min(1).describe('Field on each series row for the x-axis, e.g. "date" or "category"'),
|
|
1119
|
+
yKeys: z5.array(z5.string().min(1)).min(1).describe(
|
|
1120
|
+
'Numeric series column names on each row, e.g. ["NL","BE"] or ["created","handled"]'
|
|
1121
|
+
),
|
|
1122
|
+
series: z5.array(metricPointEntityRowSchema).describe(
|
|
1123
|
+
"Wide-format points only \u2014 one object per x value with yKeys as numeric fields"
|
|
1124
|
+
)
|
|
1125
|
+
});
|
|
1126
|
+
var memberEntityRowSchema = z5.object({
|
|
1127
|
+
name: z5.string(),
|
|
1128
|
+
email: z5.string(),
|
|
1129
|
+
role: z5.string(),
|
|
1130
|
+
membershipKind: z5.string(),
|
|
1131
|
+
profilePictureUrl: z5.string().nullable()
|
|
1132
|
+
});
|
|
1133
|
+
var taskEntityRowSchema = z5.object({
|
|
1134
|
+
id: z5.string().min(1),
|
|
1135
|
+
name: z5.string().min(1),
|
|
1136
|
+
status: z5.string().min(1),
|
|
1137
|
+
type: z5.string().nullable(),
|
|
1138
|
+
description: z5.string().nullable(),
|
|
1139
|
+
validUntil: z5.number(),
|
|
1140
|
+
createdAt: z5.number(),
|
|
1141
|
+
url: z5.string().min(1),
|
|
1142
|
+
threadPriority: z5.string().nullable().optional()
|
|
1143
|
+
});
|
|
1144
|
+
var groupEntityRowSchema = z5.object({
|
|
1145
|
+
name: z5.string().min(1),
|
|
1146
|
+
slug: z5.string().min(1),
|
|
1147
|
+
description: z5.string().nullable(),
|
|
1148
|
+
memberCount: z5.number().nullable(),
|
|
1149
|
+
url: z5.string().min(1)
|
|
1150
|
+
});
|
|
1151
|
+
var groupDetailEntitySchema = z5.object({
|
|
1152
|
+
name: z5.string().min(1),
|
|
1153
|
+
slug: z5.string().min(1),
|
|
1154
|
+
description: z5.string().nullable(),
|
|
1155
|
+
url: z5.string().min(1),
|
|
1156
|
+
members: z5.array(
|
|
1157
|
+
z5.object({
|
|
1158
|
+
name: z5.string(),
|
|
1159
|
+
email: z5.string(),
|
|
1160
|
+
profilePictureUrl: z5.string().nullable()
|
|
1161
|
+
})
|
|
1162
|
+
)
|
|
1163
|
+
});
|
|
1164
|
+
var statusEntityRowSchema = z5.object({
|
|
1165
|
+
id: z5.string().min(1),
|
|
1166
|
+
name: z5.string().min(1),
|
|
1167
|
+
status: z5.string().min(1),
|
|
1168
|
+
url: z5.string().min(1),
|
|
1169
|
+
type: z5.string().nullable().optional(),
|
|
1170
|
+
description: z5.string().nullable().optional()
|
|
1171
|
+
});
|
|
1172
|
+
var agentAdminErrorResultSchema = z5.object({
|
|
1173
|
+
ok: z5.literal(false),
|
|
1174
|
+
status: z5.number().optional(),
|
|
1175
|
+
message: z5.string(),
|
|
1176
|
+
response: z5.unknown().optional()
|
|
1177
|
+
});
|
|
1178
|
+
var agentAdminMutationResultSchema = z5.object({
|
|
1179
|
+
...agentOnlyFields
|
|
1180
|
+
}).passthrough();
|
|
1181
|
+
var searchProductsOutputSchema = withAgentOnlyFields({
|
|
1182
|
+
items: z5.array(productEntityRowSchema)
|
|
1183
|
+
});
|
|
1184
|
+
var generateRandomChartOutputSchema = toolChartResultSchema.extend({
|
|
1185
|
+
title: z5.string().min(1)
|
|
1186
|
+
});
|
|
1187
|
+
var generateImageOutputSchema = withAgentOnlyFields({
|
|
1188
|
+
prompt: z5.string().min(1),
|
|
1189
|
+
mediaType: z5.string().min(1),
|
|
1190
|
+
model: z5.string().min(1),
|
|
1191
|
+
storageId: z5.string().min(1),
|
|
1192
|
+
url: z5.string().min(1),
|
|
1193
|
+
/** @deprecated Legacy sessions only — prefer storageId/url. */
|
|
1194
|
+
base64: z5.string().min(1).optional()
|
|
1195
|
+
});
|
|
1196
|
+
var manageTeamMembersListOutputSchema = withAgentOnlyFields({
|
|
1197
|
+
members: z5.array(memberEntityRowSchema)
|
|
1198
|
+
});
|
|
1199
|
+
var manageTeamMembersDetailOutputSchema = withAgentOnlyFields(
|
|
1200
|
+
memberEntityRowSchema.shape
|
|
1201
|
+
);
|
|
1202
|
+
var manageTeamMembersOutputSchema = z5.union([
|
|
1203
|
+
manageTeamMembersListOutputSchema,
|
|
1204
|
+
manageTeamMembersDetailOutputSchema,
|
|
1205
|
+
agentAdminMutationResultSchema,
|
|
1206
|
+
agentAdminErrorResultSchema
|
|
1207
|
+
]);
|
|
1208
|
+
var manageGroupsListOutputSchema = withAgentOnlyFields({
|
|
1209
|
+
groups: z5.array(groupEntityRowSchema)
|
|
1210
|
+
});
|
|
1211
|
+
var manageGroupsDetailOutputSchema = withAgentOnlyFields(
|
|
1212
|
+
groupDetailEntitySchema.shape
|
|
1213
|
+
);
|
|
1214
|
+
var manageGroupsSummaryOutputSchema = withAgentOnlyFields(
|
|
1215
|
+
groupEntityRowSchema.shape
|
|
1216
|
+
);
|
|
1217
|
+
var manageGroupsOutputSchema = z5.union([
|
|
1218
|
+
manageGroupsListOutputSchema,
|
|
1219
|
+
manageGroupsDetailOutputSchema,
|
|
1220
|
+
manageGroupsSummaryOutputSchema,
|
|
1221
|
+
agentAdminMutationResultSchema,
|
|
1222
|
+
agentAdminErrorResultSchema
|
|
1223
|
+
]);
|
|
1224
|
+
var queryTasksListOutputSchema = withAgentOnlyFields({
|
|
1225
|
+
items: z5.array(taskEntityRowSchema),
|
|
1226
|
+
nextCursor: z5.string().nullable().optional()
|
|
1227
|
+
});
|
|
1228
|
+
var queryTasksDetailOutputSchema = withAgentOnlyFields({
|
|
1229
|
+
id: z5.string().nullable(),
|
|
1230
|
+
status: z5.string().nullable(),
|
|
1231
|
+
type: z5.string().nullable(),
|
|
1232
|
+
name: z5.string().nullable(),
|
|
1233
|
+
description: z5.string().nullable(),
|
|
1234
|
+
validUntil: z5.number().nullable(),
|
|
1235
|
+
createdAt: z5.number().nullable(),
|
|
1236
|
+
url: z5.string().min(1).nullable()
|
|
1237
|
+
});
|
|
1238
|
+
var queryTasksOutputSchema = z5.union([
|
|
1239
|
+
queryTasksListOutputSchema,
|
|
1240
|
+
queryTasksDetailOutputSchema,
|
|
1241
|
+
agentAdminErrorResultSchema
|
|
1242
|
+
]);
|
|
1243
|
+
var assignTasksOutputSchema = z5.union([
|
|
1244
|
+
withAgentOnlyFields({
|
|
1245
|
+
results: z5.array(statusEntityRowSchema)
|
|
1246
|
+
}),
|
|
1247
|
+
agentAdminErrorResultSchema
|
|
1248
|
+
]);
|
|
1249
|
+
var workspaceUsageEntitySchema = z5.object({
|
|
1250
|
+
workspace: z5.string(),
|
|
1251
|
+
plan: z5.string(),
|
|
1252
|
+
planType: z5.string(),
|
|
1253
|
+
trialState: z5.string(),
|
|
1254
|
+
daysRemaining: z5.number().nullable(),
|
|
1255
|
+
isPaidPro: z5.boolean(),
|
|
1256
|
+
subscriptionStatus: z5.string(),
|
|
1257
|
+
tasksToday: z5.string(),
|
|
1258
|
+
tasksResetAt: z5.string(),
|
|
1259
|
+
openTasks: z5.number(),
|
|
1260
|
+
totalTasks: z5.number(),
|
|
1261
|
+
seats: z5.string(),
|
|
1262
|
+
groups: z5.string(),
|
|
1263
|
+
apiKeys: z5.string(),
|
|
1264
|
+
rateLimitPerSecond: z5.number()
|
|
1265
|
+
});
|
|
1266
|
+
var getWorkspaceUsageOutputSchema = z5.union([
|
|
1267
|
+
withAgentOnlyFields({
|
|
1268
|
+
usage: workspaceUsageEntitySchema
|
|
1269
|
+
}),
|
|
1270
|
+
agentAdminErrorResultSchema
|
|
1271
|
+
]);
|
|
1272
|
+
|
|
1273
|
+
// src/eve/tool-reply-guidance.ts
|
|
1274
|
+
var TOOL_REPLY_GUIDANCE_FIELD = "replyGuidance";
|
|
1275
|
+
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.";
|
|
1276
|
+
function withReplyGuidance(result, guidance) {
|
|
1277
|
+
return {
|
|
1278
|
+
...result,
|
|
1279
|
+
[TOOL_REPLY_GUIDANCE_FIELD]: guidance
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
// src/eve/tool-display-format.ts
|
|
1284
|
+
function formatToolObjectResult(data, options) {
|
|
1285
|
+
let result = withReplyGuidance(
|
|
1286
|
+
data,
|
|
1287
|
+
options.replyGuidance
|
|
1288
|
+
);
|
|
1289
|
+
if (options.ui) {
|
|
1290
|
+
result = withToolUi(result, options.ui);
|
|
1291
|
+
}
|
|
1292
|
+
if (options.uiHint) {
|
|
1293
|
+
result = withUiHint(result, options.uiHint);
|
|
1294
|
+
}
|
|
1295
|
+
return result;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// src/eve/tools/admin/format-workspace-usage.ts
|
|
1299
|
+
function formatLimit(current, max) {
|
|
1300
|
+
return max === null ? `${current} / unlimited` : `${current} / ${max}`;
|
|
1301
|
+
}
|
|
1302
|
+
function formatWorkspaceUsageResult(usage) {
|
|
1303
|
+
const tasksLimit = usage.maxTasksPerDay === null ? `${usage.tasksToday} / unlimited` : `${usage.tasksToday} / ${usage.maxTasksPerDay}`;
|
|
1304
|
+
return formatToolObjectResult(
|
|
1305
|
+
{
|
|
1306
|
+
usage: {
|
|
1307
|
+
workspace: usage.workspace,
|
|
1308
|
+
plan: usage.planName,
|
|
1309
|
+
planType: usage.planType,
|
|
1310
|
+
trialState: usage.trialState,
|
|
1311
|
+
daysRemaining: usage.daysRemaining,
|
|
1312
|
+
isPaidPro: usage.isPaidPro,
|
|
1313
|
+
subscriptionStatus: usage.subscriptionStatus ?? "\u2014",
|
|
1314
|
+
tasksToday: tasksLimit,
|
|
1315
|
+
tasksResetAt: new Date(usage.tasksResetAt).toISOString(),
|
|
1316
|
+
openTasks: usage.openTasks,
|
|
1317
|
+
totalTasks: usage.totalTasks,
|
|
1318
|
+
seats: formatLimit(usage.seatsCurrent, usage.seatsMax),
|
|
1319
|
+
groups: formatLimit(usage.groupsCurrent, usage.groupsMax),
|
|
1320
|
+
apiKeys: formatLimit(usage.apiKeysCurrent, usage.apiKeysMax),
|
|
1321
|
+
rateLimitPerSecond: usage.rateLimitPerSecond
|
|
1322
|
+
}
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
replyGuidance: GET_WORKSPACE_USAGE_REPLY_GUIDANCE,
|
|
1326
|
+
ui: { entity: "usage" }
|
|
1327
|
+
}
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// src/eve/tools/admin/get-workspace-usage.ts
|
|
1332
|
+
var GET_WORKSPACE_USAGE_TOOL_NAME = "get_workspace_usage";
|
|
1333
|
+
var getWorkspaceUsageInputSchema = z6.object({});
|
|
1334
|
+
function defineGetWorkspaceUsageTool() {
|
|
1335
|
+
return defineTool({
|
|
1336
|
+
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.",
|
|
1337
|
+
inputSchema: getWorkspaceUsageInputSchema,
|
|
1338
|
+
outputSchema: getWorkspaceUsageOutputSchema,
|
|
1339
|
+
async execute(_input, ctx) {
|
|
1340
|
+
const api = requireBoundAgentAdminClient(ctx);
|
|
1341
|
+
try {
|
|
1342
|
+
const result = await api.usage.get();
|
|
1343
|
+
return formatWorkspaceUsageResult(result.usage);
|
|
1344
|
+
} catch (error) {
|
|
1345
|
+
if (error instanceof RobotRockError) {
|
|
1346
|
+
return {
|
|
1347
|
+
ok: false,
|
|
1348
|
+
status: error.statusCode,
|
|
1349
|
+
message: error.message,
|
|
1350
|
+
response: error.response
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
throw error;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
var getWorkspaceUsageTool = defineGetWorkspaceUsageTool();
|
|
1359
|
+
export {
|
|
1360
|
+
GET_WORKSPACE_USAGE_TOOL_NAME,
|
|
1361
|
+
defineGetWorkspaceUsageTool,
|
|
1362
|
+
getWorkspaceUsageInputSchema,
|
|
1363
|
+
getWorkspaceUsageTool
|
|
1364
|
+
};
|
|
1365
|
+
//# sourceMappingURL=get-workspace-usage.js.map
|