robotrock 1.0.0 → 1.3.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.
Files changed (71) hide show
  1. package/dist/agent-admin.d.ts +82 -0
  2. package/dist/agent-admin.js +938 -0
  3. package/dist/agent-admin.js.map +1 -0
  4. package/dist/ai/index.d.ts +6 -5
  5. package/dist/ai/index.js +682 -225
  6. package/dist/ai/index.js.map +1 -1
  7. package/dist/ai/trigger.d.ts +4 -3
  8. package/dist/ai/trigger.js +682 -225
  9. package/dist/ai/trigger.js.map +1 -1
  10. package/dist/ai/workflow.d.ts +4 -3
  11. package/dist/ai/workflow.js +679 -222
  12. package/dist/ai/workflow.js.map +1 -1
  13. package/dist/auth-headers-qL-ZeEtd.d.ts +13 -0
  14. package/dist/{client-CzVmjXpz.d.ts → client-YO9Y1rkH.d.ts} +51 -10
  15. package/dist/eve/agent/index.d.ts +164 -0
  16. package/dist/eve/agent/index.js +2854 -0
  17. package/dist/eve/agent/index.js.map +1 -0
  18. package/dist/eve/index.d.ts +8 -0
  19. package/dist/eve/index.js +639 -0
  20. package/dist/eve/index.js.map +1 -0
  21. package/dist/eve/tools/admin/assign-tasks.d.ts +39 -0
  22. package/dist/eve/tools/admin/assign-tasks.js +1060 -0
  23. package/dist/eve/tools/admin/assign-tasks.js.map +1 -0
  24. package/dist/eve/tools/admin/manage-groups.d.ts +53 -0
  25. package/dist/eve/tools/admin/manage-groups.js +1218 -0
  26. package/dist/eve/tools/admin/manage-groups.js.map +1 -0
  27. package/dist/eve/tools/admin/manage-team-members.d.ts +45 -0
  28. package/dist/eve/tools/admin/manage-team-members.js +1160 -0
  29. package/dist/eve/tools/admin/manage-team-members.js.map +1 -0
  30. package/dist/eve/tools/admin/query-tasks.d.ts +71 -0
  31. package/dist/eve/tools/admin/query-tasks.js +1161 -0
  32. package/dist/eve/tools/admin/query-tasks.js.map +1 -0
  33. package/dist/eve/tools/catalog/search-products.d.ts +57 -0
  34. package/dist/eve/tools/catalog/search-products.js +94 -0
  35. package/dist/eve/tools/catalog/search-products.js.map +1 -0
  36. package/dist/eve/tools/identity/index.d.ts +8 -0
  37. package/dist/eve/tools/identity/index.js +234 -0
  38. package/dist/eve/tools/identity/index.js.map +1 -0
  39. package/dist/eve/tools/identity/my-access.d.ts +18 -0
  40. package/dist/eve/tools/identity/my-access.js +187 -0
  41. package/dist/eve/tools/identity/my-access.js.map +1 -0
  42. package/dist/eve/tools/identity/whoami.d.ts +44 -0
  43. package/dist/eve/tools/identity/whoami.js +117 -0
  44. package/dist/eve/tools/identity/whoami.js.map +1 -0
  45. package/dist/eve/tools/inbox/create-task.d.ts +114 -0
  46. package/dist/eve/tools/inbox/create-task.js +1785 -0
  47. package/dist/eve/tools/inbox/create-task.js.map +1 -0
  48. package/dist/eve/tools/inbox/index.d.ts +6 -0
  49. package/dist/eve/tools/inbox/index.js +1785 -0
  50. package/dist/eve/tools/inbox/index.js.map +1 -0
  51. package/dist/eve/tools/index.d.ts +24 -0
  52. package/dist/eve/tools/index.js +2848 -0
  53. package/dist/eve/tools/index.js.map +1 -0
  54. package/dist/index-DoQN48Bm.d.ts +200 -0
  55. package/dist/index.d.ts +8 -44
  56. package/dist/index.js +842 -137
  57. package/dist/index.js.map +1 -1
  58. package/dist/schemas/index.d.ts +6 -1
  59. package/dist/schemas/index.js +251 -59
  60. package/dist/schemas/index.js.map +1 -1
  61. package/dist/tenant-5YKDrdC-.d.ts +23 -0
  62. package/dist/{tool-approval-bridge-DbwUEBHv.d.ts → tool-approval-bridge-aMA79Z1B.d.ts} +1 -1
  63. package/dist/tool-reply-guidance-C3qrT1In.d.ts +25 -0
  64. package/dist/trigger/index.d.ts +2 -1
  65. package/dist/trigger/index.js +543 -127
  66. package/dist/trigger/index.js.map +1 -1
  67. package/dist/{trigger-BCKBbAV7.d.ts → trigger-CXrbKVCL.d.ts} +2 -2
  68. package/dist/workflow/index.d.ts +2 -1
  69. package/dist/workflow/index.js +543 -127
  70. package/dist/workflow/index.js.map +1 -1
  71. package/package.json +69 -8
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/schemas/index.ts
2
- import { z as z2 } from "zod";
2
+ import { z as z4 } from "zod";
3
3
 
4
4
  // ../core/src/utils/safe-url.ts
5
5
  var BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set([
@@ -108,6 +108,25 @@ function isBlockedHostname(hostname) {
108
108
  }
109
109
  return isBlockedIpv4(host) || isBlockedIpv6(host);
110
110
  }
111
+ function isLoopbackHandlerUrl(urlString) {
112
+ let url;
113
+ try {
114
+ url = new URL(urlString);
115
+ } catch {
116
+ return false;
117
+ }
118
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
119
+ return false;
120
+ }
121
+ if (url.username || url.password) {
122
+ return false;
123
+ }
124
+ const host = url.hostname.toLowerCase();
125
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]" || host.endsWith(".localhost");
126
+ }
127
+ function isAllowedHandlerUrl(urlString) {
128
+ return isPublicHttpUrl(urlString) || isLoopbackHandlerUrl(urlString);
129
+ }
111
130
  function isPublicHttpUrl(urlString) {
112
131
  let url;
113
132
  try {
@@ -124,6 +143,7 @@ function isPublicHttpUrl(urlString) {
124
143
  return !isBlockedHostname(url.hostname);
125
144
  }
126
145
  var PUBLIC_HTTP_URL_ERROR = "URL must be a public http:// or https:// address";
146
+ var HANDLER_URL_ERROR = "Handler URL must be a public or loopback http:// or https:// address";
127
147
 
128
148
  // ../core/src/schemas/task.ts
129
149
  import { z } from "zod";
@@ -185,6 +205,9 @@ function validateContextPublicUrls(context2) {
185
205
  var safeUrlSchema = z.string().refine((url) => isPublicHttpUrl(url), {
186
206
  message: PUBLIC_HTTP_URL_ERROR
187
207
  });
208
+ var handlerUrlSchema = z.string().refine((url) => isAllowedHandlerUrl(url), {
209
+ message: HANDLER_URL_ERROR
210
+ });
188
211
  var jsonSchema7Schema = z.custom(
189
212
  (val) => typeof val === "object" && val !== null,
190
213
  { message: "Must be a valid JSON Schema object" }
@@ -194,7 +217,7 @@ var uiSchemaSchema = z.custom((val) => typeof val === "object" && val !== null,
194
217
  });
195
218
  var webhookHandlerSchema = z.object({
196
219
  type: z.literal("webhook"),
197
- url: safeUrlSchema,
220
+ url: handlerUrlSchema,
198
221
  headers: z.record(z.string(), z.string())
199
222
  });
200
223
  var triggerHandlerSchema = webhookHandlerSchema.extend({
@@ -345,86 +368,253 @@ var agentChatSeedMessageSchema = z.object({
345
368
  action: agentChatSeedActionSchema
346
369
  }).optional()
347
370
  });
371
+ var eveAgentChatTransportSchema = z.object({
372
+ kind: z.literal("eve"),
373
+ chatId: z.string().min(1),
374
+ baseUrl: z.string().url(),
375
+ sessionId: z.string().optional(),
376
+ continuationToken: z.string().optional(),
377
+ streamIndex: z.number().int().nonnegative().optional(),
378
+ isStreaming: z.boolean().optional()
379
+ });
348
380
  var createAgentChatBodySchema = z.object({
349
- /** Trigger chat agent id (task slug). Required unless `parentChatId` is set. */
381
+ /** Agent id (eve agent name). Required unless `parentChatId` is set. */
350
382
  agentIdentifier: z.string().min(1).optional(),
351
383
  /** Inherit tenant/connection/agent from an existing chat (agent-spawned chats). */
352
384
  parentChatId: z.string().min(1).optional(),
353
- /** Convex tenantTriggerConnections id; resolved from the tenant when omitted. */
354
- connectionId: z.string().min(1).optional(),
385
+ /** Convex tenantEveConnections id; resolved from the tenant when omitted. */
386
+ eveConnectionId: z.string().min(1).optional(),
355
387
  /** Source application id; groups the chat under an inbox section. */
356
388
  app: z.string().min(1).optional(),
357
- assignTo: assignToSchema.optional(),
389
+ /** Email of the user who owns the chat. Required unless `parentChatId` is set. */
390
+ ownerEmail: z.string().email().optional(),
358
391
  title: z.string().min(1),
359
392
  messages: z.array(agentChatSeedMessageSchema).default([]),
360
393
  /** Provenance label stored on the session ("cron" | "agent" | ...). */
361
394
  source: z.string().min(1).optional()
362
395
  }).refine((data) => Boolean(data.agentIdentifier || data.parentChatId), {
363
396
  message: "Provide either agentIdentifier or parentChatId"
397
+ }).refine((data) => Boolean(data.ownerEmail || data.parentChatId), {
398
+ message: "Provide ownerEmail unless parentChatId is set"
364
399
  });
365
- var agentChatTransportBodySchema = z.object({
366
- chatId: z.string().min(1),
367
- publicAccessToken: z.string().min(1),
368
- lastEventId: z.string().optional(),
369
- isStreaming: z.boolean().optional()
400
+ var agentChatAuditToolBodySchema = z.object({
401
+ eveSessionId: z.string().min(1),
402
+ userId: z.string().min(1),
403
+ toolCallId: z.string().min(1),
404
+ toolName: z.string().min(1),
405
+ input: z.record(z.string(), z.unknown()).default({}),
406
+ success: z.boolean(),
407
+ status: z.enum(["completed", "failed", "rejected"]),
408
+ error: z.string().optional(),
409
+ idempotencyKey: z.string().optional()
410
+ });
411
+ var agentChatAuditInputBodySchema = z.object({
412
+ eveSessionId: z.string().min(1),
413
+ userId: z.string().min(1),
414
+ actionId: z.string().min(1),
415
+ actionTitle: z.string().optional(),
416
+ prompt: z.string().optional(),
417
+ data: z.record(z.string(), z.unknown()).optional(),
418
+ idempotencyKey: z.string().optional(),
419
+ /** Eve input request id — used to merge staged HITL metadata. */
420
+ requestId: z.string().optional(),
421
+ /** Eve tool call id — fallback lookup for staged HITL metadata. */
422
+ toolCallId: z.string().optional()
423
+ });
424
+ var eveHitlStagedOptionSchema = z.object({
425
+ id: z.string(),
426
+ label: z.string()
427
+ });
428
+ var agentChatStageHitlBodySchema = z.object({
429
+ eveSessionId: z.string().min(1),
430
+ requests: z.array(
431
+ z.object({
432
+ requestId: z.string().min(1),
433
+ toolCallId: z.string().min(1),
434
+ toolName: z.string().min(1),
435
+ prompt: z.string().min(1),
436
+ display: z.enum(["confirmation", "select", "text"]).optional(),
437
+ allowFreeform: z.boolean().optional(),
438
+ options: z.array(eveHitlStagedOptionSchema).optional(),
439
+ toolInput: z.record(z.string(), z.unknown()).optional()
440
+ })
441
+ )
442
+ });
443
+ var agentChatLinkTaskBodySchema = z.object({
444
+ eveSessionId: z.string().min(1),
445
+ publicTaskId: z.string().min(1),
446
+ toolCallId: z.string().min(1)
447
+ });
448
+
449
+ // ../core/src/schemas/tool-result-display.ts
450
+ import { z as z2 } from "zod";
451
+ var toolDisplayMetadataSchema = z2.object({
452
+ widget: z2.string().optional(),
453
+ title: z2.string().optional(),
454
+ description: z2.string().optional()
455
+ });
456
+ var toolDisplayEnvelopeSchema = z2.object({
457
+ display: toolDisplayMetadataSchema.optional(),
458
+ data: z2.record(z2.string(), z2.unknown()),
459
+ ui: z2.record(
460
+ z2.string(),
461
+ z2.object({
462
+ "ui:widget": z2.string().optional(),
463
+ "ui:title": z2.string().optional(),
464
+ "ui:description": z2.string().optional(),
465
+ "ui:options": z2.record(z2.string(), z2.unknown()).optional()
466
+ }).passthrough()
467
+ ).optional()
468
+ });
469
+
470
+ // ../core/src/schemas/agent-admin.ts
471
+ import { z as z3 } from "zod";
472
+ var tenantRoleSchema = z3.enum(["admin", "member"]);
473
+ var agentAdminUserSchema = z3.object({
474
+ id: z3.string(),
475
+ email: z3.string().email(),
476
+ name: z3.string()
477
+ });
478
+ var agentAdminMemberSchema = z3.object({
479
+ userId: z3.string(),
480
+ role: z3.string(),
481
+ membershipKind: z3.enum(["team", "assignee"]),
482
+ hasLoggedIn: z3.boolean(),
483
+ user: agentAdminUserSchema
484
+ });
485
+ var agentAdminGroupSchema = z3.object({
486
+ id: z3.string(),
487
+ name: z3.string(),
488
+ slug: z3.string(),
489
+ description: z3.string().nullable(),
490
+ memberCount: z3.number().optional()
491
+ });
492
+ var agentAdminGroupDetailSchema = agentAdminGroupSchema.extend({
493
+ members: z3.array(
494
+ z3.object({
495
+ userId: z3.string(),
496
+ user: agentAdminUserSchema
497
+ })
498
+ )
499
+ });
500
+ var agentAdminTaskSummarySchema = z3.object({
501
+ id: z3.string(),
502
+ convexId: z3.string(),
503
+ status: z3.string(),
504
+ type: z3.string().nullable(),
505
+ name: z3.string().nullable(),
506
+ description: z3.string().nullable(),
507
+ validUntil: z3.number(),
508
+ createdAt: z3.number(),
509
+ threadPriority: z3.string().nullable(),
510
+ handledByUserId: z3.string().nullable()
511
+ });
512
+ var inviteMemberBodySchema = z3.object({
513
+ email: z3.string().email(),
514
+ role: tenantRoleSchema.optional()
515
+ });
516
+ var updateMemberRoleBodySchema = z3.object({
517
+ role: tenantRoleSchema
518
+ });
519
+ var createGroupBodySchema = z3.object({
520
+ name: z3.string().min(1),
521
+ description: z3.string().optional()
522
+ });
523
+ var updateGroupBodySchema = z3.object({
524
+ name: z3.string().min(1).optional(),
525
+ description: z3.string().optional()
526
+ });
527
+ var addGroupMemberBodySchema = z3.object({
528
+ userId: z3.string().min(1).describe("Convex user id or member email.")
529
+ });
530
+ var listTasksQuerySchema = z3.object({
531
+ statusFilter: z3.enum(["all", "open", "handled", "expired"]).optional(),
532
+ typeFilter: z3.string().optional(),
533
+ appFilter: z3.string().optional(),
534
+ sortField: z3.enum(["type", "date", "status", "validUntil"]).optional(),
535
+ sortDirection: z3.enum(["asc", "desc"]).optional(),
536
+ limit: z3.coerce.number().int().positive().max(100).optional(),
537
+ cursor: z3.string().optional()
538
+ });
539
+ var searchTasksQuerySchema = z3.object({
540
+ q: z3.string().min(1),
541
+ limit: z3.coerce.number().int().positive().max(100).optional()
542
+ });
543
+ var assignTasksResultSchema = z3.object({
544
+ taskId: z3.string(),
545
+ success: z3.boolean(),
546
+ message: z3.string().optional(),
547
+ name: z3.string().nullable().optional(),
548
+ description: z3.string().nullable().optional(),
549
+ type: z3.string().nullable().optional()
550
+ });
551
+ var assignTasksResponseSchema = z3.object({
552
+ results: z3.array(assignTasksResultSchema)
553
+ });
554
+ var assignTasksBodySchema = z3.object({
555
+ taskIds: z3.array(z3.string().min(1)).min(1).max(100),
556
+ assignTo: assignToSchema.refine(
557
+ (value) => (value.users?.length ?? 0) > 0 || (value.groups?.length ?? 0) > 0,
558
+ { message: "assignTo needs at least one user email or group slug." }
559
+ )
370
560
  });
371
561
 
372
562
  // src/schemas/index.ts
373
- var safeUrlSchema2 = z2.string().refine((url) => isPublicHttpUrl(url), {
374
- message: PUBLIC_HTTP_URL_ERROR
563
+ var handlerUrlSchema2 = z4.string().refine((url) => isAllowedHandlerUrl(url), {
564
+ message: HANDLER_URL_ERROR
375
565
  });
376
- var jsonSchema7Schema2 = z2.custom(
566
+ var jsonSchema7Schema2 = z4.custom(
377
567
  (val) => typeof val === "object" && val !== null,
378
568
  { message: "Must be a valid JSON Schema object" }
379
569
  );
380
- var uiSchemaSchema2 = z2.custom((val) => typeof val === "object" && val !== null, {
570
+ var uiSchemaSchema2 = z4.custom((val) => typeof val === "object" && val !== null, {
381
571
  message: "Must be a valid UiSchema object"
382
572
  });
383
- var webhookHandlerSchema2 = z2.object({
384
- type: z2.literal("webhook"),
385
- url: safeUrlSchema2,
386
- headers: z2.record(z2.string(), z2.string())
573
+ var webhookHandlerSchema2 = z4.object({
574
+ type: z4.literal("webhook"),
575
+ url: handlerUrlSchema2,
576
+ headers: z4.record(z4.string(), z4.string())
387
577
  });
388
578
  var triggerHandlerSchema2 = webhookHandlerSchema2.extend({
389
- type: z2.literal("trigger"),
390
- tokenId: z2.string().min(1)
579
+ type: z4.literal("trigger"),
580
+ tokenId: z4.string().min(1)
391
581
  });
392
- var handlerSchema2 = z2.discriminatedUnion("type", [webhookHandlerSchema2, triggerHandlerSchema2]);
393
- var taskActionInputSchema2 = z2.object({
394
- id: z2.string().min(1),
395
- title: z2.string().min(1),
396
- description: z2.string().optional(),
582
+ var handlerSchema2 = z4.discriminatedUnion("type", [webhookHandlerSchema2, triggerHandlerSchema2]);
583
+ var taskActionInputSchema2 = z4.object({
584
+ id: z4.string().min(1),
585
+ title: z4.string().min(1),
586
+ description: z4.string().optional(),
397
587
  schema: jsonSchema7Schema2.optional(),
398
588
  ui: uiSchemaSchema2.optional(),
399
- data: z2.record(z2.string(), z2.unknown()).optional()
589
+ data: z4.record(z4.string(), z4.unknown()).optional()
400
590
  });
401
591
  var taskActionSchema2 = taskActionInputSchema2.extend({
402
- handlers: z2.array(handlerSchema2).min(1).optional()
592
+ handlers: z4.array(handlerSchema2).min(1).optional()
403
593
  });
404
- var uiFieldSchemaSchema2 = z2.object({
405
- "ui:widget": z2.string().optional(),
406
- "ui:title": z2.string().optional(),
407
- "ui:description": z2.string().optional(),
408
- "ui:options": z2.record(z2.string(), z2.unknown()).optional(),
409
- items: z2.lazy(() => z2.record(z2.string(), uiFieldSchemaSchema2)).optional()
594
+ var uiFieldSchemaSchema2 = z4.object({
595
+ "ui:widget": z4.string().optional(),
596
+ "ui:title": z4.string().optional(),
597
+ "ui:description": z4.string().optional(),
598
+ "ui:options": z4.record(z4.string(), z4.unknown()).optional(),
599
+ items: z4.lazy(() => z4.record(z4.string(), uiFieldSchemaSchema2)).optional()
410
600
  }).passthrough();
411
- var contextUiSchema2 = z2.record(z2.string(), uiFieldSchemaSchema2).optional();
412
- var contextDataSchema2 = z2.object({
413
- data: z2.record(z2.string(), z2.unknown()),
601
+ var contextUiSchema2 = z4.record(z4.string(), uiFieldSchemaSchema2).optional();
602
+ var contextDataSchema2 = z4.object({
603
+ data: z4.record(z4.string(), z4.unknown()),
414
604
  ui: contextUiSchema2
415
605
  }).optional();
416
606
  var TASK_CONTEXT_FORMAT_VERSION2 = 2;
417
- var taskContextObjectBaseSchema2 = z2.object({
418
- app: z2.string().min(1).optional(),
419
- type: z2.string().min(1),
420
- name: z2.string().min(1),
421
- description: z2.string().optional(),
422
- validUntil: z2.string().optional(),
607
+ var taskContextObjectBaseSchema2 = z4.object({
608
+ app: z4.string().min(1).optional(),
609
+ type: z4.string().min(1),
610
+ name: z4.string().min(1),
611
+ description: z4.string().optional(),
612
+ validUntil: z4.string().optional(),
423
613
  context: contextDataSchema2,
424
- contextVersion: z2.literal(2).optional(),
614
+ contextVersion: z4.literal(2).optional(),
425
615
  /** @deprecated Use `contextVersion`. Accepted on ingest only. */
426
- version: z2.literal(2).optional(),
427
- actions: z2.array(taskActionSchema2).min(1, "At least one action is required")
616
+ version: z4.literal(2).optional(),
617
+ actions: z4.array(taskActionSchema2).min(1, "At least one action is required")
428
618
  });
429
619
  function normalizeTaskContextVersion2(data) {
430
620
  const { version: legacyVersion, contextVersion, ...rest } = data;
@@ -440,7 +630,7 @@ function refineContextPublicUrls2(data, ctx) {
440
630
  const error = validateContextPublicUrls(data.context);
441
631
  if (error) {
442
632
  ctx.addIssue({
443
- code: z2.ZodIssueCode.custom,
633
+ code: z4.ZodIssueCode.custom,
444
634
  message: error,
445
635
  path: ["context"]
446
636
  });
@@ -449,9 +639,9 @@ function refineContextPublicUrls2(data, ctx) {
449
639
  var taskContextSchema2 = taskContextObjectSchema2.superRefine(
450
640
  refineContextPublicUrls2
451
641
  );
452
- var assignToSchema2 = z2.object({
453
- users: z2.array(z2.string().email()).optional(),
454
- groups: z2.array(z2.string().min(1)).optional()
642
+ var assignToSchema2 = z4.object({
643
+ users: z4.array(z4.string().email()).optional(),
644
+ groups: z4.array(z4.string().min(1)).optional()
455
645
  }).refine(
456
646
  (data) => {
457
647
  const groups = data.groups ?? [];
@@ -462,7 +652,7 @@ var assignToSchema2 = z2.object({
462
652
  },
463
653
  { message: 'Cannot combine "all" with other group slugs' }
464
654
  );
465
- var threadUpdateMessageSchema2 = z2.string().min(1).max(500);
655
+ var threadUpdateMessageSchema2 = z4.string().min(1).max(500);
466
656
  var threadUpdateStatuses2 = [
467
657
  "info",
468
658
  "queued",
@@ -472,14 +662,14 @@ var threadUpdateStatuses2 = [
472
662
  "failed",
473
663
  "cancelled"
474
664
  ];
475
- var threadUpdateStatusSchema2 = z2.enum(threadUpdateStatuses2);
665
+ var threadUpdateStatusSchema2 = z4.enum(threadUpdateStatuses2);
476
666
  var DEFAULT_THREAD_UPDATE_STATUS = "info";
477
- var threadUpdateInputSchema2 = z2.object({
667
+ var threadUpdateInputSchema2 = z4.object({
478
668
  message: threadUpdateMessageSchema2,
479
669
  status: threadUpdateStatusSchema2.optional()
480
670
  });
481
671
  var taskPriorities2 = ["low", "normal", "high", "urgent"];
482
- var taskPrioritySchema2 = z2.enum(taskPriorities2);
672
+ var taskPrioritySchema2 = z4.enum(taskPriorities2);
483
673
  var DEFAULT_TASK_PRIORITY = "normal";
484
674
  var LOWEST_TASK_PRIORITY = "low";
485
675
  var TASK_PRIORITY_RANK = {
@@ -488,8 +678,8 @@ var TASK_PRIORITY_RANK = {
488
678
  high: 3,
489
679
  urgent: 4
490
680
  };
491
- var agentTelemetrySchema2 = z2.object({
492
- version: z2.string().min(1)
681
+ var agentTelemetrySchema2 = z4.object({
682
+ version: z4.string().min(1)
493
683
  });
494
684
  var createTaskBodySchema2 = taskContextObjectBaseSchema2.extend({
495
685
  assignTo: assignToSchema2.optional(),
@@ -497,7 +687,7 @@ var createTaskBodySchema2 = taskContextObjectBaseSchema2.extend({
497
687
  * Groups related tasks together. When omitted, the server generates one and
498
688
  * returns it so the caller can reuse it on later tasks in the same thread.
499
689
  */
500
- threadId: z2.string().min(1).optional(),
690
+ threadId: z4.string().min(1).optional(),
501
691
  /**
502
692
  * Optional thread priority. When set, applies to the whole thread and
503
693
  * overwrites any previous priority. Omit on later tasks to leave unchanged.
@@ -512,6 +702,65 @@ var createTaskBodySchema2 = taskContextObjectBaseSchema2.extend({
512
702
  }).transform(normalizeTaskContextVersion2).superRefine(refineContextPublicUrls2);
513
703
  var threadUpdateBodySchema = threadUpdateInputSchema2;
514
704
 
705
+ // ../core/src/handler-retry.ts
706
+ var HANDLER_RETRY_DELAYS_MS = [
707
+ 6e4,
708
+ // 1m
709
+ 3e5,
710
+ // 5m
711
+ 18e5,
712
+ // 30m
713
+ 36e5,
714
+ // 1h
715
+ 216e5,
716
+ // 6h
717
+ 864e5,
718
+ // 24h
719
+ 1728e5
720
+ // 48h
721
+ ];
722
+ var HANDLER_MAX_ATTEMPTS = HANDLER_RETRY_DELAYS_MS.length + 1;
723
+
724
+ // ../core/src/attribution/index.ts
725
+ import { z as z5 } from "zod";
726
+
727
+ // ../core/src/app-url.ts
728
+ var PRODUCTION_APP_URL = "https://app.robotrock.io";
729
+ var PRODUCTION_API_URL = "https://api.robotrock.io/v1";
730
+ var DEV_API_URL = "http://localhost:4001/v1";
731
+ var APP_SIGNUP_URL = `${PRODUCTION_APP_URL}/sign-up`;
732
+ function normalizeRobotRockApiBaseUrl(baseUrl) {
733
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
734
+ if (trimmed.endsWith("/v1")) {
735
+ return trimmed;
736
+ }
737
+ return `${trimmed}/v1`;
738
+ }
739
+ function getRobotRockApiBaseUrl() {
740
+ const explicit = process.env.ROBOTROCK_BASE_URL?.trim() || process.env.ROBOTROCK_API_URL?.trim();
741
+ if (explicit) {
742
+ return normalizeRobotRockApiBaseUrl(explicit);
743
+ }
744
+ if (process.env.NODE_ENV === "production") {
745
+ return PRODUCTION_API_URL;
746
+ }
747
+ return DEV_API_URL;
748
+ }
749
+
750
+ // ../core/src/attribution/index.ts
751
+ var ATTRIBUTION_COOKIE_MAX_AGE = 60 * 60 * 24 * 90;
752
+ var attributionSchema = z5.object({
753
+ utmSource: z5.string().optional(),
754
+ utmMedium: z5.string().optional(),
755
+ utmCampaign: z5.string().optional(),
756
+ utmContent: z5.string().optional(),
757
+ utmTerm: z5.string().optional(),
758
+ gclid: z5.string().optional(),
759
+ landingUrl: z5.string().optional(),
760
+ referrer: z5.string().optional(),
761
+ capturedAt: z5.number()
762
+ });
763
+
515
764
  // src/approval-result.ts
516
765
  var TaskTimeoutError = class extends Error {
517
766
  constructor(message) {
@@ -568,8 +817,13 @@ async function parseResponseBody(response) {
568
817
  }
569
818
  function getErrorMessage(data, fallback) {
570
819
  if (data && typeof data === "object" && !Array.isArray(data)) {
571
- const maybeMessage = data.message;
820
+ const record = data;
821
+ const maybeMessage = record.message;
822
+ const maybeHint = record.hint;
572
823
  if (typeof maybeMessage === "string" && maybeMessage.trim()) {
824
+ if (typeof maybeHint === "string" && maybeHint.trim()) {
825
+ return `${maybeMessage.trim()} ${maybeHint.trim()}`;
826
+ }
573
827
  return maybeMessage;
574
828
  }
575
829
  }
@@ -581,51 +835,49 @@ function getErrorMessage(data, fallback) {
581
835
  return fallback;
582
836
  }
583
837
 
584
- // ../core/src/handler-retry.ts
585
- var HANDLER_RETRY_DELAYS_MS = [
586
- 6e4,
587
- // 1m
588
- 3e5,
589
- // 5m
590
- 18e5,
591
- // 30m
592
- 36e5,
593
- // 1h
594
- 216e5,
595
- // 6h
596
- 864e5,
597
- // 24h
598
- 1728e5
599
- // 48h
600
- ];
601
- var HANDLER_MAX_ATTEMPTS = HANDLER_RETRY_DELAYS_MS.length + 1;
602
-
603
- // ../core/src/attribution/index.ts
604
- import { z as z3 } from "zod";
605
-
606
- // ../core/src/app-url.ts
607
- var PRODUCTION_APP_URL = "https://app.robotrock.io";
608
- var APP_SIGNUP_URL = `${PRODUCTION_APP_URL}/sign-up`;
609
-
610
- // ../core/src/attribution/index.ts
611
- var ATTRIBUTION_COOKIE_MAX_AGE = 60 * 60 * 24 * 90;
612
- var attributionSchema = z3.object({
613
- utmSource: z3.string().optional(),
614
- utmMedium: z3.string().optional(),
615
- utmCampaign: z3.string().optional(),
616
- utmContent: z3.string().optional(),
617
- utmTerm: z3.string().optional(),
618
- gclid: z3.string().optional(),
619
- landingUrl: z3.string().optional(),
620
- referrer: z3.string().optional(),
621
- capturedAt: z3.number()
622
- });
838
+ // src/auth-headers.ts
839
+ var ROBOTROCK_ACTING_USER_ID_HEADER = "x-robotrock-acting-user-id";
840
+ function buildRobotRockAuthHeaders(auth) {
841
+ if (auth.kind === "apiKey") {
842
+ const headers2 = {
843
+ "X-Api-Key": auth.apiKey
844
+ };
845
+ if (auth.actingUserId?.trim()) {
846
+ headers2[ROBOTROCK_ACTING_USER_ID_HEADER] = auth.actingUserId.trim();
847
+ }
848
+ return headers2;
849
+ }
850
+ const headers = {
851
+ Authorization: `Bearer ${auth.token}`,
852
+ "X-RobotRock-Tenant-Slug": auth.tenantSlug,
853
+ "X-RobotRock-Connection-Id": auth.connectionId
854
+ };
855
+ if (auth.actingUserId?.trim()) {
856
+ headers[ROBOTROCK_ACTING_USER_ID_HEADER] = auth.actingUserId.trim();
857
+ }
858
+ return headers;
859
+ }
860
+ function resolveRobotRockAuthConfig(overrides) {
861
+ if (overrides?.agentService) {
862
+ return {
863
+ kind: "agentService",
864
+ ...overrides.agentService
865
+ };
866
+ }
867
+ const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;
868
+ if (!apiKey) {
869
+ throw new Error(
870
+ "RobotRock auth is required. Set ROBOTROCK_API_KEY, ROBOTROCK_AGENT_SERVICE_TOKEN with tenant context, or pass auth when creating the client."
871
+ );
872
+ }
873
+ return { kind: "apiKey", apiKey };
874
+ }
623
875
 
624
876
  // src/chats.ts
625
877
  function createChatsApi(config) {
626
878
  const headers = () => ({
627
879
  "Content-Type": "application/json",
628
- "X-Api-Key": config.apiKey
880
+ ...buildRobotRockAuthHeaders(config.auth)
629
881
  });
630
882
  return {
631
883
  async create(input) {
@@ -678,6 +930,120 @@ function createChatsApi(config) {
678
930
  data
679
931
  );
680
932
  }
933
+ },
934
+ async stageHitlRequests(input) {
935
+ const validation = agentChatStageHitlBodySchema.safeParse(input);
936
+ if (!validation.success) {
937
+ throw new RobotRockError(
938
+ `Invalid stage HITL input: ${validation.error.issues[0]?.message}`,
939
+ 400,
940
+ validation.error.issues
941
+ );
942
+ }
943
+ const response = await fetch(`${config.baseUrl}/agent-chats/stage-hitl`, {
944
+ method: "POST",
945
+ headers: headers(),
946
+ body: JSON.stringify(validation.data)
947
+ });
948
+ if (!response.ok) {
949
+ const data = await parseResponseBody(response);
950
+ throw new RobotRockError(
951
+ getErrorMessage(data, "Failed to stage chat HITL requests"),
952
+ response.status,
953
+ data
954
+ );
955
+ }
956
+ },
957
+ async getStagedHitlRequests(eveSessionId) {
958
+ const trimmed = eveSessionId.trim();
959
+ if (!trimmed) {
960
+ throw new RobotRockError("eveSessionId is required", 400);
961
+ }
962
+ const url = new URL(`${config.baseUrl}/agent-chats/staged-hitl`);
963
+ url.searchParams.set("eveSessionId", trimmed);
964
+ const response = await fetch(url.toString(), {
965
+ method: "GET",
966
+ headers: headers()
967
+ });
968
+ const data = await parseResponseBody(response);
969
+ if (!response.ok) {
970
+ throw new RobotRockError(
971
+ getErrorMessage(data, "Failed to fetch staged chat HITL requests"),
972
+ response.status,
973
+ data
974
+ );
975
+ }
976
+ const requests = data.requests;
977
+ return Array.isArray(requests) ? requests : [];
978
+ },
979
+ async logInputSubmission(input) {
980
+ const validation = agentChatAuditInputBodySchema.safeParse(input);
981
+ if (!validation.success) {
982
+ throw new RobotRockError(
983
+ `Invalid audit input: ${validation.error.issues[0]?.message}`,
984
+ 400,
985
+ validation.error.issues
986
+ );
987
+ }
988
+ const response = await fetch(`${config.baseUrl}/agent-chats/audit-input`, {
989
+ method: "POST",
990
+ headers: headers(),
991
+ body: JSON.stringify(validation.data)
992
+ });
993
+ if (!response.ok) {
994
+ const data = await parseResponseBody(response);
995
+ throw new RobotRockError(
996
+ getErrorMessage(data, "Failed to log chat input submission"),
997
+ response.status,
998
+ data
999
+ );
1000
+ }
1001
+ },
1002
+ async logToolExecution(input) {
1003
+ const validation = agentChatAuditToolBodySchema.safeParse(input);
1004
+ if (!validation.success) {
1005
+ throw new RobotRockError(
1006
+ `Invalid audit tool input: ${validation.error.issues[0]?.message}`,
1007
+ 400,
1008
+ validation.error.issues
1009
+ );
1010
+ }
1011
+ const response = await fetch(`${config.baseUrl}/agent-chats/audit-tool`, {
1012
+ method: "POST",
1013
+ headers: headers(),
1014
+ body: JSON.stringify(validation.data)
1015
+ });
1016
+ if (!response.ok) {
1017
+ const data = await parseResponseBody(response);
1018
+ throw new RobotRockError(
1019
+ getErrorMessage(data, "Failed to log chat tool execution"),
1020
+ response.status,
1021
+ data
1022
+ );
1023
+ }
1024
+ },
1025
+ async linkTask(input) {
1026
+ const validation = agentChatLinkTaskBodySchema.safeParse(input);
1027
+ if (!validation.success) {
1028
+ throw new RobotRockError(
1029
+ `Invalid link task input: ${validation.error.issues[0]?.message}`,
1030
+ 400,
1031
+ validation.error.issues
1032
+ );
1033
+ }
1034
+ const response = await fetch(`${config.baseUrl}/agent-chats/link-task`, {
1035
+ method: "POST",
1036
+ headers: headers(),
1037
+ body: JSON.stringify(validation.data)
1038
+ });
1039
+ if (!response.ok) {
1040
+ const data = await parseResponseBody(response);
1041
+ throw new RobotRockError(
1042
+ getErrorMessage(data, "Failed to link inbox task to chat"),
1043
+ response.status,
1044
+ data
1045
+ );
1046
+ }
681
1047
  }
682
1048
  };
683
1049
  }
@@ -720,7 +1086,7 @@ function serializeValidUntil(value) {
720
1086
  throw new RobotRockError("Invalid validUntil: expected a Date or parseable date string", 400);
721
1087
  }
722
1088
  var RobotRock = class {
723
- apiKey;
1089
+ auth;
724
1090
  baseUrl;
725
1091
  app;
726
1092
  agentVersion;
@@ -738,14 +1104,17 @@ var RobotRock = class {
738
1104
  );
739
1105
  }
740
1106
  const apiKey = config.apiKey ?? process.env.ROBOTROCK_API_KEY;
741
- if (!apiKey) {
1107
+ const agentService = config.agentService;
1108
+ if (apiKey && agentService) {
742
1109
  throw new Error(
743
- "RobotRock API key is required. Set ROBOTROCK_API_KEY or pass apiKey when creating the client."
1110
+ "RobotRock client cannot configure both apiKey and agentService."
744
1111
  );
745
1112
  }
746
- this.apiKey = apiKey;
747
- const rawBase = config.baseUrl ?? "https://api.robotrock.io/v1";
748
- this.baseUrl = rawBase.replace(/\/+$/, "");
1113
+ this.auth = resolveRobotRockAuthConfig({
1114
+ ...apiKey ? { apiKey } : {},
1115
+ ...agentService ? { agentService } : {}
1116
+ });
1117
+ this.baseUrl = config.baseUrl ?? getRobotRockApiBaseUrl();
749
1118
  this.app = config.app;
750
1119
  this.agentVersion = config.version ?? resolveAgentVersionFromEnv();
751
1120
  this.contextVersion = config.advanced?.contextVersion ?? TASK_CONTEXT_FORMAT_VERSION2;
@@ -755,14 +1124,23 @@ var RobotRock = class {
755
1124
  create: (task) => this.createTaskRequest(task),
756
1125
  get: (taskId) => this.getTaskById(taskId),
757
1126
  cancel: (taskId) => this.cancelTaskRequest(taskId),
758
- sendUpdate: (input) => this.sendThreadUpdate(input)
1127
+ sendUpdate: (input) => this.sendThreadUpdate(input),
1128
+ list: (input) => this.listTasksRequest(input),
1129
+ search: (input) => this.searchTasksRequest(input)
759
1130
  };
760
1131
  this.chats = createChatsApi({
761
1132
  baseUrl: this.baseUrl,
762
- apiKey: this.apiKey,
1133
+ auth: this.auth,
763
1134
  app: this.app
764
1135
  });
765
1136
  }
1137
+ authHeaders(extra) {
1138
+ return {
1139
+ "Content-Type": "application/json",
1140
+ ...buildRobotRockAuthHeaders(this.auth),
1141
+ ...extra
1142
+ };
1143
+ }
766
1144
  async createTaskRequest(task) {
767
1145
  const normalizedTask = normalizeSendToHumanInput(task, {
768
1146
  webhook: this.webhook,
@@ -787,13 +1165,9 @@ var RobotRock = class {
787
1165
  validation.error.issues
788
1166
  );
789
1167
  }
790
- const headers = {
791
- "Content-Type": "application/json",
792
- "X-Api-Key": this.apiKey
793
- };
794
- if (task.idempotencyKey) {
795
- headers["Idempotency-Key"] = task.idempotencyKey;
796
- }
1168
+ const headers = this.authHeaders(
1169
+ task.idempotencyKey ? { "Idempotency-Key": task.idempotencyKey } : void 0
1170
+ );
797
1171
  const response = await fetch(`${this.baseUrl}/`, {
798
1172
  method: "POST",
799
1173
  headers,
@@ -886,9 +1260,7 @@ var RobotRock = class {
886
1260
  async getTaskById(taskId) {
887
1261
  const response = await fetch(`${this.baseUrl}/tasks/${taskId}`, {
888
1262
  method: "GET",
889
- headers: {
890
- "X-Api-Key": this.apiKey
891
- }
1263
+ headers: this.authHeaders()
892
1264
  });
893
1265
  if (response.status === 404) {
894
1266
  return null;
@@ -923,10 +1295,7 @@ var RobotRock = class {
923
1295
  `${this.baseUrl}/threads/${encodeURIComponent(threadId)}/updates`,
924
1296
  {
925
1297
  method: "POST",
926
- headers: {
927
- "Content-Type": "application/json",
928
- "X-Api-Key": this.apiKey
929
- },
1298
+ headers: this.authHeaders(),
930
1299
  body: JSON.stringify(validation.data)
931
1300
  }
932
1301
  );
@@ -943,9 +1312,7 @@ var RobotRock = class {
943
1312
  async cancelTaskRequest(taskId) {
944
1313
  const response = await fetch(`${this.baseUrl}/tasks/${taskId}/cancel`, {
945
1314
  method: "POST",
946
- headers: {
947
- "X-Api-Key": this.apiKey
948
- }
1315
+ headers: this.authHeaders()
949
1316
  });
950
1317
  if (!response.ok) {
951
1318
  const data = await parseResponseBody(response);
@@ -956,6 +1323,47 @@ var RobotRock = class {
956
1323
  );
957
1324
  }
958
1325
  }
1326
+ async listTasksRequest(input) {
1327
+ const params = new URLSearchParams();
1328
+ for (const [key, value] of Object.entries(input ?? {})) {
1329
+ if (value !== void 0 && value !== "") {
1330
+ params.set(key, String(value));
1331
+ }
1332
+ }
1333
+ const suffix = params.size > 0 ? `?${params.toString()}` : "";
1334
+ const response = await fetch(`${this.baseUrl}/tasks${suffix}`, {
1335
+ method: "GET",
1336
+ headers: this.authHeaders()
1337
+ });
1338
+ const data = await parseResponseBody(response);
1339
+ if (!response.ok) {
1340
+ throw new RobotRockError(
1341
+ getErrorMessage(data, "Failed to list tasks"),
1342
+ response.status,
1343
+ data
1344
+ );
1345
+ }
1346
+ return data;
1347
+ }
1348
+ async searchTasksRequest(input) {
1349
+ const params = new URLSearchParams({ q: input.q });
1350
+ if (input.limit !== void 0) {
1351
+ params.set("limit", String(input.limit));
1352
+ }
1353
+ const response = await fetch(`${this.baseUrl}/tasks/search?${params.toString()}`, {
1354
+ method: "GET",
1355
+ headers: this.authHeaders()
1356
+ });
1357
+ const data = await parseResponseBody(response);
1358
+ if (!response.ok) {
1359
+ throw new RobotRockError(
1360
+ getErrorMessage(data, "Failed to search tasks"),
1361
+ response.status,
1362
+ data
1363
+ );
1364
+ }
1365
+ return data;
1366
+ }
959
1367
  };
960
1368
  function createClient(config) {
961
1369
  return new RobotRock(config);
@@ -1001,16 +1409,24 @@ function normalizeSendToHumanInput(task, clientDefaults) {
1001
1409
  }
1002
1410
 
1003
1411
  // src/env.ts
1004
- var DEFAULT_BASE_URL = "https://api.robotrock.io/v1";
1005
1412
  function resolveRobotRockConfig(overrides) {
1413
+ const agentService = overrides?.agentService;
1006
1414
  const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;
1007
- if (!apiKey) {
1415
+ if (agentService && apiKey) {
1008
1416
  throw new Error(
1009
- "RobotRock API key is required. Set ROBOTROCK_API_KEY or pass apiKey when creating the client."
1417
+ "RobotRock client cannot configure both apiKey and agentService."
1010
1418
  );
1011
1419
  }
1012
- const baseUrl = overrides?.baseUrl ?? process.env.ROBOTROCK_BASE_URL ?? process.env.ROBOTROCK_API_URL ?? DEFAULT_BASE_URL;
1420
+ const baseUrl = overrides?.baseUrl ?? getRobotRockApiBaseUrl();
1013
1421
  const app = overrides?.app ?? process.env.ROBOTROCK_APP;
1422
+ if (agentService) {
1423
+ return app ? { agentService, baseUrl, app } : { agentService, baseUrl };
1424
+ }
1425
+ if (!apiKey) {
1426
+ throw new Error(
1427
+ "RobotRock API key is required. Set ROBOTROCK_API_KEY or pass agentService when creating the client."
1428
+ );
1429
+ }
1014
1430
  return app ? { apiKey, baseUrl, app } : { apiKey, baseUrl };
1015
1431
  }
1016
1432
  function resolveRobotRockClient(client, configOverrides) {
@@ -1111,20 +1527,295 @@ function shouldStopAgentForHandledAction(actionId) {
1111
1527
  return isPlatformTerminalAction(actionId);
1112
1528
  }
1113
1529
 
1530
+ // src/eve/input-request.ts
1531
+ var EVE_INPUT_SUBMIT_ACTION_ID = "submit";
1532
+ var EVE_INPUT_OTHER_CHOICE_ID = "__other__";
1533
+ var EVE_INPUT_OTHER_CHOICE_LABEL = "Type your own answer";
1534
+ var CONFIRMATION_DEFAULT_OPTIONS = [
1535
+ { id: "approve", label: "Approve", style: "primary" },
1536
+ { id: "deny", label: "Deny", style: "danger" }
1537
+ ];
1538
+ var SELECT_PER_OPTION_THRESHOLD = 6;
1539
+ function asRecord(value) {
1540
+ if (value == null || typeof value !== "object" || Array.isArray(value)) {
1541
+ return null;
1542
+ }
1543
+ return value;
1544
+ }
1545
+ function readStringField(data, key) {
1546
+ const value = data[key];
1547
+ if (typeof value !== "string") {
1548
+ return void 0;
1549
+ }
1550
+ const trimmed = value.trim();
1551
+ return trimmed.length > 0 ? trimmed : void 0;
1552
+ }
1553
+ function resolveEveInputDisplay(request, toolName) {
1554
+ if (request.display) {
1555
+ return request.display;
1556
+ }
1557
+ if (toolName === "ask_question") {
1558
+ return request.options && request.options.length > 0 ? "select" : "text";
1559
+ }
1560
+ if (request.options && request.options.length > 0) {
1561
+ return "select";
1562
+ }
1563
+ return "confirmation";
1564
+ }
1565
+ function confirmationActions(request) {
1566
+ const options = request.options && request.options.length > 0 ? request.options : CONFIRMATION_DEFAULT_OPTIONS;
1567
+ return options.map((option) => ({
1568
+ id: option.id,
1569
+ title: option.label,
1570
+ ...option.description ? { description: option.description } : {}
1571
+ }));
1572
+ }
1573
+ function textSubmitAction(prompt) {
1574
+ return {
1575
+ id: EVE_INPUT_SUBMIT_ACTION_ID,
1576
+ title: "Submit",
1577
+ schema: {
1578
+ type: "object",
1579
+ required: ["answer"],
1580
+ properties: {
1581
+ answer: {
1582
+ type: "string",
1583
+ title: "Your answer"
1584
+ }
1585
+ }
1586
+ },
1587
+ ui: {
1588
+ answer: {
1589
+ "ui:title": prompt.trim() || "Your answer",
1590
+ "ui:widget": "textarea"
1591
+ }
1592
+ }
1593
+ };
1594
+ }
1595
+ function selectPerOptionActions(options) {
1596
+ return options.map((option) => ({
1597
+ id: option.id,
1598
+ title: option.label,
1599
+ ...option.description ? { description: option.description } : {}
1600
+ }));
1601
+ }
1602
+ function selectFormAction(request) {
1603
+ const options = request.options ?? [];
1604
+ const allowFreeform = request.allowFreeform === true;
1605
+ const enumValues = options.map((option) => option.id);
1606
+ const enumNames = options.map((option) => option.label);
1607
+ if (allowFreeform) {
1608
+ enumValues.push(EVE_INPUT_OTHER_CHOICE_ID);
1609
+ enumNames.push(EVE_INPUT_OTHER_CHOICE_LABEL);
1610
+ }
1611
+ const properties = {
1612
+ choice: {
1613
+ type: "string",
1614
+ title: "Choose one",
1615
+ enum: enumValues
1616
+ }
1617
+ };
1618
+ if (allowFreeform) {
1619
+ properties.other = {
1620
+ type: "string",
1621
+ title: "Your answer"
1622
+ };
1623
+ }
1624
+ const schema = {
1625
+ type: "object",
1626
+ required: ["choice"],
1627
+ properties
1628
+ };
1629
+ if (allowFreeform) {
1630
+ schema.allOf = [
1631
+ {
1632
+ if: {
1633
+ properties: {
1634
+ choice: { const: EVE_INPUT_OTHER_CHOICE_ID }
1635
+ },
1636
+ required: ["choice"]
1637
+ },
1638
+ then: {
1639
+ required: ["other"],
1640
+ properties: {
1641
+ other: {
1642
+ type: "string",
1643
+ minLength: 1
1644
+ }
1645
+ }
1646
+ }
1647
+ }
1648
+ ];
1649
+ }
1650
+ const ui = {
1651
+ choice: {
1652
+ "ui:widget": "radio",
1653
+ "ui:enumNames": enumNames
1654
+ }
1655
+ };
1656
+ if (allowFreeform) {
1657
+ ui.other = {
1658
+ "ui:placeholder": "Enter your answer"
1659
+ };
1660
+ }
1661
+ return {
1662
+ id: EVE_INPUT_SUBMIT_ACTION_ID,
1663
+ title: "Submit",
1664
+ schema,
1665
+ ui
1666
+ };
1667
+ }
1668
+ function normalizeEveSelectFormData(data) {
1669
+ const choice = typeof data.choice === "string" ? data.choice.trim() : void 0;
1670
+ if (!choice) {
1671
+ return data;
1672
+ }
1673
+ if (choice === EVE_INPUT_OTHER_CHOICE_ID) {
1674
+ return {
1675
+ choice,
1676
+ ...data.other !== void 0 ? { other: data.other } : {}
1677
+ };
1678
+ }
1679
+ return { choice };
1680
+ }
1681
+ function eveInputRequestToActions(request, options) {
1682
+ const display = resolveEveInputDisplay(request, options?.toolName);
1683
+ switch (display) {
1684
+ case "confirmation":
1685
+ return confirmationActions(request);
1686
+ case "text":
1687
+ return [textSubmitAction(request.prompt)];
1688
+ case "select": {
1689
+ const selectOptions = request.options ?? [];
1690
+ if (selectOptions.length === 0) {
1691
+ return [textSubmitAction(request.prompt)];
1692
+ }
1693
+ if (selectOptions.length <= SELECT_PER_OPTION_THRESHOLD && request.allowFreeform !== true) {
1694
+ return selectPerOptionActions(selectOptions);
1695
+ }
1696
+ return [selectFormAction(request)];
1697
+ }
1698
+ }
1699
+ }
1700
+ function eveInputRequestTaskType(request, options) {
1701
+ const display = resolveEveInputDisplay(request, options?.toolName);
1702
+ if (display === "confirmation" && options?.toolName) {
1703
+ return `eve-approval:${options.toolName}`;
1704
+ }
1705
+ return `eve-input:${display}`;
1706
+ }
1707
+ function taskHandledToEveInputResponse(request, actionId, actionData, options) {
1708
+ const base = { requestId: request.requestId };
1709
+ if (isPlatformTerminalAction(actionId)) {
1710
+ const feedback = parsePlatformRejectRequestData(actionData)?.feedback;
1711
+ return {
1712
+ ...base,
1713
+ optionId: "deny",
1714
+ ...feedback ? { text: feedback } : {}
1715
+ };
1716
+ }
1717
+ const display = resolveEveInputDisplay(request, options?.toolName);
1718
+ const selectOptions = request.options ?? [];
1719
+ const data = asRecord(actionData);
1720
+ if (display === "confirmation") {
1721
+ return { ...base, optionId: actionId };
1722
+ }
1723
+ const matchingOption = selectOptions.find((option) => option.id === actionId);
1724
+ if (matchingOption) {
1725
+ return { ...base, optionId: actionId };
1726
+ }
1727
+ if (actionId === EVE_INPUT_SUBMIT_ACTION_ID && data) {
1728
+ const submissionData = display === "select" && request.allowFreeform === true ? normalizeEveSelectFormData(data) : data;
1729
+ const answer = readStringField(submissionData, "answer");
1730
+ if (answer) {
1731
+ return { ...base, text: answer };
1732
+ }
1733
+ const choice = readStringField(submissionData, "choice");
1734
+ if (choice === EVE_INPUT_OTHER_CHOICE_ID) {
1735
+ const other = readStringField(submissionData, "other");
1736
+ if (other) {
1737
+ return { ...base, text: other };
1738
+ }
1739
+ }
1740
+ if (choice) {
1741
+ if (selectOptions.some((option) => option.id === choice)) {
1742
+ return { ...base, optionId: choice };
1743
+ }
1744
+ return { ...base, text: choice };
1745
+ }
1746
+ }
1747
+ if (data) {
1748
+ const answer = readStringField(data, "answer");
1749
+ if (answer) {
1750
+ return { ...base, text: answer };
1751
+ }
1752
+ }
1753
+ return { ...base, optionId: actionId };
1754
+ }
1755
+
1756
+ // src/eve/tool-display.ts
1757
+ var DEFAULT_TOOL_DISPLAY_LABELS = {
1758
+ refund_charge: "Refund a customer charge",
1759
+ deploy_release: "Deploy a release",
1760
+ get_weather: "Get weather",
1761
+ get_my_access: "Check my access",
1762
+ whoami: "Who am I",
1763
+ create_robotrock_task: "Create a RobotRock task",
1764
+ search_products: "Search products",
1765
+ manage_team_members: "Manage team members",
1766
+ manage_groups: "Manage groups",
1767
+ query_tasks: "Query tasks"
1768
+ };
1769
+ var toolDisplayLabelOverrides = {};
1770
+ function setToolDisplayLabelOverrides(overrides) {
1771
+ toolDisplayLabelOverrides = overrides;
1772
+ }
1773
+ function formatToolName(toolName) {
1774
+ const spaced = toolName.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").trim();
1775
+ if (!spaced) {
1776
+ return "Tool";
1777
+ }
1778
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
1779
+ }
1780
+ function getToolDisplayLabel(toolName) {
1781
+ const trimmed = toolName.trim();
1782
+ if (!trimmed) {
1783
+ return "Tool";
1784
+ }
1785
+ return toolDisplayLabelOverrides[trimmed] ?? DEFAULT_TOOL_DISPLAY_LABELS[trimmed] ?? formatToolName(trimmed);
1786
+ }
1787
+ function formatEveApprovalTitle(request, toolName) {
1788
+ const display = resolveEveInputDisplay(request, toolName);
1789
+ if (display !== "confirmation" || !toolName) {
1790
+ return request.prompt;
1791
+ }
1792
+ return `Approve: ${getToolDisplayLabel(toolName)}`;
1793
+ }
1794
+
1795
+ // src/eve/resume-message.ts
1796
+ function buildTaskHandledResumeMessage(payload) {
1797
+ const handledBy = payload.handledBy?.trim() || "someone";
1798
+ const actionTitle = payload.action.title.trim();
1799
+ return `RobotRock task ${payload.taskId} was handled: ${actionTitle} by ${handledBy}. Briefly tell the user what was decided and what happens next.`;
1800
+ }
1801
+
1802
+ // src/eve/index.ts
1803
+ var ROBOTROCK_READY_HOOK_SLUG = "robotrock-ready";
1804
+
1114
1805
  // src/webhook.ts
1115
1806
  import { createHmac, timingSafeEqual } from "crypto";
1116
- import { z as z4 } from "zod";
1807
+ import { z as z6 } from "zod";
1117
1808
  var ROBOTROCK_SIGNATURE_HEADER = "x-robotrock-signature";
1118
- var robotRockWebhookPayloadBodySchema = z4.object({
1119
- taskId: z4.string().min(1),
1120
- action: z4.object({
1121
- id: z4.string().min(1),
1122
- title: z4.string().min(1),
1123
- data: z4.unknown()
1809
+ var robotRockWebhookPayloadBodySchema = z6.object({
1810
+ taskId: z6.string().min(1),
1811
+ action: z6.object({
1812
+ id: z6.string().min(1),
1813
+ title: z6.string().min(1),
1814
+ data: z6.unknown()
1124
1815
  }),
1125
- handledBy: z4.string().min(1).optional(),
1126
- handledAt: z4.string().min(1),
1127
- handlerType: z4.string().min(1)
1816
+ handledBy: z6.string().min(1).optional(),
1817
+ handledAt: z6.string().min(1),
1818
+ handlerType: z6.string().min(1)
1128
1819
  });
1129
1820
  var RobotRockWebhookError = class extends Error {
1130
1821
  constructor(message, code, details) {
@@ -1410,6 +2101,10 @@ function finishRobotRockHumanWaitOtel(session, handled, outcome) {
1410
2101
  export {
1411
2102
  DEFAULT_TASK_PRIORITY,
1412
2103
  DEFAULT_THREAD_UPDATE_STATUS,
2104
+ DEFAULT_TOOL_DISPLAY_LABELS,
2105
+ EVE_INPUT_OTHER_CHOICE_ID,
2106
+ EVE_INPUT_OTHER_CHOICE_LABEL,
2107
+ EVE_INPUT_SUBMIT_ACTION_ID,
1413
2108
  LOWEST_TASK_PRIORITY,
1414
2109
  PLATFORM_MARK_DONE_ACTION_ID,
1415
2110
  PLATFORM_MARK_DONE_ACTION_TITLE,
@@ -1417,6 +2112,7 @@ export {
1417
2112
  PLATFORM_REJECT_REQUEST_ACTION_TITLE,
1418
2113
  PLATFORM_TERMINAL_ACTION_IDS,
1419
2114
  PlatformRejectRequestError,
2115
+ ROBOTROCK_READY_HOOK_SLUG,
1420
2116
  RobotRock,
1421
2117
  RobotRockError,
1422
2118
  RobotRockWebhookError,
@@ -1430,26 +2126,35 @@ export {
1430
2126
  assignToSchema2 as assignToSchema,
1431
2127
  attachWebhookToActions,
1432
2128
  beginRobotRockHumanWaitOtel,
2129
+ buildTaskHandledResumeMessage,
1433
2130
  captureRobotRockOtelHandle,
1434
2131
  createAgentChatBodySchema,
1435
2132
  createChatsApi,
1436
2133
  createClient,
1437
2134
  createTaskBodySchema2 as createTaskBodySchema,
1438
2135
  endRobotRockHumanWaitSpan,
2136
+ eveInputRequestTaskType,
2137
+ eveInputRequestToActions,
1439
2138
  finishRobotRockHumanWaitOtel,
2139
+ formatEveApprovalTitle,
2140
+ getToolDisplayLabel,
1440
2141
  isPlatformMarkDoneAction,
1441
2142
  isPlatformRejectRequestAction,
1442
2143
  isPlatformTerminalAction,
2144
+ normalizeEveSelectFormData,
1443
2145
  parseHandledOutcome,
1444
2146
  parsePlatformRejectRequestData,
1445
2147
  recordRobotRockHandledToOtel,
2148
+ resolveEveInputDisplay,
1446
2149
  resolveRobotRockClient,
1447
2150
  resolveRobotRockConfig,
2151
+ setToolDisplayLabelOverrides,
1448
2152
  shouldRecordRobotRockOtel,
1449
2153
  shouldStopAgentForHandledAction,
1450
2154
  startRobotRockHumanWaitSpan,
1451
2155
  stripPlatformOtelFields,
1452
2156
  taskContextSchema2 as taskContextSchema,
2157
+ taskHandledToEveInputResponse,
1453
2158
  taskPriorities2 as taskPriorities,
1454
2159
  taskPrioritySchema2 as taskPrioritySchema,
1455
2160
  threadUpdateBodySchema,