robotrock 0.8.5 → 1.0.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.
@@ -259,12 +259,12 @@ function validateUrlValue(value, widget) {
259
259
  }
260
260
  return null;
261
261
  }
262
- function validateContextPublicUrls(context) {
263
- if (!context?.data) {
262
+ function validateContextPublicUrls(context2) {
263
+ if (!context2?.data) {
264
264
  return null;
265
265
  }
266
- for (const [field, value] of Object.entries(context.data)) {
267
- const widget = widgetType(context.ui, field);
266
+ for (const [field, value] of Object.entries(context2.data)) {
267
+ const widget = widgetType(context2.ui, field);
268
268
  if (!widget) {
269
269
  continue;
270
270
  }
@@ -284,6 +284,13 @@ var init_context_urls = __esm({
284
284
 
285
285
  // ../core/src/schemas/task.ts
286
286
  import { z } from "zod";
287
+ function normalizeTaskContextVersion(data) {
288
+ const { version: legacyVersion, contextVersion, ...rest } = data;
289
+ return {
290
+ ...rest,
291
+ contextVersion: contextVersion ?? legacyVersion ?? TASK_CONTEXT_FORMAT_VERSION
292
+ };
293
+ }
287
294
  function refineContextPublicUrls(data, ctx) {
288
295
  const error = validateContextPublicUrls(data.context);
289
296
  if (error) {
@@ -294,7 +301,7 @@ function refineContextPublicUrls(data, ctx) {
294
301
  });
295
302
  }
296
303
  }
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;
304
+ var safeUrlSchema, jsonSchema7Schema, uiSchemaSchema, webhookHandlerSchema, triggerHandlerSchema, handlerSchema, taskActionInputSchema, taskActionSchema, uiFieldSchemaSchema, contextUiSchema, contextDataSchema, TASK_CONTEXT_FORMAT_VERSION, taskContextObjectBaseSchema, taskContextObjectSchema, taskContextSchema, assignToSchema, threadUpdateMessageSchema, threadUpdateStatuses, threadUpdateStatusSchema, threadUpdateInputSchema, taskPriorities, taskPrioritySchema, agentTelemetrySchema, createTaskBodySchema, agentChatSeedActionSchema, agentChatSeedMessageSchema, createAgentChatBodySchema, agentChatTransportBodySchema;
298
305
  var init_task = __esm({
299
306
  "../core/src/schemas/task.ts"() {
300
307
  "use strict";
@@ -320,13 +327,15 @@ var init_task = __esm({
320
327
  tokenId: z.string().min(1)
321
328
  });
322
329
  handlerSchema = z.discriminatedUnion("type", [webhookHandlerSchema, triggerHandlerSchema]);
323
- taskActionSchema = z.object({
330
+ taskActionInputSchema = z.object({
324
331
  id: z.string().min(1),
325
332
  title: z.string().min(1),
326
333
  description: z.string().optional(),
327
334
  schema: jsonSchema7Schema.optional(),
328
335
  ui: uiSchemaSchema.optional(),
329
- data: z.record(z.string(), z.unknown()).optional(),
336
+ data: z.record(z.string(), z.unknown()).optional()
337
+ });
338
+ taskActionSchema = taskActionInputSchema.extend({
330
339
  // Optional handlers for this action - if present, must have at least 1
331
340
  handlers: z.array(handlerSchema).min(1).optional()
332
341
  });
@@ -342,7 +351,8 @@ var init_task = __esm({
342
351
  data: z.record(z.string(), z.unknown()),
343
352
  ui: contextUiSchema
344
353
  }).optional();
345
- taskContextObjectSchema = z.object({
354
+ TASK_CONTEXT_FORMAT_VERSION = 2;
355
+ taskContextObjectBaseSchema = z.object({
346
356
  /** Source application id; omitted tasks are grouped in the default inbox. */
347
357
  app: z.string().min(1).optional(),
348
358
  type: z.string().min(1),
@@ -350,9 +360,15 @@ var init_task = __esm({
350
360
  description: z.string().optional(),
351
361
  validUntil: z.string().optional(),
352
362
  context: contextDataSchema,
363
+ /** Task context wire format version. @default 2 */
364
+ contextVersion: z.literal(2).optional(),
365
+ /** @deprecated Use `contextVersion`. Accepted on ingest only. */
353
366
  version: z.literal(2).optional(),
354
367
  actions: z.array(taskActionSchema).min(1, "At least one action is required")
355
368
  });
369
+ taskContextObjectSchema = taskContextObjectBaseSchema.transform(
370
+ normalizeTaskContextVersion
371
+ );
356
372
  taskContextSchema = taskContextObjectSchema.superRefine(
357
373
  refineContextPublicUrls
358
374
  );
@@ -386,61 +402,11 @@ var init_task = __esm({
386
402
  });
387
403
  taskPriorities = ["low", "normal", "high", "urgent"];
388
404
  taskPrioritySchema = z.enum(taskPriorities);
389
- nonNegativeInt = z.number().int().nonnegative();
390
- agentCostTokensSchema = z.object({
391
- input: nonNegativeInt.optional(),
392
- output: nonNegativeInt.optional(),
393
- total: nonNegativeInt.optional()
394
- });
395
- agentCostSchema = z.object({
396
- tokens: agentCostTokensSchema.optional(),
397
- eur: z.number().nonnegative().optional(),
398
- usd: z.number().nonnegative().optional()
399
- });
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
- });
416
405
  agentTelemetrySchema = z.object({
417
406
  /** Agent or app version (semver, git SHA, deploy tag — caller-defined). */
418
- version: z.string().min(1).optional(),
419
- /** Total tool invocations. When omitted but `toolCalls` is set, the sum of counts is used. */
420
- toolCallCount: nonNegativeInt.optional(),
421
- /** Per-tool invocation counts keyed by tool name. */
422
- toolCalls: agentToolCallsSchema.optional(),
423
- cost: agentCostSchema.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()
428
- }).refine(
429
- (data) => {
430
- const keys = data.info ? Object.keys(data.info) : [];
431
- return keys.length <= AGENT_INFO_MAX_KEYS;
432
- },
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
- }
442
- );
443
- createTaskBodySchema = taskContextObjectSchema.extend({
407
+ version: z.string().min(1)
408
+ });
409
+ createTaskBodySchema = taskContextObjectBaseSchema.extend({
444
410
  assignTo: assignToSchema.optional(),
445
411
  /**
446
412
  * Groups related tasks together. When omitted, the server generates one and
@@ -457,9 +423,59 @@ var init_task = __esm({
457
423
  * the inbox status bar and the thread update log.
458
424
  */
459
425
  update: threadUpdateInputSchema.optional(),
460
- /** Agent telemetry (version, cost, tool calls) — not shown in inbox UI. */
426
+ /** Agent release version — not shown in inbox UI. */
461
427
  agent: agentTelemetrySchema.optional()
462
- }).superRefine(refineContextPublicUrls);
428
+ }).transform(normalizeTaskContextVersion).superRefine(refineContextPublicUrls);
429
+ agentChatSeedActionSchema = z.object({
430
+ /** Stable action id echoed back on submit; auto-derived from title when omitted. */
431
+ id: z.string().min(1).optional(),
432
+ title: z.string().min(1),
433
+ description: z.string().optional(),
434
+ /** JSON Schema object for the form fields. */
435
+ schema: z.record(z.string(), z.unknown()).optional(),
436
+ /** RJSF ui schema overrides (ui:widget, ui:enumNames, etc.). */
437
+ ui: z.record(z.string(), z.unknown()).optional(),
438
+ /** Optional default field values. */
439
+ data: z.record(z.string(), z.unknown()).optional()
440
+ });
441
+ agentChatSeedMessageSchema = z.object({
442
+ role: z.enum(["user", "assistant"]),
443
+ text: z.string().min(1),
444
+ /** Optional display-name override for the message sender. */
445
+ senderName: z.string().min(1).optional(),
446
+ /**
447
+ * Optional structured input request rendered as a styled RobotRock action
448
+ * widget below the message text. Use this instead of asking the user to reply
449
+ * in plain text so the request is always a proper action form.
450
+ */
451
+ requestActionInput: z.object({
452
+ prompt: z.string().optional(),
453
+ action: agentChatSeedActionSchema
454
+ }).optional()
455
+ });
456
+ createAgentChatBodySchema = z.object({
457
+ /** Trigger chat agent id (task slug). Required unless `parentChatId` is set. */
458
+ agentIdentifier: z.string().min(1).optional(),
459
+ /** Inherit tenant/connection/agent from an existing chat (agent-spawned chats). */
460
+ parentChatId: z.string().min(1).optional(),
461
+ /** Convex tenantTriggerConnections id; resolved from the tenant when omitted. */
462
+ connectionId: z.string().min(1).optional(),
463
+ /** Source application id; groups the chat under an inbox section. */
464
+ app: z.string().min(1).optional(),
465
+ assignTo: assignToSchema.optional(),
466
+ title: z.string().min(1),
467
+ messages: z.array(agentChatSeedMessageSchema).default([]),
468
+ /** Provenance label stored on the session ("cron" | "agent" | ...). */
469
+ source: z.string().min(1).optional()
470
+ }).refine((data) => Boolean(data.agentIdentifier || data.parentChatId), {
471
+ message: "Provide either agentIdentifier or parentChatId"
472
+ });
473
+ agentChatTransportBodySchema = z.object({
474
+ chatId: z.string().min(1),
475
+ publicAccessToken: z.string().min(1),
476
+ lastEventId: z.string().optional(),
477
+ isStreaming: z.boolean().optional()
478
+ });
463
479
  }
464
480
  });
465
481
 
@@ -482,6 +498,13 @@ var init_schemas = __esm({
482
498
 
483
499
  // src/schemas/index.ts
484
500
  import { z as z2 } from "zod";
501
+ function normalizeTaskContextVersion2(data) {
502
+ const { version: legacyVersion, contextVersion, ...rest } = data;
503
+ return {
504
+ ...rest,
505
+ contextVersion: contextVersion ?? legacyVersion ?? TASK_CONTEXT_FORMAT_VERSION2
506
+ };
507
+ }
485
508
  function refineContextPublicUrls2(data, ctx) {
486
509
  const error = validateContextPublicUrls(data.context);
487
510
  if (error) {
@@ -492,7 +515,7 @@ function refineContextPublicUrls2(data, ctx) {
492
515
  });
493
516
  }
494
517
  }
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;
518
+ var safeUrlSchema2, jsonSchema7Schema2, uiSchemaSchema2, webhookHandlerSchema2, triggerHandlerSchema2, handlerSchema2, taskActionInputSchema2, taskActionSchema2, uiFieldSchemaSchema2, contextUiSchema2, contextDataSchema2, TASK_CONTEXT_FORMAT_VERSION2, taskContextObjectBaseSchema2, taskContextObjectSchema2, taskContextSchema2, assignToSchema2, threadUpdateMessageSchema2, threadUpdateStatuses2, threadUpdateStatusSchema2, threadUpdateInputSchema2, taskPriorities2, taskPrioritySchema2, agentTelemetrySchema2, createTaskBodySchema2, threadUpdateBodySchema;
496
519
  var init_schemas2 = __esm({
497
520
  "src/schemas/index.ts"() {
498
521
  "use strict";
@@ -518,13 +541,15 @@ var init_schemas2 = __esm({
518
541
  tokenId: z2.string().min(1)
519
542
  });
520
543
  handlerSchema2 = z2.discriminatedUnion("type", [webhookHandlerSchema2, triggerHandlerSchema2]);
521
- taskActionSchema2 = z2.object({
544
+ taskActionInputSchema2 = z2.object({
522
545
  id: z2.string().min(1),
523
546
  title: z2.string().min(1),
524
547
  description: z2.string().optional(),
525
548
  schema: jsonSchema7Schema2.optional(),
526
549
  ui: uiSchemaSchema2.optional(),
527
- data: z2.record(z2.string(), z2.unknown()).optional(),
550
+ data: z2.record(z2.string(), z2.unknown()).optional()
551
+ });
552
+ taskActionSchema2 = taskActionInputSchema2.extend({
528
553
  handlers: z2.array(handlerSchema2).min(1).optional()
529
554
  });
530
555
  uiFieldSchemaSchema2 = z2.object({
@@ -539,16 +564,22 @@ var init_schemas2 = __esm({
539
564
  data: z2.record(z2.string(), z2.unknown()),
540
565
  ui: contextUiSchema2
541
566
  }).optional();
542
- taskContextObjectSchema2 = z2.object({
567
+ TASK_CONTEXT_FORMAT_VERSION2 = 2;
568
+ taskContextObjectBaseSchema2 = z2.object({
543
569
  app: z2.string().min(1).optional(),
544
570
  type: z2.string().min(1),
545
571
  name: z2.string().min(1),
546
572
  description: z2.string().optional(),
547
573
  validUntil: z2.string().optional(),
548
574
  context: contextDataSchema2,
575
+ contextVersion: z2.literal(2).optional(),
576
+ /** @deprecated Use `contextVersion`. Accepted on ingest only. */
549
577
  version: z2.literal(2).optional(),
550
578
  actions: z2.array(taskActionSchema2).min(1, "At least one action is required")
551
579
  });
580
+ taskContextObjectSchema2 = taskContextObjectBaseSchema2.transform(
581
+ normalizeTaskContextVersion2
582
+ );
552
583
  taskContextSchema2 = taskContextObjectSchema2.superRefine(
553
584
  refineContextPublicUrls2
554
585
  );
@@ -582,56 +613,10 @@ var init_schemas2 = __esm({
582
613
  });
583
614
  taskPriorities2 = ["low", "normal", "high", "urgent"];
584
615
  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
616
  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({
617
+ version: z2.string().min(1)
618
+ });
619
+ createTaskBodySchema2 = taskContextObjectBaseSchema2.extend({
635
620
  assignTo: assignToSchema2.optional(),
636
621
  /**
637
622
  * Groups related tasks together. When omitted, the server generates one and
@@ -649,7 +634,7 @@ var init_schemas2 = __esm({
649
634
  */
650
635
  update: threadUpdateInputSchema2.optional(),
651
636
  agent: agentTelemetrySchema2.optional()
652
- }).superRefine(refineContextPublicUrls2);
637
+ }).transform(normalizeTaskContextVersion2).superRefine(refineContextPublicUrls2);
653
638
  threadUpdateBodySchema = threadUpdateInputSchema2;
654
639
  }
655
640
  });
@@ -687,10 +672,248 @@ var init_approval_result = __esm({
687
672
  }
688
673
  });
689
674
 
675
+ // src/http.ts
676
+ async function parseResponseBody(response) {
677
+ const contentType = response.headers.get("content-type") ?? "";
678
+ const bodyText = await response.text();
679
+ if (!bodyText) {
680
+ return null;
681
+ }
682
+ if (contentType.toLowerCase().includes("application/json")) {
683
+ try {
684
+ return JSON.parse(bodyText);
685
+ } catch {
686
+ }
687
+ }
688
+ try {
689
+ return JSON.parse(bodyText);
690
+ } catch {
691
+ return bodyText;
692
+ }
693
+ }
694
+ function getErrorMessage(data, fallback) {
695
+ if (data && typeof data === "object" && !Array.isArray(data)) {
696
+ const maybeMessage = data.message;
697
+ if (typeof maybeMessage === "string" && maybeMessage.trim()) {
698
+ return maybeMessage;
699
+ }
700
+ }
701
+ if (typeof data === "string" && data.trim()) {
702
+ const compact = data.replace(/\s+/g, " ").trim();
703
+ const snippet = compact.length > 180 ? `${compact.slice(0, 180)}...` : compact;
704
+ return `${fallback}. Server returned non-JSON response: ${snippet}`;
705
+ }
706
+ return fallback;
707
+ }
708
+ var RobotRockError;
709
+ var init_http = __esm({
710
+ "src/http.ts"() {
711
+ "use strict";
712
+ RobotRockError = class extends Error {
713
+ constructor(message, statusCode, response) {
714
+ super(message);
715
+ this.statusCode = statusCode;
716
+ this.response = response;
717
+ this.name = "RobotRockError";
718
+ }
719
+ };
720
+ }
721
+ });
722
+
723
+ // ../core/src/types/task.ts
724
+ var init_task2 = __esm({
725
+ "../core/src/types/task.ts"() {
726
+ "use strict";
727
+ }
728
+ });
729
+
730
+ // ../core/src/types/json-schema-infer.ts
731
+ var init_json_schema_infer = __esm({
732
+ "../core/src/types/json-schema-infer.ts"() {
733
+ "use strict";
734
+ }
735
+ });
736
+
737
+ // ../core/src/types/index.ts
738
+ var init_types = __esm({
739
+ "../core/src/types/index.ts"() {
740
+ "use strict";
741
+ init_task2();
742
+ init_json_schema_infer();
743
+ }
744
+ });
745
+
746
+ // ../core/src/plans/index.ts
747
+ var init_plans = __esm({
748
+ "../core/src/plans/index.ts"() {
749
+ "use strict";
750
+ }
751
+ });
752
+
753
+ // ../core/src/handler-retry.ts
754
+ var HANDLER_RETRY_DELAYS_MS, HANDLER_MAX_ATTEMPTS;
755
+ var init_handler_retry = __esm({
756
+ "../core/src/handler-retry.ts"() {
757
+ "use strict";
758
+ HANDLER_RETRY_DELAYS_MS = [
759
+ 6e4,
760
+ // 1m
761
+ 3e5,
762
+ // 5m
763
+ 18e5,
764
+ // 30m
765
+ 36e5,
766
+ // 1h
767
+ 216e5,
768
+ // 6h
769
+ 864e5,
770
+ // 24h
771
+ 1728e5
772
+ // 48h
773
+ ];
774
+ HANDLER_MAX_ATTEMPTS = HANDLER_RETRY_DELAYS_MS.length + 1;
775
+ }
776
+ });
777
+
778
+ // ../core/src/legal.ts
779
+ var init_legal = __esm({
780
+ "../core/src/legal.ts"() {
781
+ "use strict";
782
+ }
783
+ });
784
+
785
+ // ../core/src/welcome-task.ts
786
+ var init_welcome_task = __esm({
787
+ "../core/src/welcome-task.ts"() {
788
+ "use strict";
789
+ }
790
+ });
791
+
792
+ // ../core/src/app-url.ts
793
+ var PRODUCTION_APP_URL, APP_SIGNUP_URL;
794
+ var init_app_url = __esm({
795
+ "../core/src/app-url.ts"() {
796
+ "use strict";
797
+ PRODUCTION_APP_URL = "https://app.robotrock.io";
798
+ APP_SIGNUP_URL = `${PRODUCTION_APP_URL}/sign-up`;
799
+ }
800
+ });
801
+
802
+ // ../core/src/attribution/index.ts
803
+ import { z as z3 } from "zod";
804
+ var ATTRIBUTION_COOKIE_MAX_AGE, attributionSchema;
805
+ var init_attribution = __esm({
806
+ "../core/src/attribution/index.ts"() {
807
+ "use strict";
808
+ init_app_url();
809
+ init_app_url();
810
+ ATTRIBUTION_COOKIE_MAX_AGE = 60 * 60 * 24 * 90;
811
+ attributionSchema = z3.object({
812
+ utmSource: z3.string().optional(),
813
+ utmMedium: z3.string().optional(),
814
+ utmCampaign: z3.string().optional(),
815
+ utmContent: z3.string().optional(),
816
+ utmTerm: z3.string().optional(),
817
+ gclid: z3.string().optional(),
818
+ landingUrl: z3.string().optional(),
819
+ referrer: z3.string().optional(),
820
+ capturedAt: z3.number()
821
+ });
822
+ }
823
+ });
824
+
825
+ // ../core/src/index.ts
826
+ var init_src = __esm({
827
+ "../core/src/index.ts"() {
828
+ "use strict";
829
+ init_schemas();
830
+ init_types();
831
+ init_utils();
832
+ init_plans();
833
+ init_handler_retry();
834
+ init_legal();
835
+ init_welcome_task();
836
+ init_attribution();
837
+ init_app_url();
838
+ }
839
+ });
840
+
841
+ // src/chats.ts
842
+ function createChatsApi(config) {
843
+ const headers = () => ({
844
+ "Content-Type": "application/json",
845
+ "X-Api-Key": config.apiKey
846
+ });
847
+ return {
848
+ async create(input) {
849
+ const bodyPayload = {
850
+ ...input,
851
+ app: input.app ?? config.app,
852
+ messages: input.messages ?? []
853
+ };
854
+ const validation = createAgentChatBodySchema.safeParse(bodyPayload);
855
+ if (!validation.success) {
856
+ throw new RobotRockError(
857
+ `Invalid chat: ${validation.error.issues[0]?.message}`,
858
+ 400,
859
+ validation.error.issues
860
+ );
861
+ }
862
+ const response = await fetch(`${config.baseUrl}/agent-chats`, {
863
+ method: "POST",
864
+ headers: headers(),
865
+ body: JSON.stringify(validation.data)
866
+ });
867
+ const data = await parseResponseBody(response);
868
+ if (!response.ok) {
869
+ throw new RobotRockError(
870
+ getErrorMessage(data, "Failed to create chat"),
871
+ response.status,
872
+ data
873
+ );
874
+ }
875
+ const result = data;
876
+ return { tenantSlug: result.tenantSlug, chats: result.chats };
877
+ },
878
+ async close(chatId, options) {
879
+ if (!chatId) {
880
+ throw new RobotRockError("chatId is required to close a chat", 400);
881
+ }
882
+ const response = await fetch(
883
+ `${config.baseUrl}/agent-chats/${encodeURIComponent(chatId)}/close`,
884
+ {
885
+ method: "POST",
886
+ headers: headers(),
887
+ body: JSON.stringify({ reason: options?.reason })
888
+ }
889
+ );
890
+ if (!response.ok) {
891
+ const data = await parseResponseBody(response);
892
+ throw new RobotRockError(
893
+ getErrorMessage(data, "Failed to close chat"),
894
+ response.status,
895
+ data
896
+ );
897
+ }
898
+ }
899
+ };
900
+ }
901
+ var init_chats = __esm({
902
+ "src/chats.ts"() {
903
+ "use strict";
904
+ init_src();
905
+ init_http();
906
+ }
907
+ });
908
+
690
909
  // src/client.ts
691
910
  function sleep(ms) {
692
911
  return new Promise((resolve) => setTimeout(resolve, ms));
693
912
  }
913
+ function resolveAgentVersionFromEnv() {
914
+ const fromEnv = process.env.AGENT_VERSION?.trim() || process.env.ROBOTROCK_AGENT_VERSION?.trim();
915
+ return fromEnv || void 0;
916
+ }
694
917
  function parseValidUntilMs(value) {
695
918
  if (value === void 0) {
696
919
  return void 0;
@@ -744,6 +967,7 @@ function normalizeSendToHumanInput(task2, clientDefaults) {
744
967
  threadId: _threadId,
745
968
  priority: _priority,
746
969
  update: _update,
970
+ version: _version,
747
971
  validUntil,
748
972
  app: taskApp,
749
973
  ...rest
@@ -753,67 +977,35 @@ function normalizeSendToHumanInput(task2, clientDefaults) {
753
977
  const app = taskApp ?? clientDefaults.app;
754
978
  return {
755
979
  ...rest,
756
- version: clientDefaults.version,
980
+ contextVersion: clientDefaults.contextVersion,
757
981
  ...app ? { app } : {},
758
982
  ...validUntil !== void 0 ? { validUntil: serializeValidUntil(validUntil) } : {},
759
983
  actions: normalizedActions
760
984
  };
761
985
  }
762
- async function parseResponseBody(response) {
763
- const contentType = response.headers.get("content-type") ?? "";
764
- const bodyText = await response.text();
765
- if (!bodyText) {
766
- return null;
767
- }
768
- if (contentType.toLowerCase().includes("application/json")) {
769
- try {
770
- return JSON.parse(bodyText);
771
- } catch {
772
- }
773
- }
774
- try {
775
- return JSON.parse(bodyText);
776
- } catch {
777
- return bodyText;
778
- }
779
- }
780
- function getErrorMessage(data, fallback) {
781
- if (data && typeof data === "object" && !Array.isArray(data)) {
782
- const maybeMessage = data.message;
783
- if (typeof maybeMessage === "string" && maybeMessage.trim()) {
784
- return maybeMessage;
785
- }
786
- }
787
- if (typeof data === "string" && data.trim()) {
788
- const compact = data.replace(/\s+/g, " ").trim();
789
- const snippet = compact.length > 180 ? `${compact.slice(0, 180)}...` : compact;
790
- return `${fallback}. Server returned non-JSON response: ${snippet}`;
791
- }
792
- return fallback;
793
- }
794
- var DEFAULT_POLL_INTERVAL_MS, DEFAULT_TIMEOUT_MS, RobotRockError, RobotRock;
986
+ var DEFAULT_POLL_INTERVAL_MS, DEFAULT_TIMEOUT_MS, RobotRock;
795
987
  var init_client = __esm({
796
988
  "src/client.ts"() {
797
989
  "use strict";
798
990
  init_schemas2();
799
991
  init_approval_result();
992
+ init_http();
993
+ init_chats();
994
+ init_http();
800
995
  DEFAULT_POLL_INTERVAL_MS = 2e3;
801
996
  DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
802
- RobotRockError = class extends Error {
803
- constructor(message, statusCode, response) {
804
- super(message);
805
- this.statusCode = statusCode;
806
- this.response = response;
807
- this.name = "RobotRockError";
808
- }
809
- };
810
997
  RobotRock = class {
811
998
  apiKey;
812
999
  baseUrl;
813
1000
  app;
814
- version;
1001
+ agentVersion;
1002
+ contextVersion;
815
1003
  webhook;
816
1004
  polling;
1005
+ /** Task CRUD: `create`, `get`, `cancel`, `sendUpdate`. */
1006
+ tasks;
1007
+ /** Chat CRUD: `create`, `close`. */
1008
+ chats;
817
1009
  constructor(config) {
818
1010
  if (config.webhook && config.polling) {
819
1011
  throw new Error(
@@ -830,26 +1022,37 @@ var init_client = __esm({
830
1022
  const rawBase = config.baseUrl ?? "https://api.robotrock.io/v1";
831
1023
  this.baseUrl = rawBase.replace(/\/+$/, "");
832
1024
  this.app = config.app;
833
- this.version = config.version ?? 2;
1025
+ this.agentVersion = config.version ?? resolveAgentVersionFromEnv();
1026
+ this.contextVersion = config.advanced?.contextVersion ?? TASK_CONTEXT_FORMAT_VERSION2;
834
1027
  this.webhook = config.webhook;
835
1028
  this.polling = config.polling ?? {};
1029
+ this.tasks = {
1030
+ create: (task2) => this.createTaskRequest(task2),
1031
+ get: (taskId) => this.getTaskById(taskId),
1032
+ cancel: (taskId) => this.cancelTaskRequest(taskId),
1033
+ sendUpdate: (input) => this.sendThreadUpdate(input)
1034
+ };
1035
+ this.chats = createChatsApi({
1036
+ baseUrl: this.baseUrl,
1037
+ apiKey: this.apiKey,
1038
+ app: this.app
1039
+ });
836
1040
  }
837
- /**
838
- * Create a task via POST /v1 without waiting for a human response.
839
- */
840
- async createTask(task2) {
1041
+ async createTaskRequest(task2) {
841
1042
  const normalizedTask = normalizeSendToHumanInput(task2, {
842
1043
  webhook: this.webhook,
843
1044
  app: this.app,
844
- version: this.version
1045
+ contextVersion: this.contextVersion,
1046
+ agentVersion: this.agentVersion
845
1047
  });
1048
+ const agentVersion = task2.version ?? this.agentVersion;
846
1049
  const bodyPayload = {
847
1050
  ...normalizedTask,
848
1051
  ...task2.assignTo !== void 0 ? { assignTo: task2.assignTo } : {},
849
1052
  ...task2.threadId !== void 0 ? { threadId: task2.threadId } : {},
850
1053
  ...task2.priority !== void 0 ? { priority: task2.priority } : {},
851
1054
  ...task2.update !== void 0 ? { update: task2.update } : {},
852
- ...task2.agent !== void 0 ? { agent: task2.agent } : {}
1055
+ ...agentVersion !== void 0 ? { agent: { version: agentVersion } } : {}
853
1056
  };
854
1057
  const validation = createTaskBodySchema2.safeParse(bodyPayload);
855
1058
  if (!validation.success) {
@@ -885,9 +1088,10 @@ var init_client = __esm({
885
1088
  const normalizedTask = normalizeSendToHumanInput(task2, {
886
1089
  webhook: this.webhook,
887
1090
  app: this.app,
888
- version: this.version
1091
+ contextVersion: this.contextVersion,
1092
+ agentVersion: this.agentVersion
889
1093
  });
890
- const createdTaskTask = await this.createTask(task2);
1094
+ const createdTaskTask = await this.createTaskRequest(task2);
891
1095
  const hasHandlers = normalizedTask.actions.some(
892
1096
  (action) => Array.isArray(action.handlers) && action.handlers.length > 0
893
1097
  );
@@ -904,7 +1108,7 @@ var init_client = __esm({
904
1108
  const deadline = validUntilMs !== void 0 ? Math.min(pollingDeadline, validUntilMs) : pollingDeadline;
905
1109
  const taskId = createdTaskTask.taskId;
906
1110
  while (Date.now() < deadline) {
907
- const existing = await this.getTask(taskId);
1111
+ const existing = await this.getTaskById(taskId);
908
1112
  if (existing?.status === "handled" && existing.handled) {
909
1113
  return {
910
1114
  mode: "handled",
@@ -926,10 +1130,35 @@ var init_client = __esm({
926
1130
  }
927
1131
  throw new TaskTimeoutError(`No human response within ${timeoutMs}ms`);
928
1132
  }
1133
+ /**
1134
+ * Create a task via POST /v1 without waiting for a human response.
1135
+ * @deprecated Use `client.tasks.create()` instead.
1136
+ */
1137
+ async createTask(task2) {
1138
+ return this.tasks.create(task2);
1139
+ }
929
1140
  /**
930
1141
  * Get a task by public task id (returned as `task.taskId` from {@link sendToHuman}).
1142
+ * @deprecated Use `client.tasks.get()` instead.
931
1143
  */
932
1144
  async getTask(taskId) {
1145
+ return this.tasks.get(taskId);
1146
+ }
1147
+ /**
1148
+ * Log a status update against a thread.
1149
+ * @deprecated Use `client.tasks.sendUpdate()` instead.
1150
+ */
1151
+ async sendUpdate(input) {
1152
+ return this.tasks.sendUpdate(input);
1153
+ }
1154
+ /**
1155
+ * Cancel a task by public task id.
1156
+ * @deprecated Use `client.tasks.cancel()` instead.
1157
+ */
1158
+ async cancelTask(taskId) {
1159
+ return this.tasks.cancel(taskId);
1160
+ }
1161
+ async getTaskById(taskId) {
933
1162
  const response = await fetch(`${this.baseUrl}/tasks/${taskId}`, {
934
1163
  method: "GET",
935
1164
  headers: {
@@ -949,11 +1178,11 @@ var init_client = __esm({
949
1178
  }
950
1179
  return data;
951
1180
  }
952
- /**
953
- * Log a status update against a thread. The update shows in the inbox status
954
- * bar and thread update log for every task in the thread.
955
- */
956
- async sendUpdate({ threadId, message, status }) {
1181
+ async sendThreadUpdate({
1182
+ threadId,
1183
+ message,
1184
+ status
1185
+ }) {
957
1186
  if (!threadId) {
958
1187
  throw new RobotRockError("threadId is required to send an update", 400);
959
1188
  }
@@ -986,7 +1215,7 @@ var init_client = __esm({
986
1215
  }
987
1216
  return data.update;
988
1217
  }
989
- async cancelTask(taskId) {
1218
+ async cancelTaskRequest(taskId) {
990
1219
  const response = await fetch(`${this.baseUrl}/tasks/${taskId}/cancel`, {
991
1220
  method: "POST",
992
1221
  headers: {
@@ -1027,6 +1256,212 @@ var init_env = __esm({
1027
1256
  }
1028
1257
  });
1029
1258
 
1259
+ // src/record-handled-to-otel.ts
1260
+ import {
1261
+ context,
1262
+ trace,
1263
+ SpanStatusCode
1264
+ } from "@opentelemetry/api";
1265
+ function isValidTraceId(traceId) {
1266
+ return typeof traceId === "string" && traceId.length > 0 && traceId !== INVALID_TRACE_ID;
1267
+ }
1268
+ function resolveSpanContext(span) {
1269
+ const active = span ?? trace.getActiveSpan();
1270
+ const ctx = active?.spanContext();
1271
+ if (!ctx || !isValidTraceId(ctx.traceId)) {
1272
+ return void 0;
1273
+ }
1274
+ return { traceId: ctx.traceId, spanId: ctx.spanId };
1275
+ }
1276
+ function parseTaskCreatedAt(submittedAt) {
1277
+ if (submittedAt) {
1278
+ const parsed = Date.parse(submittedAt);
1279
+ if (!Number.isNaN(parsed)) {
1280
+ return parsed;
1281
+ }
1282
+ }
1283
+ return Date.now();
1284
+ }
1285
+ function parseHandledAtMs(handledAt) {
1286
+ if (handledAt instanceof Date) {
1287
+ return handledAt.getTime();
1288
+ }
1289
+ if (typeof handledAt === "number") {
1290
+ return handledAt;
1291
+ }
1292
+ const parsed = Date.parse(handledAt);
1293
+ return Number.isNaN(parsed) ? Date.now() : parsed;
1294
+ }
1295
+ function toRobotRockHandledOtelInput(handled) {
1296
+ if ("actionId" in handled) {
1297
+ return {
1298
+ taskId: handled.taskId,
1299
+ action: {
1300
+ id: handled.actionId,
1301
+ data: handled.data
1302
+ },
1303
+ handledBy: handled.handledBy,
1304
+ handledAt: handled.handledAt
1305
+ };
1306
+ }
1307
+ return {
1308
+ taskId: handled.taskId,
1309
+ action: {
1310
+ id: handled.action.id,
1311
+ title: handled.action.title,
1312
+ data: handled.action.data
1313
+ },
1314
+ handledBy: handled.handledBy,
1315
+ handledAt: handled.handledAt
1316
+ };
1317
+ }
1318
+ function captureRobotRockOtelHandle(task2, options) {
1319
+ const spanCtx = resolveSpanContext(options?.span);
1320
+ return {
1321
+ traceId: spanCtx?.traceId ?? "",
1322
+ spanId: spanCtx?.spanId ?? "",
1323
+ taskId: task2.taskId,
1324
+ threadId: task2.threadId,
1325
+ taskCreatedAt: parseTaskCreatedAt(task2.submittedAt)
1326
+ };
1327
+ }
1328
+ function startRobotRockHumanWaitSpan(handle, options) {
1329
+ const parent = options?.span ?? trace.getActiveSpan();
1330
+ if (!parent) {
1331
+ return void 0;
1332
+ }
1333
+ const tracer = trace.getTracer(options?.tracerName ?? TRACER_NAME);
1334
+ const span = tracer.startSpan(
1335
+ WAIT_SPAN_NAME,
1336
+ {},
1337
+ trace.setSpan(context.active(), parent)
1338
+ );
1339
+ span.setAttribute("robotrock.task_id", handle.taskId);
1340
+ if (handle.threadId) {
1341
+ span.setAttribute("robotrock.thread_id", handle.threadId);
1342
+ }
1343
+ return span;
1344
+ }
1345
+ function recordRobotRockHandledToOtel(handled, options = {}) {
1346
+ const span = options.span ?? trace.getActiveSpan();
1347
+ if (!span) {
1348
+ return;
1349
+ }
1350
+ const input = toRobotRockHandledOtelInput(handled);
1351
+ const handledAtMs = parseHandledAtMs(input.handledAt);
1352
+ const handle = options.handle;
1353
+ const humanWaitMs = handle != null ? Math.max(0, handledAtMs - handle.taskCreatedAt) : void 0;
1354
+ span.setAttribute("robotrock.task_id", input.taskId);
1355
+ span.setAttribute("robotrock.action.id", input.action.id);
1356
+ if (input.action.title) {
1357
+ span.setAttribute("robotrock.action.title", input.action.title);
1358
+ }
1359
+ if (input.handledBy) {
1360
+ span.setAttribute("robotrock.handled_by", input.handledBy);
1361
+ }
1362
+ span.setAttribute("robotrock.handled_at", new Date(handledAtMs).toISOString());
1363
+ if (humanWaitMs != null) {
1364
+ span.setAttribute("robotrock.human_wait_ms", humanWaitMs);
1365
+ }
1366
+ if (input.threadId) {
1367
+ span.setAttribute("robotrock.thread_id", input.threadId);
1368
+ }
1369
+ const eventAttributes = {
1370
+ "robotrock.task_id": input.taskId,
1371
+ "robotrock.action.id": input.action.id
1372
+ };
1373
+ if (input.handledBy) {
1374
+ eventAttributes["robotrock.handled_by"] = input.handledBy;
1375
+ }
1376
+ if (humanWaitMs != null) {
1377
+ eventAttributes["robotrock.human_wait_ms"] = humanWaitMs;
1378
+ }
1379
+ if (options.includeActionData && input.action.data != null) {
1380
+ const serialized = JSON.stringify(input.action.data);
1381
+ const truncated = serialized.length > 512 ? `${serialized.slice(0, 512)}\u2026` : serialized;
1382
+ span.setAttribute("robotrock.action.data", truncated);
1383
+ eventAttributes["robotrock.action.data"] = truncated;
1384
+ }
1385
+ span.addEvent(HANDLED_EVENT_NAME, eventAttributes);
1386
+ }
1387
+ function endRobotRockHumanWaitSpan(span, handled, options = {}) {
1388
+ if (!span) {
1389
+ return;
1390
+ }
1391
+ const outcome = options.outcome ?? (handled ? "handled" : "timeout");
1392
+ if (handled && outcome === "handled") {
1393
+ recordRobotRockHandledToOtel(handled, {
1394
+ span,
1395
+ handle: options.handle,
1396
+ includeActionData: options.includeActionData
1397
+ });
1398
+ span.setStatus({ code: SpanStatusCode.OK });
1399
+ } else {
1400
+ span.setAttribute("robotrock.outcome", outcome);
1401
+ span.setStatus({
1402
+ code: SpanStatusCode.ERROR,
1403
+ message: outcome === "timeout" ? "Human response timed out before validUntil" : "Human wait failed"
1404
+ });
1405
+ }
1406
+ span.end();
1407
+ }
1408
+ var TRACER_NAME, WAIT_SPAN_NAME, HANDLED_EVENT_NAME, INVALID_TRACE_ID;
1409
+ var init_record_handled_to_otel = __esm({
1410
+ "src/record-handled-to-otel.ts"() {
1411
+ "use strict";
1412
+ TRACER_NAME = "robotrock";
1413
+ WAIT_SPAN_NAME = "robotrock.wait_for_human";
1414
+ HANDLED_EVENT_NAME = "robotrock.task_handled";
1415
+ INVALID_TRACE_ID = "00000000000000000000000000000000";
1416
+ }
1417
+ });
1418
+
1419
+ // src/otel-platform.ts
1420
+ function shouldRecordRobotRockOtel(recordOtel) {
1421
+ if (recordOtel === true) {
1422
+ return true;
1423
+ }
1424
+ if (recordOtel === false) {
1425
+ return false;
1426
+ }
1427
+ const env = process.env.ROBOTROCK_OTEL_RECORD_HANDLED;
1428
+ return env === "true" || env === "1";
1429
+ }
1430
+ function stripPlatformOtelFields(payload) {
1431
+ const { recordOtel: _recordOtel, otelIncludeActionData: _otelIncludeActionData, ...rest } = payload;
1432
+ return rest;
1433
+ }
1434
+ function beginRobotRockHumanWaitOtel(task2, options = {}) {
1435
+ const recordOtel = shouldRecordRobotRockOtel(options.recordOtel);
1436
+ if (!recordOtel) {
1437
+ return { recordOtel: false };
1438
+ }
1439
+ const handle = captureRobotRockOtelHandle(task2);
1440
+ const waitSpan = startRobotRockHumanWaitSpan(handle);
1441
+ return {
1442
+ recordOtel: true,
1443
+ handle,
1444
+ waitSpan,
1445
+ includeActionData: options.otelIncludeActionData
1446
+ };
1447
+ }
1448
+ function finishRobotRockHumanWaitOtel(session, handled, outcome) {
1449
+ if (!session.recordOtel) {
1450
+ return;
1451
+ }
1452
+ endRobotRockHumanWaitSpan(session.waitSpan, handled, {
1453
+ handle: session.handle,
1454
+ outcome,
1455
+ includeActionData: session.includeActionData
1456
+ });
1457
+ }
1458
+ var init_otel_platform = __esm({
1459
+ "src/otel-platform.ts"() {
1460
+ "use strict";
1461
+ init_record_handled_to_otel();
1462
+ }
1463
+ });
1464
+
1030
1465
  // src/handler-webhook.ts
1031
1466
  function isRobotRockHandlerWebhookPayload(value) {
1032
1467
  if (typeof value !== "object" || value === null) {
@@ -1107,7 +1542,7 @@ __export(trigger_exports, {
1107
1542
  });
1108
1543
  import { task, wait } from "@trigger.dev/sdk";
1109
1544
  async function runSendToHuman(payload) {
1110
- const { validUntil: validUntilInput, ...taskInput } = payload;
1545
+ const { validUntil: validUntilInput, app, recordOtel, otelIncludeActionData, ...taskFields } = payload;
1111
1546
  const { validUntil, timeout } = resolveWaitTiming(validUntilInput);
1112
1547
  const token = await wait.createToken({ timeout });
1113
1548
  const baseConfig = resolveRobotRockConfig();
@@ -1116,45 +1551,74 @@ async function runSendToHuman(payload) {
1116
1551
  baseUrl: baseConfig.baseUrl,
1117
1552
  ...baseConfig.app ? { app: baseConfig.app } : {},
1118
1553
  ...baseConfig.version ? { version: baseConfig.version } : {},
1554
+ ...baseConfig.advanced ? { advanced: baseConfig.advanced } : {},
1119
1555
  webhook: { url: token.url }
1120
1556
  });
1557
+ const taskInput = stripPlatformOtelFields(taskFields);
1121
1558
  const sendResult = await client.sendToHuman({
1122
1559
  ...taskInput,
1123
- validUntil
1560
+ validUntil,
1561
+ ...app !== void 0 ? { app } : {}
1124
1562
  });
1125
- const outcome = await wait.forToken(token.id);
1126
- if (!outcome.ok) {
1127
- throw new Error(`Human response timed out before validUntil (${timeout})`);
1128
- }
1129
- const output = outcome.output;
1130
- if (!isRobotRockHandlerWebhookPayload(output)) {
1131
- throw new Error(
1132
- "Wait token completed with unexpected payload; expected RobotRock handler body (taskId, action.id, action.data)."
1133
- );
1134
- }
1135
- return toDiscriminatedApprovalResult(
1136
- payload.actions,
1137
- {
1138
- id: output.taskId,
1139
- createdAt: /* @__PURE__ */ new Date(),
1140
- status: "handled",
1141
- context: sendResult.task.context,
1142
- validUntil: Date.now(),
1143
- handledAt: new Date(output.handledAt).getTime(),
1144
- handled: {
1145
- action: {
1146
- id: output.action.id,
1147
- data: output.action.data
1148
- },
1149
- handledBy: output.handledBy
1563
+ const otelSession = beginRobotRockHumanWaitOtel(sendResult.task, {
1564
+ recordOtel,
1565
+ otelIncludeActionData
1566
+ });
1567
+ let handledPayload = null;
1568
+ let waitOutcome = "pending";
1569
+ try {
1570
+ const outcome = await wait.forToken(token.id);
1571
+ if (!outcome.ok) {
1572
+ waitOutcome = "timeout";
1573
+ throw new Error(`Human response timed out before validUntil (${timeout})`);
1574
+ }
1575
+ const output = outcome.output;
1576
+ if (!isRobotRockHandlerWebhookPayload(output)) {
1577
+ waitOutcome = "error";
1578
+ throw new Error(
1579
+ "Wait token completed with unexpected payload; expected RobotRock handler body (taskId, action.id, action.data)."
1580
+ );
1581
+ }
1582
+ handledPayload = output;
1583
+ waitOutcome = "handled";
1584
+ return toDiscriminatedApprovalResult(
1585
+ payload.actions,
1586
+ {
1587
+ id: output.taskId,
1588
+ createdAt: /* @__PURE__ */ new Date(),
1589
+ status: "handled",
1590
+ context: sendResult.task.context,
1591
+ validUntil: Date.now(),
1592
+ handledAt: new Date(output.handledAt).getTime(),
1593
+ handled: {
1594
+ action: {
1595
+ id: output.action.id,
1596
+ data: output.action.data
1597
+ },
1598
+ handledBy: output.handledBy
1599
+ }
1150
1600
  }
1601
+ );
1602
+ } catch (error) {
1603
+ if (waitOutcome === "pending") {
1604
+ waitOutcome = "error";
1151
1605
  }
1152
- );
1606
+ throw error;
1607
+ } finally {
1608
+ if (waitOutcome !== "pending") {
1609
+ finishRobotRockHumanWaitOtel(
1610
+ otelSession,
1611
+ handledPayload,
1612
+ waitOutcome === "handled" ? "handled" : waitOutcome
1613
+ );
1614
+ }
1615
+ }
1153
1616
  }
1154
1617
  var APPROVE_BY_HUMAN_ACTIONS, sendToHumanTask, approveByHumanTask;
1155
1618
  var init_trigger = __esm({
1156
1619
  "src/trigger/index.ts"() {
1157
1620
  "use strict";
1621
+ init_otel_platform();
1158
1622
  init_client();
1159
1623
  init_env();
1160
1624
  init_approval_result();
@@ -1194,6 +1658,7 @@ async function createRobotRockTaskForWebhook(input) {
1194
1658
  baseUrl: baseConfig.baseUrl,
1195
1659
  ...input.app ?? baseConfig.app ? { app: input.app ?? baseConfig.app } : {},
1196
1660
  ...baseConfig.version ? { version: baseConfig.version } : {},
1661
+ ...baseConfig.advanced ? { advanced: baseConfig.advanced } : {},
1197
1662
  webhook: { url: input.webhookUrl }
1198
1663
  });
1199
1664
  return client.sendToHuman({
@@ -1214,7 +1679,7 @@ async function parseRobotRockWebhookRequest(request) {
1214
1679
  async function sendToHumanInWorkflow(payload) {
1215
1680
  var _stack = [];
1216
1681
  try {
1217
- const { validUntil: validUntilInput, app, ...taskInput } = payload;
1682
+ const { validUntil: validUntilInput, app, recordOtel, otelIncludeActionData, ...taskFields } = payload;
1218
1683
  const { validUntil, timeout } = resolveWaitTiming(validUntilInput);
1219
1684
  const timeoutMs = parseValidUntilMs2(validUntil) - Date.now();
1220
1685
  const webhook = __using(_stack, createWebhook());
@@ -1222,31 +1687,54 @@ async function sendToHumanInWorkflow(payload) {
1222
1687
  webhookUrl: webhook.url,
1223
1688
  app,
1224
1689
  validUntil,
1225
- taskInput
1690
+ taskInput: stripPlatformOtelFields(taskFields)
1226
1691
  });
1227
- const outcome = await Promise.race([
1228
- webhook.then((request) => parseRobotRockWebhookRequest(request)),
1229
- sleep2(timeoutMs).then(() => ({ timedOut: true }))
1230
- ]);
1231
- if ("timedOut" in outcome) {
1232
- throw new Error(`Human response timed out before validUntil (${timeout})`);
1233
- }
1234
- const output = outcome;
1235
- return toDiscriminatedApprovalResult(payload.actions, {
1236
- id: output.taskId,
1237
- createdAt: /* @__PURE__ */ new Date(),
1238
- status: "handled",
1239
- context: sendResult.task.context,
1240
- validUntil: Date.now(),
1241
- handledAt: new Date(output.handledAt).getTime(),
1242
- handled: {
1243
- action: {
1244
- id: output.action.id,
1245
- data: output.action.data
1246
- },
1247
- handledBy: output.handledBy
1248
- }
1692
+ const otelSession = beginRobotRockHumanWaitOtel(sendResult.task, {
1693
+ recordOtel,
1694
+ otelIncludeActionData
1249
1695
  });
1696
+ let handledPayload = null;
1697
+ let waitOutcome = "pending";
1698
+ try {
1699
+ const outcome = await Promise.race([
1700
+ webhook.then((request) => parseRobotRockWebhookRequest(request)),
1701
+ sleep2(timeoutMs).then(() => ({ timedOut: true }))
1702
+ ]);
1703
+ if ("timedOut" in outcome) {
1704
+ waitOutcome = "timeout";
1705
+ throw new Error(`Human response timed out before validUntil (${timeout})`);
1706
+ }
1707
+ handledPayload = outcome;
1708
+ waitOutcome = "handled";
1709
+ return toDiscriminatedApprovalResult(payload.actions, {
1710
+ id: outcome.taskId,
1711
+ createdAt: /* @__PURE__ */ new Date(),
1712
+ status: "handled",
1713
+ context: sendResult.task.context,
1714
+ validUntil: Date.now(),
1715
+ handledAt: new Date(outcome.handledAt).getTime(),
1716
+ handled: {
1717
+ action: {
1718
+ id: outcome.action.id,
1719
+ data: outcome.action.data
1720
+ },
1721
+ handledBy: outcome.handledBy
1722
+ }
1723
+ });
1724
+ } catch (error) {
1725
+ if (waitOutcome === "pending") {
1726
+ waitOutcome = "error";
1727
+ }
1728
+ throw error;
1729
+ } finally {
1730
+ if (waitOutcome !== "pending") {
1731
+ finishRobotRockHumanWaitOtel(
1732
+ otelSession,
1733
+ handledPayload,
1734
+ waitOutcome === "handled" ? "handled" : waitOutcome
1735
+ );
1736
+ }
1737
+ }
1250
1738
  } catch (_) {
1251
1739
  var _error = _, _hasError = true;
1252
1740
  } finally {
@@ -1267,9 +1755,10 @@ async function sendRobotRockUpdate(payload) {
1267
1755
  apiKey: baseConfig.apiKey,
1268
1756
  baseUrl: baseConfig.baseUrl,
1269
1757
  ...app ?? baseConfig.app ? { app: app ?? baseConfig.app } : {},
1270
- ...baseConfig.version ? { version: baseConfig.version } : {}
1758
+ ...baseConfig.version ? { version: baseConfig.version } : {},
1759
+ ...baseConfig.advanced ? { advanced: baseConfig.advanced } : {}
1271
1760
  });
1272
- return client.sendUpdate(update);
1761
+ return client.tasks.sendUpdate(update);
1273
1762
  }
1274
1763
  async function sendUpdateInWorkflow(payload) {
1275
1764
  return sendRobotRockUpdate(payload);
@@ -1283,6 +1772,7 @@ var init_workflow = __esm({
1283
1772
  init_approval_result();
1284
1773
  init_handler_webhook();
1285
1774
  init_wait_timing();
1775
+ init_otel_platform();
1286
1776
  APPROVE_BY_HUMAN_ACTIONS2 = [
1287
1777
  { id: "approve", title: "Approve" },
1288
1778
  { id: "decline", title: "Decline" }
@@ -1291,7 +1781,7 @@ var init_workflow = __esm({
1291
1781
  });
1292
1782
 
1293
1783
  // src/ai/approve-by-human-tool-core.ts
1294
- import { z as z3 } from "zod";
1784
+ import { z as z4 } from "zod";
1295
1785
 
1296
1786
  // src/ai/context.ts
1297
1787
  init_client();
@@ -1321,27 +1811,27 @@ function normalizeRobotRockAiContext(clientOrContext) {
1321
1811
  }
1322
1812
  throw new Error(`Unknown RobotRock AI mode: ${String(clientOrContext.mode)}`);
1323
1813
  }
1324
- async function sendToHumanForAi(context, payload) {
1325
- if (context.mode === "trigger") {
1814
+ async function sendToHumanForAi(context2, payload) {
1815
+ if (context2.mode === "trigger") {
1326
1816
  const { sendToHumanTask: sendToHumanTask2 } = await Promise.resolve().then(() => (init_trigger(), trigger_exports));
1327
1817
  const waitResult = await sendToHumanTask2.triggerAndWait({
1328
1818
  ...payload,
1329
- ...context.app ? { app: context.app } : {}
1819
+ ...context2.app ? { app: context2.app } : {}
1330
1820
  });
1331
1821
  if (!waitResult.ok) {
1332
1822
  throw waitResult.error;
1333
1823
  }
1334
1824
  return waitResult.output;
1335
1825
  }
1336
- if (context.mode === "workflow") {
1826
+ if (context2.mode === "workflow") {
1337
1827
  const { sendToHumanInWorkflow: sendToHumanInWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1338
1828
  const result2 = await sendToHumanInWorkflow2({
1339
1829
  ...payload,
1340
- ...context.app ? { app: context.app } : {}
1830
+ ...context2.app ? { app: context2.app } : {}
1341
1831
  });
1342
1832
  return result2;
1343
1833
  }
1344
- const result = await context.client.sendToHuman(payload);
1834
+ const result = await context2.client.sendToHuman(payload);
1345
1835
  if (result.mode !== "handled") {
1346
1836
  throw new Error(
1347
1837
  "RobotRock task was created but not handled. Configure client polling or webhook, or use mode: 'trigger' / 'workflow' for durable waits."
@@ -1355,42 +1845,42 @@ async function sendToHumanForAi(context, payload) {
1355
1845
  taskId: result.taskId
1356
1846
  };
1357
1847
  }
1358
- async function sendUpdateForAi(context, payload) {
1359
- if (context.mode === "workflow") {
1848
+ async function sendUpdateForAi(context2, payload) {
1849
+ if (context2.mode === "workflow") {
1360
1850
  const { sendUpdateInWorkflow: sendUpdateInWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1361
1851
  return sendUpdateInWorkflow2({
1362
1852
  ...payload,
1363
- ...context.app ? { app: context.app } : {}
1853
+ ...context2.app ? { app: context2.app } : {}
1364
1854
  });
1365
1855
  }
1366
- if (context.mode === "trigger") {
1856
+ if (context2.mode === "trigger") {
1367
1857
  const client = createClient(
1368
- resolveRobotRockConfig(context.app ? { app: context.app } : void 0)
1858
+ resolveRobotRockConfig(context2.app ? { app: context2.app } : void 0)
1369
1859
  );
1370
- return client.sendUpdate(payload);
1860
+ return client.tasks.sendUpdate(payload);
1371
1861
  }
1372
- return context.client.sendUpdate(payload);
1862
+ return context2.client.tasks.sendUpdate(payload);
1373
1863
  }
1374
- async function approveByHumanForAi(context, payload) {
1375
- if (context.mode === "trigger") {
1864
+ async function approveByHumanForAi(context2, payload) {
1865
+ if (context2.mode === "trigger") {
1376
1866
  const { approveByHumanTask: approveByHumanTask2 } = await Promise.resolve().then(() => (init_trigger(), trigger_exports));
1377
1867
  const waitResult = await approveByHumanTask2.triggerAndWait({
1378
1868
  ...payload,
1379
- ...context.app ? { app: context.app } : {}
1869
+ ...context2.app ? { app: context2.app } : {}
1380
1870
  });
1381
1871
  if (!waitResult.ok) {
1382
1872
  throw waitResult.error;
1383
1873
  }
1384
1874
  return waitResult.output;
1385
1875
  }
1386
- if (context.mode === "workflow") {
1876
+ if (context2.mode === "workflow") {
1387
1877
  const { approveByHumanInWorkflow: approveByHumanInWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1388
1878
  return await approveByHumanInWorkflow2({
1389
1879
  ...payload,
1390
- ...context.app ? { app: context.app } : {}
1880
+ ...context2.app ? { app: context2.app } : {}
1391
1881
  });
1392
1882
  }
1393
- const result = await context.client.sendToHuman({
1883
+ const result = await context2.client.sendToHuman({
1394
1884
  ...payload,
1395
1885
  actions: APPROVE_BY_HUMAN_ACTIONS3
1396
1886
  });
@@ -1428,11 +1918,11 @@ function toHumanToolResult(result) {
1428
1918
  }
1429
1919
 
1430
1920
  // src/ai/approve-by-human-tool-core.ts
1431
- var approveByHumanInputSchema = z3.object({
1432
- type: z3.string().optional().describe("Task type slug; defaults to ai-approval"),
1433
- name: z3.string().describe("Short title for the approval request"),
1434
- description: z3.string().describe("What needs approval and the consequences of approving or declining"),
1435
- contextSummary: z3.string().optional().describe("Optional markdown summary shown to the reviewer")
1921
+ var approveByHumanInputSchema = z4.object({
1922
+ type: z4.string().optional().describe("Task type slug; defaults to ai-approval"),
1923
+ name: z4.string().describe("Short title for the approval request"),
1924
+ description: z4.string().describe("What needs approval and the consequences of approving or declining"),
1925
+ contextSummary: z4.string().optional().describe("Optional markdown summary shown to the reviewer")
1436
1926
  });
1437
1927
  function resolveApproveByHumanToolConfig(clientOrContext, maybeOptions = {}) {
1438
1928
  const isDurable = typeof clientOrContext === "object" && clientOrContext !== null && "mode" in clientOrContext && (clientOrContext.mode === "trigger" || clientOrContext.mode === "workflow");
@@ -1474,16 +1964,16 @@ function buildApproveByHumanToolDefinition(clientOrContext, maybeOptions = {}) {
1474
1964
 
1475
1965
  // src/ai/create-send-to-human-tool-core.ts
1476
1966
  init_schemas2();
1477
- import { z as z4 } from "zod";
1478
- var sendToHumanToolInputSchema = z4.object({
1479
- type: z4.string().describe("Task type slug shown in the RobotRock inbox"),
1480
- name: z4.string().describe("Short title for the human reviewer"),
1481
- description: z4.string().optional().describe("What you need from the human and why you cannot proceed alone"),
1482
- context: z4.object({
1483
- data: z4.record(z4.string(), z4.unknown()).optional(),
1484
- ui: z4.record(z4.string(), z4.unknown()).optional()
1967
+ import { z as z5 } from "zod";
1968
+ var sendToHumanToolInputSchema = z5.object({
1969
+ type: z5.string().describe("Task type slug shown in the RobotRock inbox"),
1970
+ name: z5.string().describe("Short title for the human reviewer"),
1971
+ description: z5.string().optional().describe("What you need from the human and why you cannot proceed alone"),
1972
+ context: z5.object({
1973
+ data: z5.record(z5.string(), z5.unknown()).optional(),
1974
+ ui: z5.record(z5.string(), z5.unknown()).optional()
1485
1975
  }).optional().describe("Optional structured context for the inbox UI"),
1486
- validUntil: z4.string().datetime().optional().describe("Optional ISO deadline for the task"),
1976
+ validUntil: z5.string().datetime().optional().describe("Optional ISO deadline for the task"),
1487
1977
  assignTo: assignToSchema2.optional().describe(
1488
1978
  "Assign to tenant member emails and/or group slugs; narrows who sees the task in the inbox"
1489
1979
  )
@@ -1529,12 +2019,12 @@ function buildSendToHumanToolDefinition(clientOrOptions, maybeOptions) {
1529
2019
  // src/ai/create-send-update-tool-core.ts
1530
2020
  init_schemas2();
1531
2021
  init_client();
1532
- import { z as z5 } from "zod";
1533
- var sendUpdateToolInputSchema = z5.object({
1534
- threadId: z5.string().optional().describe(
2022
+ import { z as z6 } from "zod";
2023
+ var sendUpdateToolInputSchema = z6.object({
2024
+ threadId: z6.string().optional().describe(
1535
2025
  "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."
1536
2026
  ),
1537
- message: z5.string().describe("Short progress update (1-2 sentences) shown in the inbox status bar"),
2027
+ message: z6.string().describe("Short progress update (1-2 sentences) shown in the inbox status bar"),
1538
2028
  status: threadUpdateStatusSchema2.optional().describe(
1539
2029
  "Lifecycle status driving the status-bar icon/color: info, queued, running, waiting, succeeded, failed, cancelled"
1540
2030
  )
@@ -1585,6 +2075,84 @@ function buildSendUpdateToolDefinition(clientOrOptions, maybeOptions = {}) {
1585
2075
  };
1586
2076
  }
1587
2077
 
2078
+ // src/ai/request-action-input-tool-core.ts
2079
+ import { z as z7 } from "zod";
2080
+ var requestActionInputActionSchema = z7.object({
2081
+ id: z7.string().min(1).optional().describe(
2082
+ "Stable action identifier echoed in tool output (e.g. pick-blog-topic). Strongly recommended \u2014 auto-derived from title when omitted."
2083
+ ),
2084
+ title: z7.string().min(1),
2085
+ description: z7.string().optional(),
2086
+ schema: z7.record(z7.string(), z7.unknown()).optional().describe("JSON Schema object for the human feedback form"),
2087
+ ui: z7.record(z7.string(), z7.unknown()).optional().describe(
2088
+ 'RJSF ui schema overrides (ui:widget, ui:enumNames, etc.). Use ui:widget "radio" for 2\u20136 discrete choices rendered as tappable cards.'
2089
+ ),
2090
+ data: z7.record(z7.string(), z7.unknown()).optional().describe("Optional default form field values")
2091
+ });
2092
+ var requestActionInputToolOutputSchema = z7.object({
2093
+ actionId: z7.string().min(1),
2094
+ data: z7.record(z7.string(), z7.unknown())
2095
+ });
2096
+ var requestActionInputToolInputSchema = z7.object({
2097
+ prompt: z7.string().optional().describe("Optional heading shown above the action widget in chat"),
2098
+ action: requestActionInputActionSchema.describe(
2099
+ "Action widget config: JSON Schema form fields and optional RJSF ui overrides (same shape as RobotRock inbox actions)"
2100
+ )
2101
+ });
2102
+ function buildRequestActionInputToolDefinition(options = {}) {
2103
+ const description = options.description ?? `Ask the user for structured input via a RobotRock action widget in chat. Always set action.id (e.g. "pick-blog-topic") and action.title. Provide action.schema and optional action.ui using the same JSON Schema and RJSF ui shape as inbox action widgets. Put every field you need in a single call \u2014 never invoke this tool more than once per turn. For 2\u20136 discrete options, use a string enum with ui:widget "radio" and ui:enumNames \u2014 never markdown bullet lists. After the tool returns, act on the user's data immediately; do not ask them to confirm choices they already submitted.`;
2104
+ return {
2105
+ description,
2106
+ inputSchema: requestActionInputToolInputSchema,
2107
+ outputSchema: requestActionInputToolOutputSchema
2108
+ };
2109
+ }
2110
+
2111
+ // src/ai/report-status-tool-core.ts
2112
+ import { z as z8 } from "zod";
2113
+ var reportStatusPhaseSchema = z8.enum([
2114
+ "info",
2115
+ "running",
2116
+ "waiting",
2117
+ "succeeded",
2118
+ "failed"
2119
+ ]);
2120
+ var reportStatusToolInputSchema = z8.object({
2121
+ message: z8.string().min(1).describe(
2122
+ "Short progress update shown in chat (1-2 sentences). Use while researching, drafting, or waiting on external work."
2123
+ ),
2124
+ phase: reportStatusPhaseSchema.optional().describe(
2125
+ "Lifecycle phase for the status marker. Defaults to running. Use succeeded or failed when a step finishes."
2126
+ )
2127
+ });
2128
+ var reportStatusToolOutputSchema = z8.object({
2129
+ message: z8.string().min(1),
2130
+ phase: reportStatusPhaseSchema
2131
+ });
2132
+ function normalizeReportStatusToolInput(input) {
2133
+ const parsed = reportStatusToolInputSchema.parse(input);
2134
+ return {
2135
+ message: parsed.message.trim(),
2136
+ phase: parsed.phase
2137
+ };
2138
+ }
2139
+ async function executeReportStatusTool(input) {
2140
+ const normalized = normalizeReportStatusToolInput(input);
2141
+ return {
2142
+ message: normalized.message,
2143
+ phase: normalized.phase ?? "running"
2144
+ };
2145
+ }
2146
+ function buildReportStatusToolDefinition(options = {}) {
2147
+ const description = options.description ?? 'Post a short progress update to the chat UI while you work. Call this before and during long steps (research, drafting, tool runs) so the user sees what is happening. Use phase "running" while in progress, "succeeded" or "failed" when a step completes, and "waiting" when blocked on external input.';
2148
+ return {
2149
+ description,
2150
+ inputSchema: reportStatusToolInputSchema,
2151
+ outputSchema: reportStatusToolOutputSchema,
2152
+ execute: executeReportStatusTool
2153
+ };
2154
+ }
2155
+
1588
2156
  // src/ai/workflow-tools.ts
1589
2157
  function approveByHumanTool(clientOrContext, maybeOptions = {}) {
1590
2158
  return buildApproveByHumanToolDefinition(clientOrContext, maybeOptions);
@@ -1595,21 +2163,29 @@ function createSendToHumanTool(clientOrOptions, maybeOptions) {
1595
2163
  function createSendUpdateTool(clientOrOptions, maybeOptions = {}) {
1596
2164
  return buildSendUpdateToolDefinition(clientOrOptions, maybeOptions);
1597
2165
  }
2166
+ function requestActionInputTool(options = {}) {
2167
+ return buildRequestActionInputToolDefinition(options);
2168
+ }
2169
+ function reportStatusTool(options = {}) {
2170
+ return buildReportStatusToolDefinition(options);
2171
+ }
1598
2172
  function createRobotRockAiTools(options = {}) {
1599
- const context = { mode: "workflow", app: options.app };
2173
+ const context2 = { mode: "workflow", app: options.app };
1600
2174
  return {
1601
- context,
1602
- approveByHuman: (toolOptions) => buildApproveByHumanToolDefinition({ ...context, ...toolOptions }),
2175
+ context: context2,
2176
+ approveByHuman: (toolOptions) => buildApproveByHumanToolDefinition({ ...context2, ...toolOptions }),
1603
2177
  sendToHuman: (toolOptions) => buildSendToHumanToolDefinition({
1604
- ...context,
2178
+ ...context2,
1605
2179
  ...options.threadId ? { threadId: options.threadId } : {},
1606
2180
  ...toolOptions
1607
2181
  }),
1608
2182
  sendUpdate: (toolOptions = {}) => buildSendUpdateToolDefinition({
1609
- ...context,
2183
+ ...context2,
1610
2184
  ...options.threadId ? { threadId: options.threadId } : {},
1611
2185
  ...toolOptions
1612
- })
2186
+ }),
2187
+ requestActionInput: (toolOptions = {}) => buildRequestActionInputToolDefinition(toolOptions),
2188
+ reportStatus: (toolOptions = {}) => buildReportStatusToolDefinition(toolOptions)
1613
2189
  };
1614
2190
  }
1615
2191
 
@@ -1617,12 +2193,6 @@ function createRobotRockAiTools(options = {}) {
1617
2193
  function defaultFormatToolApprovalTask(toolCall, options = {}) {
1618
2194
  const approveId = options.approveActionId ?? "approve";
1619
2195
  const denyId = options.denyActionId ?? "deny";
1620
- let inputPreview;
1621
- try {
1622
- inputPreview = JSON.stringify(toolCall.input, null, 2);
1623
- } catch {
1624
- inputPreview = String(toolCall.input);
1625
- }
1626
2196
  return {
1627
2197
  type: options.type ?? "ai-tool-approval",
1628
2198
  name: `Approve: ${toolCall.toolName}`,
@@ -1820,7 +2390,7 @@ function resolveToolCallForRequest(request, source, messages) {
1820
2390
  );
1821
2391
  }
1822
2392
  async function resolveToolApprovalsViaRobotRock(clientOrContext, source, options = {}) {
1823
- const context = normalizeRobotRockAiContext(clientOrContext);
2393
+ const context2 = normalizeRobotRockAiContext(clientOrContext);
1824
2394
  const approveId = options.approveActionId ?? "approve";
1825
2395
  const denyId = options.denyActionId ?? "deny";
1826
2396
  const formatTask = options.formatTask ?? defaultFormatToolApprovalTask;
@@ -1833,7 +2403,7 @@ async function resolveToolApprovalsViaRobotRock(clientOrContext, source, options
1833
2403
  approveActionId: approveId,
1834
2404
  denyActionId: denyId
1835
2405
  });
1836
- const result = await sendToHumanForAi(context, taskInput);
2406
+ const result = await sendToHumanForAi(context2, taskInput);
1837
2407
  const approved = result.actionId === approveId;
1838
2408
  const reason = typeof result.data === "object" && result.data !== null && "reason" in result.data && typeof result.data.reason === "string" ? result.data.reason : approved ? "Approved in RobotRock inbox" : "Denied in RobotRock inbox";
1839
2409
  responses.push({
@@ -1879,6 +2449,8 @@ export {
1879
2449
  createRobotRockToolApproval,
1880
2450
  createSendToHumanTool,
1881
2451
  createSendUpdateTool,
2452
+ reportStatusTool,
2453
+ requestActionInputTool,
1882
2454
  resolveToolApprovalsViaRobotRock,
1883
2455
  runWithRobotRockApprovals
1884
2456
  };