robotrock 0.8.1 → 0.8.4

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 CHANGED
@@ -53,13 +53,237 @@ var __callDispose = (stack, error, hasError) => {
53
53
  return next();
54
54
  };
55
55
 
56
- // src/schemas/index.ts
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, threadUpdateBodySchema;
74
- var init_schemas = __esm({
75
- "src/schemas/index.ts"() {
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, AGENT_OTEL_SPANS_MAX, agentToolCallsSchema, agentOtelSpanStatusSchema, agentOtelSpanSummarySchema, agentOtelSchema, 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,17 +398,47 @@ 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
+ AGENT_OTEL_SPANS_MAX = 32;
403
+ agentToolCallsSchema = z.record(z.string().min(1), nonNegativeInt);
404
+ agentOtelSpanStatusSchema = z.enum(["ok", "error"]);
405
+ agentOtelSpanSummarySchema = z.object({
406
+ name: z.string().min(1),
407
+ durationMs: z.number().nonnegative(),
408
+ status: agentOtelSpanStatusSchema
409
+ });
410
+ agentOtelSchema = z.object({
411
+ traceId: z.string().min(1),
412
+ spanId: z.string().min(1).optional(),
413
+ rootDurationMs: z.number().nonnegative().optional(),
414
+ spans: z.array(agentOtelSpanSummarySchema).max(AGENT_OTEL_SPANS_MAX).optional()
415
+ });
173
416
  agentTelemetrySchema = z.object({
417
+ /** Agent or app version (semver, git SHA, deploy tag — caller-defined). */
174
418
  version: z.string().min(1).optional(),
419
+ /** Total tool invocations. When omitted but `toolCalls` is set, the sum of counts is used. */
175
420
  toolCallCount: nonNegativeInt.optional(),
421
+ /** Per-tool invocation counts keyed by tool name. */
422
+ toolCalls: agentToolCallsSchema.optional(),
176
423
  cost: agentCostSchema.optional(),
177
- info: z.record(z.string(), z.unknown()).optional()
424
+ /** Free-form metadata for experiments (model, prompt variant, etc.). */
425
+ info: z.record(z.string(), z.unknown()).optional(),
426
+ /** Structured OpenTelemetry span snapshot for feedback analysis. */
427
+ otel: agentOtelSchema.optional()
178
428
  }).refine(
179
429
  (data) => {
180
430
  const keys = data.info ? Object.keys(data.info) : [];
181
431
  return keys.length <= AGENT_INFO_MAX_KEYS;
182
432
  },
183
433
  { message: `agent.info may contain at most ${AGENT_INFO_MAX_KEYS} keys` }
434
+ ).refine(
435
+ (data) => {
436
+ const keys = data.toolCalls ? Object.keys(data.toolCalls) : [];
437
+ return keys.length <= AGENT_TOOL_CALLS_MAX_KEYS;
438
+ },
439
+ {
440
+ message: `agent.toolCalls may contain at most ${AGENT_TOOL_CALLS_MAX_KEYS} tool names`
441
+ }
184
442
  );
185
443
  createTaskBodySchema = taskContextObjectSchema.extend({
186
444
  assignTo: assignToSchema.optional(),
@@ -199,9 +457,200 @@ var init_schemas = __esm({
199
457
  * the inbox status bar and the thread update log.
200
458
  */
201
459
  update: threadUpdateInputSchema.optional(),
460
+ /** Agent telemetry (version, cost, tool calls) — not shown in inbox UI. */
202
461
  agent: agentTelemetrySchema.optional()
203
462
  }).superRefine(refineContextPublicUrls);
204
- threadUpdateBodySchema = threadUpdateInputSchema;
463
+ }
464
+ });
465
+
466
+ // ../core/src/schemas/json-schema.ts
467
+ var init_json_schema = __esm({
468
+ "../core/src/schemas/json-schema.ts"() {
469
+ "use strict";
470
+ }
471
+ });
472
+
473
+ // ../core/src/schemas/index.ts
474
+ var init_schemas = __esm({
475
+ "../core/src/schemas/index.ts"() {
476
+ "use strict";
477
+ init_task();
478
+ init_json_schema();
479
+ init_context_urls();
480
+ }
481
+ });
482
+
483
+ // src/schemas/index.ts
484
+ import { z as z2 } from "zod";
485
+ function refineContextPublicUrls2(data, ctx) {
486
+ const error = validateContextPublicUrls(data.context);
487
+ if (error) {
488
+ ctx.addIssue({
489
+ code: z2.ZodIssueCode.custom,
490
+ message: error,
491
+ path: ["context"]
492
+ });
493
+ }
494
+ }
495
+ 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, AGENT_OTEL_SPANS_MAX2, agentToolCallsSchema2, agentOtelSpanStatusSchema2, agentOtelSpanSummarySchema2, agentOtelSchema2, agentTelemetrySchema2, createTaskBodySchema2, threadUpdateBodySchema;
496
+ var init_schemas2 = __esm({
497
+ "src/schemas/index.ts"() {
498
+ "use strict";
499
+ init_utils();
500
+ init_schemas();
501
+ safeUrlSchema2 = z2.string().refine((url) => isPublicHttpUrl(url), {
502
+ message: PUBLIC_HTTP_URL_ERROR
503
+ });
504
+ jsonSchema7Schema2 = z2.custom(
505
+ (val) => typeof val === "object" && val !== null,
506
+ { message: "Must be a valid JSON Schema object" }
507
+ );
508
+ uiSchemaSchema2 = z2.custom((val) => typeof val === "object" && val !== null, {
509
+ message: "Must be a valid UiSchema object"
510
+ });
511
+ webhookHandlerSchema2 = z2.object({
512
+ type: z2.literal("webhook"),
513
+ url: safeUrlSchema2,
514
+ headers: z2.record(z2.string(), z2.string())
515
+ });
516
+ triggerHandlerSchema2 = webhookHandlerSchema2.extend({
517
+ type: z2.literal("trigger"),
518
+ tokenId: z2.string().min(1)
519
+ });
520
+ handlerSchema2 = z2.discriminatedUnion("type", [webhookHandlerSchema2, triggerHandlerSchema2]);
521
+ taskActionSchema2 = z2.object({
522
+ id: z2.string().min(1),
523
+ title: z2.string().min(1),
524
+ description: z2.string().optional(),
525
+ schema: jsonSchema7Schema2.optional(),
526
+ ui: uiSchemaSchema2.optional(),
527
+ data: z2.record(z2.string(), z2.unknown()).optional(),
528
+ handlers: z2.array(handlerSchema2).min(1).optional()
529
+ });
530
+ uiFieldSchemaSchema2 = z2.object({
531
+ "ui:widget": z2.string().optional(),
532
+ "ui:title": z2.string().optional(),
533
+ "ui:description": z2.string().optional(),
534
+ "ui:options": z2.record(z2.string(), z2.unknown()).optional(),
535
+ items: z2.lazy(() => z2.record(z2.string(), uiFieldSchemaSchema2)).optional()
536
+ }).passthrough();
537
+ contextUiSchema2 = z2.record(z2.string(), uiFieldSchemaSchema2).optional();
538
+ contextDataSchema2 = z2.object({
539
+ data: z2.record(z2.string(), z2.unknown()),
540
+ ui: contextUiSchema2
541
+ }).optional();
542
+ taskContextObjectSchema2 = z2.object({
543
+ app: z2.string().min(1).optional(),
544
+ type: z2.string().min(1),
545
+ name: z2.string().min(1),
546
+ description: z2.string().optional(),
547
+ validUntil: z2.string().optional(),
548
+ context: contextDataSchema2,
549
+ version: z2.literal(2).optional(),
550
+ actions: z2.array(taskActionSchema2).min(1, "At least one action is required")
551
+ });
552
+ taskContextSchema2 = taskContextObjectSchema2.superRefine(
553
+ refineContextPublicUrls2
554
+ );
555
+ assignToSchema2 = z2.object({
556
+ users: z2.array(z2.string().email()).optional(),
557
+ groups: z2.array(z2.string().min(1)).optional()
558
+ }).refine(
559
+ (data) => {
560
+ const groups = data.groups ?? [];
561
+ if (groups.includes("all") && groups.length > 1) {
562
+ return false;
563
+ }
564
+ return true;
565
+ },
566
+ { message: 'Cannot combine "all" with other group slugs' }
567
+ );
568
+ threadUpdateMessageSchema2 = z2.string().min(1).max(500);
569
+ threadUpdateStatuses2 = [
570
+ "info",
571
+ "queued",
572
+ "running",
573
+ "waiting",
574
+ "succeeded",
575
+ "failed",
576
+ "cancelled"
577
+ ];
578
+ threadUpdateStatusSchema2 = z2.enum(threadUpdateStatuses2);
579
+ threadUpdateInputSchema2 = z2.object({
580
+ message: threadUpdateMessageSchema2,
581
+ status: threadUpdateStatusSchema2.optional()
582
+ });
583
+ taskPriorities2 = ["low", "normal", "high", "urgent"];
584
+ taskPrioritySchema2 = z2.enum(taskPriorities2);
585
+ nonNegativeInt2 = z2.number().int().nonnegative();
586
+ agentCostTokensSchema2 = z2.object({
587
+ input: nonNegativeInt2.optional(),
588
+ output: nonNegativeInt2.optional(),
589
+ total: nonNegativeInt2.optional()
590
+ });
591
+ agentCostSchema2 = z2.object({
592
+ tokens: agentCostTokensSchema2.optional(),
593
+ eur: z2.number().nonnegative().optional(),
594
+ usd: z2.number().nonnegative().optional()
595
+ });
596
+ AGENT_INFO_MAX_KEYS2 = 32;
597
+ AGENT_TOOL_CALLS_MAX_KEYS2 = 64;
598
+ AGENT_OTEL_SPANS_MAX2 = 32;
599
+ agentToolCallsSchema2 = z2.record(z2.string().min(1), nonNegativeInt2);
600
+ agentOtelSpanStatusSchema2 = z2.enum(["ok", "error"]);
601
+ agentOtelSpanSummarySchema2 = z2.object({
602
+ name: z2.string().min(1),
603
+ durationMs: z2.number().nonnegative(),
604
+ status: agentOtelSpanStatusSchema2
605
+ });
606
+ agentOtelSchema2 = z2.object({
607
+ traceId: z2.string().min(1),
608
+ spanId: z2.string().min(1).optional(),
609
+ rootDurationMs: z2.number().nonnegative().optional(),
610
+ spans: z2.array(agentOtelSpanSummarySchema2).max(AGENT_OTEL_SPANS_MAX2).optional()
611
+ });
612
+ agentTelemetrySchema2 = z2.object({
613
+ version: z2.string().min(1).optional(),
614
+ toolCallCount: nonNegativeInt2.optional(),
615
+ toolCalls: agentToolCallsSchema2.optional(),
616
+ cost: agentCostSchema2.optional(),
617
+ info: z2.record(z2.string(), z2.unknown()).optional(),
618
+ otel: agentOtelSchema2.optional()
619
+ }).refine(
620
+ (data) => {
621
+ const keys = data.info ? Object.keys(data.info) : [];
622
+ return keys.length <= AGENT_INFO_MAX_KEYS2;
623
+ },
624
+ { message: `agent.info may contain at most ${AGENT_INFO_MAX_KEYS2} keys` }
625
+ ).refine(
626
+ (data) => {
627
+ const keys = data.toolCalls ? Object.keys(data.toolCalls) : [];
628
+ return keys.length <= AGENT_TOOL_CALLS_MAX_KEYS2;
629
+ },
630
+ {
631
+ message: `agent.toolCalls may contain at most ${AGENT_TOOL_CALLS_MAX_KEYS2} tool names`
632
+ }
633
+ );
634
+ createTaskBodySchema2 = taskContextObjectSchema2.extend({
635
+ assignTo: assignToSchema2.optional(),
636
+ /**
637
+ * Groups related tasks together. When omitted, the server generates one and
638
+ * returns it so the caller can reuse it on later tasks in the same thread.
639
+ */
640
+ threadId: z2.string().min(1).optional(),
641
+ /**
642
+ * Optional thread priority. When set, applies to the whole thread and
643
+ * overwrites any previous priority. Omit on later tasks to leave unchanged.
644
+ */
645
+ priority: taskPrioritySchema2.optional(),
646
+ /**
647
+ * Optional initial status update logged against the task's thread. Shows in
648
+ * the inbox status bar and the thread update log.
649
+ */
650
+ update: threadUpdateInputSchema2.optional(),
651
+ agent: agentTelemetrySchema2.optional()
652
+ }).superRefine(refineContextPublicUrls2);
653
+ threadUpdateBodySchema = threadUpdateInputSchema2;
205
654
  }
206
655
  });
207
656
 
@@ -346,7 +795,7 @@ var DEFAULT_POLL_INTERVAL_MS, DEFAULT_TIMEOUT_MS, RobotRockError, RobotRock;
346
795
  var init_client = __esm({
347
796
  "src/client.ts"() {
348
797
  "use strict";
349
- init_schemas();
798
+ init_schemas2();
350
799
  init_approval_result();
351
800
  DEFAULT_POLL_INTERVAL_MS = 2e3;
352
801
  DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
@@ -402,7 +851,7 @@ var init_client = __esm({
402
851
  ...task2.update !== void 0 ? { update: task2.update } : {},
403
852
  ...task2.agent !== void 0 ? { agent: task2.agent } : {}
404
853
  };
405
- const validation = createTaskBodySchema.safeParse(bodyPayload);
854
+ const validation = createTaskBodySchema2.safeParse(bodyPayload);
406
855
  if (!validation.success) {
407
856
  throw new RobotRockError(
408
857
  `Invalid task: ${validation.error.issues[0]?.message}`,
@@ -845,7 +1294,7 @@ var init_workflow = __esm({
845
1294
  import { tool } from "ai";
846
1295
 
847
1296
  // src/ai/approve-by-human-tool-core.ts
848
- import { z as z2 } from "zod";
1297
+ import { z as z3 } from "zod";
849
1298
 
850
1299
  // src/ai/context.ts
851
1300
  init_client();
@@ -989,11 +1438,11 @@ var APPROVE_BY_HUMAN_ACTIONS4 = [
989
1438
  { id: "approve", title: "Approve" },
990
1439
  { id: "decline", title: "Decline" }
991
1440
  ];
992
- var approveByHumanInputSchema = z2.object({
993
- type: z2.string().optional().describe("Task type slug; defaults to ai-approval"),
994
- name: z2.string().describe("Short title for the approval request"),
995
- description: z2.string().describe("What needs approval and the consequences of approving or declining"),
996
- contextSummary: z2.string().optional().describe("Optional markdown summary shown to the reviewer")
1441
+ var approveByHumanInputSchema = z3.object({
1442
+ type: z3.string().optional().describe("Task type slug; defaults to ai-approval"),
1443
+ name: z3.string().describe("Short title for the approval request"),
1444
+ description: z3.string().describe("What needs approval and the consequences of approving or declining"),
1445
+ contextSummary: z3.string().optional().describe("Optional markdown summary shown to the reviewer")
997
1446
  });
998
1447
  function resolveApproveByHumanToolConfig(clientOrContext, maybeOptions = {}) {
999
1448
  const isDurable = typeof clientOrContext === "object" && clientOrContext !== null && "mode" in clientOrContext && (clientOrContext.mode === "trigger" || clientOrContext.mode === "workflow");
@@ -1042,18 +1491,18 @@ function approveByHumanTool(clientOrContext, maybeOptions = {}) {
1042
1491
  import { tool as tool2 } from "ai";
1043
1492
 
1044
1493
  // src/ai/create-send-to-human-tool-core.ts
1045
- init_schemas();
1046
- import { z as z3 } from "zod";
1047
- var sendToHumanToolInputSchema = z3.object({
1048
- type: z3.string().describe("Task type slug shown in the RobotRock inbox"),
1049
- name: z3.string().describe("Short title for the human reviewer"),
1050
- description: z3.string().optional().describe("What you need from the human and why you cannot proceed alone"),
1051
- context: z3.object({
1052
- data: z3.record(z3.string(), z3.unknown()).optional(),
1053
- ui: z3.record(z3.string(), z3.unknown()).optional()
1494
+ init_schemas2();
1495
+ import { z as z4 } from "zod";
1496
+ var sendToHumanToolInputSchema = z4.object({
1497
+ type: z4.string().describe("Task type slug shown in the RobotRock inbox"),
1498
+ name: z4.string().describe("Short title for the human reviewer"),
1499
+ description: z4.string().optional().describe("What you need from the human and why you cannot proceed alone"),
1500
+ context: z4.object({
1501
+ data: z4.record(z4.string(), z4.unknown()).optional(),
1502
+ ui: z4.record(z4.string(), z4.unknown()).optional()
1054
1503
  }).optional().describe("Optional structured context for the inbox UI"),
1055
- validUntil: z3.string().datetime().optional().describe("Optional ISO deadline for the task"),
1056
- assignTo: assignToSchema.optional().describe(
1504
+ validUntil: z4.string().datetime().optional().describe("Optional ISO deadline for the task"),
1505
+ assignTo: assignToSchema2.optional().describe(
1057
1506
  "Assign to tenant member emails and/or group slugs; narrows who sees the task in the inbox"
1058
1507
  )
1059
1508
  });
@@ -1104,15 +1553,15 @@ function createSendToHumanTool(clientOrOptions, maybeOptions) {
1104
1553
  import { tool as tool3 } from "ai";
1105
1554
 
1106
1555
  // src/ai/create-send-update-tool-core.ts
1107
- init_schemas();
1556
+ init_schemas2();
1108
1557
  init_client();
1109
- import { z as z4 } from "zod";
1110
- var sendUpdateToolInputSchema = z4.object({
1111
- threadId: z4.string().optional().describe(
1558
+ import { z as z5 } from "zod";
1559
+ var sendUpdateToolInputSchema = z5.object({
1560
+ threadId: z5.string().optional().describe(
1112
1561
  "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
1562
  ),
1114
- message: z4.string().describe("Short progress update (1-2 sentences) shown in the inbox status bar"),
1115
- status: threadUpdateStatusSchema.optional().describe(
1563
+ message: z5.string().describe("Short progress update (1-2 sentences) shown in the inbox status bar"),
1564
+ status: threadUpdateStatusSchema2.optional().describe(
1116
1565
  "Lifecycle status driving the status-bar icon/color: info, queued, running, waiting, succeeded, failed, cancelled"
1117
1566
  )
1118
1567
  });