robotrock 0.8.1 → 0.8.3
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/dist/ai/index.js +455 -35
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/trigger.js +455 -35
- package/dist/ai/trigger.js.map +1 -1
- package/dist/ai/workflow.js +455 -35
- package/dist/ai/workflow.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +384 -38
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.d.ts +5 -1
- package/dist/schemas/index.js +373 -27
- package/dist/schemas/index.js.map +1 -1
- package/dist/trigger/index.js +352 -7
- package/dist/trigger/index.js.map +1 -1
- package/dist/workflow/index.js +352 -7
- package/dist/workflow/index.js.map +1 -1
- package/package.json +1 -4
package/dist/ai/index.js
CHANGED
|
@@ -53,13 +53,237 @@ var __callDispose = (stack, error, hasError) => {
|
|
|
53
53
|
return next();
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
//
|
|
56
|
+
// ../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
57
|
+
var init_clsx = __esm({
|
|
58
|
+
"../../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs"() {
|
|
59
|
+
"use strict";
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// ../core/src/utils/cn.ts
|
|
64
|
+
var init_cn = __esm({
|
|
65
|
+
"../core/src/utils/cn.ts"() {
|
|
66
|
+
"use strict";
|
|
67
|
+
init_clsx();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// ../core/src/utils/convex-sanitize.ts
|
|
72
|
+
var init_convex_sanitize = __esm({
|
|
73
|
+
"../core/src/utils/convex-sanitize.ts"() {
|
|
74
|
+
"use strict";
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// ../core/src/utils/safe-url.ts
|
|
79
|
+
function normalizeHostname(hostname) {
|
|
80
|
+
return hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
81
|
+
}
|
|
82
|
+
function isBlockedIpv4(host) {
|
|
83
|
+
const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
|
|
84
|
+
if (!match) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const octets = match.slice(1, 5).map((part) => Number(part));
|
|
88
|
+
if (octets.some((octet) => Number.isNaN(octet) || octet < 0 || octet > 255)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
const [a, b, _c, _d] = octets;
|
|
92
|
+
if (a === void 0 || b === void 0) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if (a === 127 || a === 0) return true;
|
|
96
|
+
if (a === 10) return true;
|
|
97
|
+
if (a === 169 && b === 254) return true;
|
|
98
|
+
if (a === 192 && b === 168) return true;
|
|
99
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
100
|
+
if (a === 100 && b >= 64 && b <= 127) return true;
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
function ipv4FromNumericHost(host) {
|
|
104
|
+
if (/^\d+$/.test(host)) {
|
|
105
|
+
const num = Number(host);
|
|
106
|
+
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const a = num >>> 24 & 255;
|
|
110
|
+
const b = num >>> 16 & 255;
|
|
111
|
+
const c = num >>> 8 & 255;
|
|
112
|
+
const d = num & 255;
|
|
113
|
+
return `${a}.${b}.${c}.${d}`;
|
|
114
|
+
}
|
|
115
|
+
const hexMatch = /^0x([0-9a-f]{1,8})$/i.exec(host);
|
|
116
|
+
if (hexMatch) {
|
|
117
|
+
const num = Number.parseInt(hexMatch[1], 16);
|
|
118
|
+
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const a = num >>> 24 & 255;
|
|
122
|
+
const b = num >>> 16 & 255;
|
|
123
|
+
const c = num >>> 8 & 255;
|
|
124
|
+
const d = num & 255;
|
|
125
|
+
return `${a}.${b}.${c}.${d}`;
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
function isBlockedIpv4Mapped(host) {
|
|
130
|
+
const mappedDotted = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/i.exec(host);
|
|
131
|
+
if (mappedDotted) {
|
|
132
|
+
return isBlockedIpv4(mappedDotted[1]);
|
|
133
|
+
}
|
|
134
|
+
const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(host);
|
|
135
|
+
if (mappedHex) {
|
|
136
|
+
const high = Number.parseInt(mappedHex[1], 16);
|
|
137
|
+
const low = Number.parseInt(mappedHex[2], 16);
|
|
138
|
+
if (Number.isFinite(high) && Number.isFinite(low)) {
|
|
139
|
+
const a = high >> 8 & 255;
|
|
140
|
+
const b = high & 255;
|
|
141
|
+
const c = low >> 8 & 255;
|
|
142
|
+
const d = low & 255;
|
|
143
|
+
return isBlockedIpv4(`${a}.${b}.${c}.${d}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
function isBlockedIpv6(host) {
|
|
149
|
+
if (host === "::1" || host === "0:0:0:0:0:0:0:1") {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
if (host.startsWith("fc") || host.startsWith("fd")) {
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
if (host.startsWith("fe80:")) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
if (isBlockedIpv4Mapped(host)) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
function isBlockedHostname(hostname) {
|
|
164
|
+
const host = normalizeHostname(hostname);
|
|
165
|
+
if (!host) {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
if (BLOCKED_HOSTNAMES.has(host)) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
if (host.endsWith(".localhost") || host.endsWith(".local")) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
const numericIpv4 = ipv4FromNumericHost(host);
|
|
175
|
+
if (numericIpv4 && isBlockedIpv4(numericIpv4)) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
return isBlockedIpv4(host) || isBlockedIpv6(host);
|
|
179
|
+
}
|
|
180
|
+
function isPublicHttpUrl(urlString) {
|
|
181
|
+
let url;
|
|
182
|
+
try {
|
|
183
|
+
url = new URL(urlString);
|
|
184
|
+
} catch {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
if (url.username || url.password) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return !isBlockedHostname(url.hostname);
|
|
194
|
+
}
|
|
195
|
+
var BLOCKED_HOSTNAMES, PUBLIC_HTTP_URL_ERROR;
|
|
196
|
+
var init_safe_url = __esm({
|
|
197
|
+
"../core/src/utils/safe-url.ts"() {
|
|
198
|
+
"use strict";
|
|
199
|
+
BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
200
|
+
"localhost",
|
|
201
|
+
"metadata.google.internal",
|
|
202
|
+
"metadata.goog"
|
|
203
|
+
]);
|
|
204
|
+
PUBLIC_HTTP_URL_ERROR = "URL must be a public http:// or https:// address";
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// ../core/src/utils/task-app.ts
|
|
209
|
+
var init_task_app = __esm({
|
|
210
|
+
"../core/src/utils/task-app.ts"() {
|
|
211
|
+
"use strict";
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// ../core/src/utils/index.ts
|
|
216
|
+
var init_utils = __esm({
|
|
217
|
+
"../core/src/utils/index.ts"() {
|
|
218
|
+
"use strict";
|
|
219
|
+
init_cn();
|
|
220
|
+
init_convex_sanitize();
|
|
221
|
+
init_safe_url();
|
|
222
|
+
init_task_app();
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// ../core/src/schemas/context-urls.ts
|
|
227
|
+
function resolveLinkUrl(value) {
|
|
228
|
+
return value.startsWith("http://") || value.startsWith("https://") ? value : `https://${value}`;
|
|
229
|
+
}
|
|
230
|
+
function widgetType(ui, field) {
|
|
231
|
+
const fieldUi = ui?.[field];
|
|
232
|
+
if (typeof fieldUi !== "object" || fieldUi === null) {
|
|
233
|
+
return void 0;
|
|
234
|
+
}
|
|
235
|
+
const widget = fieldUi["ui:widget"];
|
|
236
|
+
return typeof widget === "string" ? widget : void 0;
|
|
237
|
+
}
|
|
238
|
+
function validateUrlValue(value, widget) {
|
|
239
|
+
if (widget === "image" || widget === "link") {
|
|
240
|
+
if (typeof value !== "string") {
|
|
241
|
+
return PUBLIC_HTTP_URL_ERROR;
|
|
242
|
+
}
|
|
243
|
+
const url = widget === "link" ? resolveLinkUrl(value) : value;
|
|
244
|
+
if (!isPublicHttpUrl(url)) {
|
|
245
|
+
return PUBLIC_HTTP_URL_ERROR;
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
if (widget === "attachments" && Array.isArray(value)) {
|
|
250
|
+
for (const item of value) {
|
|
251
|
+
if (typeof item !== "object" || item === null) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const url = item.url;
|
|
255
|
+
if (typeof url === "string" && !isPublicHttpUrl(resolveLinkUrl(url))) {
|
|
256
|
+
return PUBLIC_HTTP_URL_ERROR;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
function validateContextPublicUrls(context) {
|
|
263
|
+
if (!context?.data) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
for (const [field, value] of Object.entries(context.data)) {
|
|
267
|
+
const widget = widgetType(context.ui, field);
|
|
268
|
+
if (!widget) {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
const error = validateUrlValue(value, widget);
|
|
272
|
+
if (error) {
|
|
273
|
+
return `context.data.${field}: ${error}`;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
var init_context_urls = __esm({
|
|
279
|
+
"../core/src/schemas/context-urls.ts"() {
|
|
280
|
+
"use strict";
|
|
281
|
+
init_safe_url();
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// ../core/src/schemas/task.ts
|
|
57
286
|
import { z } from "zod";
|
|
58
|
-
import {
|
|
59
|
-
isPublicHttpUrl,
|
|
60
|
-
PUBLIC_HTTP_URL_ERROR
|
|
61
|
-
} from "@robotrock/core/utils";
|
|
62
|
-
import { validateContextPublicUrls } from "@robotrock/core/schemas";
|
|
63
287
|
function refineContextPublicUrls(data, ctx) {
|
|
64
288
|
const error = validateContextPublicUrls(data.context);
|
|
65
289
|
if (error) {
|
|
@@ -70,10 +294,12 @@ function refineContextPublicUrls(data, ctx) {
|
|
|
70
294
|
});
|
|
71
295
|
}
|
|
72
296
|
}
|
|
73
|
-
var safeUrlSchema, jsonSchema7Schema, uiSchemaSchema, webhookHandlerSchema, triggerHandlerSchema, handlerSchema, taskActionSchema, uiFieldSchemaSchema, contextUiSchema, contextDataSchema, taskContextObjectSchema, taskContextSchema, assignToSchema, threadUpdateMessageSchema, threadUpdateStatuses, threadUpdateStatusSchema, threadUpdateInputSchema, taskPriorities, taskPrioritySchema, nonNegativeInt, agentCostTokensSchema, agentCostSchema, AGENT_INFO_MAX_KEYS, agentTelemetrySchema, createTaskBodySchema
|
|
74
|
-
var
|
|
75
|
-
"src/schemas/
|
|
297
|
+
var safeUrlSchema, jsonSchema7Schema, uiSchemaSchema, webhookHandlerSchema, triggerHandlerSchema, handlerSchema, taskActionSchema, uiFieldSchemaSchema, contextUiSchema, contextDataSchema, taskContextObjectSchema, taskContextSchema, assignToSchema, threadUpdateMessageSchema, threadUpdateStatuses, threadUpdateStatusSchema, threadUpdateInputSchema, taskPriorities, taskPrioritySchema, nonNegativeInt, agentCostTokensSchema, agentCostSchema, AGENT_INFO_MAX_KEYS, AGENT_TOOL_CALLS_MAX_KEYS, agentToolCallsSchema, agentTelemetrySchema, createTaskBodySchema;
|
|
298
|
+
var init_task = __esm({
|
|
299
|
+
"../core/src/schemas/task.ts"() {
|
|
76
300
|
"use strict";
|
|
301
|
+
init_safe_url();
|
|
302
|
+
init_context_urls();
|
|
77
303
|
safeUrlSchema = z.string().refine((url) => isPublicHttpUrl(url), {
|
|
78
304
|
message: PUBLIC_HTTP_URL_ERROR
|
|
79
305
|
});
|
|
@@ -101,6 +327,7 @@ var init_schemas = __esm({
|
|
|
101
327
|
schema: jsonSchema7Schema.optional(),
|
|
102
328
|
ui: uiSchemaSchema.optional(),
|
|
103
329
|
data: z.record(z.string(), z.unknown()).optional(),
|
|
330
|
+
// Optional handlers for this action - if present, must have at least 1
|
|
104
331
|
handlers: z.array(handlerSchema).min(1).optional()
|
|
105
332
|
});
|
|
106
333
|
uiFieldSchemaSchema = z.object({
|
|
@@ -116,6 +343,7 @@ var init_schemas = __esm({
|
|
|
116
343
|
ui: contextUiSchema
|
|
117
344
|
}).optional();
|
|
118
345
|
taskContextObjectSchema = z.object({
|
|
346
|
+
/** Source application id; omitted tasks are grouped in the default inbox. */
|
|
119
347
|
app: z.string().min(1).optional(),
|
|
120
348
|
type: z.string().min(1),
|
|
121
349
|
name: z.string().min(1),
|
|
@@ -170,10 +398,17 @@ var init_schemas = __esm({
|
|
|
170
398
|
usd: z.number().nonnegative().optional()
|
|
171
399
|
});
|
|
172
400
|
AGENT_INFO_MAX_KEYS = 32;
|
|
401
|
+
AGENT_TOOL_CALLS_MAX_KEYS = 64;
|
|
402
|
+
agentToolCallsSchema = z.record(z.string().min(1), nonNegativeInt);
|
|
173
403
|
agentTelemetrySchema = z.object({
|
|
404
|
+
/** Agent or app version (semver, git SHA, deploy tag — caller-defined). */
|
|
174
405
|
version: z.string().min(1).optional(),
|
|
406
|
+
/** Total tool invocations. When omitted but `toolCalls` is set, the sum of counts is used. */
|
|
175
407
|
toolCallCount: nonNegativeInt.optional(),
|
|
408
|
+
/** Per-tool invocation counts keyed by tool name. */
|
|
409
|
+
toolCalls: agentToolCallsSchema.optional(),
|
|
176
410
|
cost: agentCostSchema.optional(),
|
|
411
|
+
/** Free-form metadata for experiments (model, prompt variant, etc.). */
|
|
177
412
|
info: z.record(z.string(), z.unknown()).optional()
|
|
178
413
|
}).refine(
|
|
179
414
|
(data) => {
|
|
@@ -181,6 +416,14 @@ var init_schemas = __esm({
|
|
|
181
416
|
return keys.length <= AGENT_INFO_MAX_KEYS;
|
|
182
417
|
},
|
|
183
418
|
{ message: `agent.info may contain at most ${AGENT_INFO_MAX_KEYS} keys` }
|
|
419
|
+
).refine(
|
|
420
|
+
(data) => {
|
|
421
|
+
const keys = data.toolCalls ? Object.keys(data.toolCalls) : [];
|
|
422
|
+
return keys.length <= AGENT_TOOL_CALLS_MAX_KEYS;
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
message: `agent.toolCalls may contain at most ${AGENT_TOOL_CALLS_MAX_KEYS} tool names`
|
|
426
|
+
}
|
|
184
427
|
);
|
|
185
428
|
createTaskBodySchema = taskContextObjectSchema.extend({
|
|
186
429
|
assignTo: assignToSchema.optional(),
|
|
@@ -199,9 +442,186 @@ var init_schemas = __esm({
|
|
|
199
442
|
* the inbox status bar and the thread update log.
|
|
200
443
|
*/
|
|
201
444
|
update: threadUpdateInputSchema.optional(),
|
|
445
|
+
/** Agent telemetry (version, cost, tool calls) — not shown in inbox UI. */
|
|
202
446
|
agent: agentTelemetrySchema.optional()
|
|
203
447
|
}).superRefine(refineContextPublicUrls);
|
|
204
|
-
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// ../core/src/schemas/json-schema.ts
|
|
452
|
+
var init_json_schema = __esm({
|
|
453
|
+
"../core/src/schemas/json-schema.ts"() {
|
|
454
|
+
"use strict";
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// ../core/src/schemas/index.ts
|
|
459
|
+
var init_schemas = __esm({
|
|
460
|
+
"../core/src/schemas/index.ts"() {
|
|
461
|
+
"use strict";
|
|
462
|
+
init_task();
|
|
463
|
+
init_json_schema();
|
|
464
|
+
init_context_urls();
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
// src/schemas/index.ts
|
|
469
|
+
import { z as z2 } from "zod";
|
|
470
|
+
function refineContextPublicUrls2(data, ctx) {
|
|
471
|
+
const error = validateContextPublicUrls(data.context);
|
|
472
|
+
if (error) {
|
|
473
|
+
ctx.addIssue({
|
|
474
|
+
code: z2.ZodIssueCode.custom,
|
|
475
|
+
message: error,
|
|
476
|
+
path: ["context"]
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
var safeUrlSchema2, jsonSchema7Schema2, uiSchemaSchema2, webhookHandlerSchema2, triggerHandlerSchema2, handlerSchema2, taskActionSchema2, uiFieldSchemaSchema2, contextUiSchema2, contextDataSchema2, taskContextObjectSchema2, taskContextSchema2, assignToSchema2, threadUpdateMessageSchema2, threadUpdateStatuses2, threadUpdateStatusSchema2, threadUpdateInputSchema2, taskPriorities2, taskPrioritySchema2, nonNegativeInt2, agentCostTokensSchema2, agentCostSchema2, AGENT_INFO_MAX_KEYS2, AGENT_TOOL_CALLS_MAX_KEYS2, agentToolCallsSchema2, agentTelemetrySchema2, createTaskBodySchema2, threadUpdateBodySchema;
|
|
481
|
+
var init_schemas2 = __esm({
|
|
482
|
+
"src/schemas/index.ts"() {
|
|
483
|
+
"use strict";
|
|
484
|
+
init_utils();
|
|
485
|
+
init_schemas();
|
|
486
|
+
safeUrlSchema2 = z2.string().refine((url) => isPublicHttpUrl(url), {
|
|
487
|
+
message: PUBLIC_HTTP_URL_ERROR
|
|
488
|
+
});
|
|
489
|
+
jsonSchema7Schema2 = z2.custom(
|
|
490
|
+
(val) => typeof val === "object" && val !== null,
|
|
491
|
+
{ message: "Must be a valid JSON Schema object" }
|
|
492
|
+
);
|
|
493
|
+
uiSchemaSchema2 = z2.custom((val) => typeof val === "object" && val !== null, {
|
|
494
|
+
message: "Must be a valid UiSchema object"
|
|
495
|
+
});
|
|
496
|
+
webhookHandlerSchema2 = z2.object({
|
|
497
|
+
type: z2.literal("webhook"),
|
|
498
|
+
url: safeUrlSchema2,
|
|
499
|
+
headers: z2.record(z2.string(), z2.string())
|
|
500
|
+
});
|
|
501
|
+
triggerHandlerSchema2 = webhookHandlerSchema2.extend({
|
|
502
|
+
type: z2.literal("trigger"),
|
|
503
|
+
tokenId: z2.string().min(1)
|
|
504
|
+
});
|
|
505
|
+
handlerSchema2 = z2.discriminatedUnion("type", [webhookHandlerSchema2, triggerHandlerSchema2]);
|
|
506
|
+
taskActionSchema2 = z2.object({
|
|
507
|
+
id: z2.string().min(1),
|
|
508
|
+
title: z2.string().min(1),
|
|
509
|
+
description: z2.string().optional(),
|
|
510
|
+
schema: jsonSchema7Schema2.optional(),
|
|
511
|
+
ui: uiSchemaSchema2.optional(),
|
|
512
|
+
data: z2.record(z2.string(), z2.unknown()).optional(),
|
|
513
|
+
handlers: z2.array(handlerSchema2).min(1).optional()
|
|
514
|
+
});
|
|
515
|
+
uiFieldSchemaSchema2 = z2.object({
|
|
516
|
+
"ui:widget": z2.string().optional(),
|
|
517
|
+
"ui:title": z2.string().optional(),
|
|
518
|
+
"ui:description": z2.string().optional(),
|
|
519
|
+
"ui:options": z2.record(z2.string(), z2.unknown()).optional(),
|
|
520
|
+
items: z2.lazy(() => z2.record(z2.string(), uiFieldSchemaSchema2)).optional()
|
|
521
|
+
}).passthrough();
|
|
522
|
+
contextUiSchema2 = z2.record(z2.string(), uiFieldSchemaSchema2).optional();
|
|
523
|
+
contextDataSchema2 = z2.object({
|
|
524
|
+
data: z2.record(z2.string(), z2.unknown()),
|
|
525
|
+
ui: contextUiSchema2
|
|
526
|
+
}).optional();
|
|
527
|
+
taskContextObjectSchema2 = z2.object({
|
|
528
|
+
app: z2.string().min(1).optional(),
|
|
529
|
+
type: z2.string().min(1),
|
|
530
|
+
name: z2.string().min(1),
|
|
531
|
+
description: z2.string().optional(),
|
|
532
|
+
validUntil: z2.string().optional(),
|
|
533
|
+
context: contextDataSchema2,
|
|
534
|
+
version: z2.literal(2).optional(),
|
|
535
|
+
actions: z2.array(taskActionSchema2).min(1, "At least one action is required")
|
|
536
|
+
});
|
|
537
|
+
taskContextSchema2 = taskContextObjectSchema2.superRefine(
|
|
538
|
+
refineContextPublicUrls2
|
|
539
|
+
);
|
|
540
|
+
assignToSchema2 = z2.object({
|
|
541
|
+
users: z2.array(z2.string().email()).optional(),
|
|
542
|
+
groups: z2.array(z2.string().min(1)).optional()
|
|
543
|
+
}).refine(
|
|
544
|
+
(data) => {
|
|
545
|
+
const groups = data.groups ?? [];
|
|
546
|
+
if (groups.includes("all") && groups.length > 1) {
|
|
547
|
+
return false;
|
|
548
|
+
}
|
|
549
|
+
return true;
|
|
550
|
+
},
|
|
551
|
+
{ message: 'Cannot combine "all" with other group slugs' }
|
|
552
|
+
);
|
|
553
|
+
threadUpdateMessageSchema2 = z2.string().min(1).max(500);
|
|
554
|
+
threadUpdateStatuses2 = [
|
|
555
|
+
"info",
|
|
556
|
+
"queued",
|
|
557
|
+
"running",
|
|
558
|
+
"waiting",
|
|
559
|
+
"succeeded",
|
|
560
|
+
"failed",
|
|
561
|
+
"cancelled"
|
|
562
|
+
];
|
|
563
|
+
threadUpdateStatusSchema2 = z2.enum(threadUpdateStatuses2);
|
|
564
|
+
threadUpdateInputSchema2 = z2.object({
|
|
565
|
+
message: threadUpdateMessageSchema2,
|
|
566
|
+
status: threadUpdateStatusSchema2.optional()
|
|
567
|
+
});
|
|
568
|
+
taskPriorities2 = ["low", "normal", "high", "urgent"];
|
|
569
|
+
taskPrioritySchema2 = z2.enum(taskPriorities2);
|
|
570
|
+
nonNegativeInt2 = z2.number().int().nonnegative();
|
|
571
|
+
agentCostTokensSchema2 = z2.object({
|
|
572
|
+
input: nonNegativeInt2.optional(),
|
|
573
|
+
output: nonNegativeInt2.optional(),
|
|
574
|
+
total: nonNegativeInt2.optional()
|
|
575
|
+
});
|
|
576
|
+
agentCostSchema2 = z2.object({
|
|
577
|
+
tokens: agentCostTokensSchema2.optional(),
|
|
578
|
+
eur: z2.number().nonnegative().optional(),
|
|
579
|
+
usd: z2.number().nonnegative().optional()
|
|
580
|
+
});
|
|
581
|
+
AGENT_INFO_MAX_KEYS2 = 32;
|
|
582
|
+
AGENT_TOOL_CALLS_MAX_KEYS2 = 64;
|
|
583
|
+
agentToolCallsSchema2 = z2.record(z2.string().min(1), nonNegativeInt2);
|
|
584
|
+
agentTelemetrySchema2 = z2.object({
|
|
585
|
+
version: z2.string().min(1).optional(),
|
|
586
|
+
toolCallCount: nonNegativeInt2.optional(),
|
|
587
|
+
toolCalls: agentToolCallsSchema2.optional(),
|
|
588
|
+
cost: agentCostSchema2.optional(),
|
|
589
|
+
info: z2.record(z2.string(), z2.unknown()).optional()
|
|
590
|
+
}).refine(
|
|
591
|
+
(data) => {
|
|
592
|
+
const keys = data.info ? Object.keys(data.info) : [];
|
|
593
|
+
return keys.length <= AGENT_INFO_MAX_KEYS2;
|
|
594
|
+
},
|
|
595
|
+
{ message: `agent.info may contain at most ${AGENT_INFO_MAX_KEYS2} keys` }
|
|
596
|
+
).refine(
|
|
597
|
+
(data) => {
|
|
598
|
+
const keys = data.toolCalls ? Object.keys(data.toolCalls) : [];
|
|
599
|
+
return keys.length <= AGENT_TOOL_CALLS_MAX_KEYS2;
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
message: `agent.toolCalls may contain at most ${AGENT_TOOL_CALLS_MAX_KEYS2} tool names`
|
|
603
|
+
}
|
|
604
|
+
);
|
|
605
|
+
createTaskBodySchema2 = taskContextObjectSchema2.extend({
|
|
606
|
+
assignTo: assignToSchema2.optional(),
|
|
607
|
+
/**
|
|
608
|
+
* Groups related tasks together. When omitted, the server generates one and
|
|
609
|
+
* returns it so the caller can reuse it on later tasks in the same thread.
|
|
610
|
+
*/
|
|
611
|
+
threadId: z2.string().min(1).optional(),
|
|
612
|
+
/**
|
|
613
|
+
* Optional thread priority. When set, applies to the whole thread and
|
|
614
|
+
* overwrites any previous priority. Omit on later tasks to leave unchanged.
|
|
615
|
+
*/
|
|
616
|
+
priority: taskPrioritySchema2.optional(),
|
|
617
|
+
/**
|
|
618
|
+
* Optional initial status update logged against the task's thread. Shows in
|
|
619
|
+
* the inbox status bar and the thread update log.
|
|
620
|
+
*/
|
|
621
|
+
update: threadUpdateInputSchema2.optional(),
|
|
622
|
+
agent: agentTelemetrySchema2.optional()
|
|
623
|
+
}).superRefine(refineContextPublicUrls2);
|
|
624
|
+
threadUpdateBodySchema = threadUpdateInputSchema2;
|
|
205
625
|
}
|
|
206
626
|
});
|
|
207
627
|
|
|
@@ -346,7 +766,7 @@ var DEFAULT_POLL_INTERVAL_MS, DEFAULT_TIMEOUT_MS, RobotRockError, RobotRock;
|
|
|
346
766
|
var init_client = __esm({
|
|
347
767
|
"src/client.ts"() {
|
|
348
768
|
"use strict";
|
|
349
|
-
|
|
769
|
+
init_schemas2();
|
|
350
770
|
init_approval_result();
|
|
351
771
|
DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
352
772
|
DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -402,7 +822,7 @@ var init_client = __esm({
|
|
|
402
822
|
...task2.update !== void 0 ? { update: task2.update } : {},
|
|
403
823
|
...task2.agent !== void 0 ? { agent: task2.agent } : {}
|
|
404
824
|
};
|
|
405
|
-
const validation =
|
|
825
|
+
const validation = createTaskBodySchema2.safeParse(bodyPayload);
|
|
406
826
|
if (!validation.success) {
|
|
407
827
|
throw new RobotRockError(
|
|
408
828
|
`Invalid task: ${validation.error.issues[0]?.message}`,
|
|
@@ -845,7 +1265,7 @@ var init_workflow = __esm({
|
|
|
845
1265
|
import { tool } from "ai";
|
|
846
1266
|
|
|
847
1267
|
// src/ai/approve-by-human-tool-core.ts
|
|
848
|
-
import { z as
|
|
1268
|
+
import { z as z3 } from "zod";
|
|
849
1269
|
|
|
850
1270
|
// src/ai/context.ts
|
|
851
1271
|
init_client();
|
|
@@ -989,11 +1409,11 @@ var APPROVE_BY_HUMAN_ACTIONS4 = [
|
|
|
989
1409
|
{ id: "approve", title: "Approve" },
|
|
990
1410
|
{ id: "decline", title: "Decline" }
|
|
991
1411
|
];
|
|
992
|
-
var approveByHumanInputSchema =
|
|
993
|
-
type:
|
|
994
|
-
name:
|
|
995
|
-
description:
|
|
996
|
-
contextSummary:
|
|
1412
|
+
var approveByHumanInputSchema = z3.object({
|
|
1413
|
+
type: z3.string().optional().describe("Task type slug; defaults to ai-approval"),
|
|
1414
|
+
name: z3.string().describe("Short title for the approval request"),
|
|
1415
|
+
description: z3.string().describe("What needs approval and the consequences of approving or declining"),
|
|
1416
|
+
contextSummary: z3.string().optional().describe("Optional markdown summary shown to the reviewer")
|
|
997
1417
|
});
|
|
998
1418
|
function resolveApproveByHumanToolConfig(clientOrContext, maybeOptions = {}) {
|
|
999
1419
|
const isDurable = typeof clientOrContext === "object" && clientOrContext !== null && "mode" in clientOrContext && (clientOrContext.mode === "trigger" || clientOrContext.mode === "workflow");
|
|
@@ -1042,18 +1462,18 @@ function approveByHumanTool(clientOrContext, maybeOptions = {}) {
|
|
|
1042
1462
|
import { tool as tool2 } from "ai";
|
|
1043
1463
|
|
|
1044
1464
|
// src/ai/create-send-to-human-tool-core.ts
|
|
1045
|
-
|
|
1046
|
-
import { z as
|
|
1047
|
-
var sendToHumanToolInputSchema =
|
|
1048
|
-
type:
|
|
1049
|
-
name:
|
|
1050
|
-
description:
|
|
1051
|
-
context:
|
|
1052
|
-
data:
|
|
1053
|
-
ui:
|
|
1465
|
+
init_schemas2();
|
|
1466
|
+
import { z as z4 } from "zod";
|
|
1467
|
+
var sendToHumanToolInputSchema = z4.object({
|
|
1468
|
+
type: z4.string().describe("Task type slug shown in the RobotRock inbox"),
|
|
1469
|
+
name: z4.string().describe("Short title for the human reviewer"),
|
|
1470
|
+
description: z4.string().optional().describe("What you need from the human and why you cannot proceed alone"),
|
|
1471
|
+
context: z4.object({
|
|
1472
|
+
data: z4.record(z4.string(), z4.unknown()).optional(),
|
|
1473
|
+
ui: z4.record(z4.string(), z4.unknown()).optional()
|
|
1054
1474
|
}).optional().describe("Optional structured context for the inbox UI"),
|
|
1055
|
-
validUntil:
|
|
1056
|
-
assignTo:
|
|
1475
|
+
validUntil: z4.string().datetime().optional().describe("Optional ISO deadline for the task"),
|
|
1476
|
+
assignTo: assignToSchema2.optional().describe(
|
|
1057
1477
|
"Assign to tenant member emails and/or group slugs; narrows who sees the task in the inbox"
|
|
1058
1478
|
)
|
|
1059
1479
|
});
|
|
@@ -1104,15 +1524,15 @@ function createSendToHumanTool(clientOrOptions, maybeOptions) {
|
|
|
1104
1524
|
import { tool as tool3 } from "ai";
|
|
1105
1525
|
|
|
1106
1526
|
// src/ai/create-send-update-tool-core.ts
|
|
1107
|
-
|
|
1527
|
+
init_schemas2();
|
|
1108
1528
|
init_client();
|
|
1109
|
-
import { z as
|
|
1110
|
-
var sendUpdateToolInputSchema =
|
|
1111
|
-
threadId:
|
|
1529
|
+
import { z as z5 } from "zod";
|
|
1530
|
+
var sendUpdateToolInputSchema = z5.object({
|
|
1531
|
+
threadId: z5.string().optional().describe(
|
|
1112
1532
|
"Thread to post the update to. Use the `threadId` returned by a prior send-to-human task. Omit only when a session threadId is configured on the tool."
|
|
1113
1533
|
),
|
|
1114
|
-
message:
|
|
1115
|
-
status:
|
|
1534
|
+
message: z5.string().describe("Short progress update (1-2 sentences) shown in the inbox status bar"),
|
|
1535
|
+
status: threadUpdateStatusSchema2.optional().describe(
|
|
1116
1536
|
"Lifecycle status driving the status-bar icon/color: info, queued, running, waiting, succeeded, failed, cancelled"
|
|
1117
1537
|
)
|
|
1118
1538
|
});
|