robotrock 0.9.0 → 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.
@@ -301,7 +301,7 @@ function refineContextPublicUrls(data, ctx) {
301
301
  });
302
302
  }
303
303
  }
304
- var safeUrlSchema, jsonSchema7Schema, uiSchemaSchema, webhookHandlerSchema, triggerHandlerSchema, handlerSchema, taskActionSchema, uiFieldSchemaSchema, contextUiSchema, contextDataSchema, TASK_CONTEXT_FORMAT_VERSION, taskContextObjectBaseSchema, taskContextObjectSchema, taskContextSchema, assignToSchema, threadUpdateMessageSchema, threadUpdateStatuses, threadUpdateStatusSchema, threadUpdateInputSchema, taskPriorities, taskPrioritySchema, 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;
305
305
  var init_task = __esm({
306
306
  "../core/src/schemas/task.ts"() {
307
307
  "use strict";
@@ -327,13 +327,15 @@ var init_task = __esm({
327
327
  tokenId: z.string().min(1)
328
328
  });
329
329
  handlerSchema = z.discriminatedUnion("type", [webhookHandlerSchema, triggerHandlerSchema]);
330
- taskActionSchema = z.object({
330
+ taskActionInputSchema = z.object({
331
331
  id: z.string().min(1),
332
332
  title: z.string().min(1),
333
333
  description: z.string().optional(),
334
334
  schema: jsonSchema7Schema.optional(),
335
335
  ui: uiSchemaSchema.optional(),
336
- data: z.record(z.string(), z.unknown()).optional(),
336
+ data: z.record(z.string(), z.unknown()).optional()
337
+ });
338
+ taskActionSchema = taskActionInputSchema.extend({
337
339
  // Optional handlers for this action - if present, must have at least 1
338
340
  handlers: z.array(handlerSchema).min(1).optional()
339
341
  });
@@ -424,6 +426,56 @@ var init_task = __esm({
424
426
  /** Agent release version — not shown in inbox UI. */
425
427
  agent: agentTelemetrySchema.optional()
426
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
+ });
427
479
  }
428
480
  });
429
481
 
@@ -463,7 +515,7 @@ function refineContextPublicUrls2(data, ctx) {
463
515
  });
464
516
  }
465
517
  }
466
- var safeUrlSchema2, jsonSchema7Schema2, uiSchemaSchema2, webhookHandlerSchema2, triggerHandlerSchema2, handlerSchema2, taskActionSchema2, uiFieldSchemaSchema2, contextUiSchema2, contextDataSchema2, TASK_CONTEXT_FORMAT_VERSION2, taskContextObjectBaseSchema2, taskContextObjectSchema2, taskContextSchema2, assignToSchema2, threadUpdateMessageSchema2, threadUpdateStatuses2, threadUpdateStatusSchema2, threadUpdateInputSchema2, taskPriorities2, taskPrioritySchema2, 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;
467
519
  var init_schemas2 = __esm({
468
520
  "src/schemas/index.ts"() {
469
521
  "use strict";
@@ -489,13 +541,15 @@ var init_schemas2 = __esm({
489
541
  tokenId: z2.string().min(1)
490
542
  });
491
543
  handlerSchema2 = z2.discriminatedUnion("type", [webhookHandlerSchema2, triggerHandlerSchema2]);
492
- taskActionSchema2 = z2.object({
544
+ taskActionInputSchema2 = z2.object({
493
545
  id: z2.string().min(1),
494
546
  title: z2.string().min(1),
495
547
  description: z2.string().optional(),
496
548
  schema: jsonSchema7Schema2.optional(),
497
549
  ui: uiSchemaSchema2.optional(),
498
- data: z2.record(z2.string(), z2.unknown()).optional(),
550
+ data: z2.record(z2.string(), z2.unknown()).optional()
551
+ });
552
+ taskActionSchema2 = taskActionInputSchema2.extend({
499
553
  handlers: z2.array(handlerSchema2).min(1).optional()
500
554
  });
501
555
  uiFieldSchemaSchema2 = z2.object({
@@ -618,6 +672,240 @@ var init_approval_result = __esm({
618
672
  }
619
673
  });
620
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
+
621
909
  // src/client.ts
622
910
  function sleep(ms) {
623
911
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -695,54 +983,17 @@ function normalizeSendToHumanInput(task2, clientDefaults) {
695
983
  actions: normalizedActions
696
984
  };
697
985
  }
698
- async function parseResponseBody(response) {
699
- const contentType = response.headers.get("content-type") ?? "";
700
- const bodyText = await response.text();
701
- if (!bodyText) {
702
- return null;
703
- }
704
- if (contentType.toLowerCase().includes("application/json")) {
705
- try {
706
- return JSON.parse(bodyText);
707
- } catch {
708
- }
709
- }
710
- try {
711
- return JSON.parse(bodyText);
712
- } catch {
713
- return bodyText;
714
- }
715
- }
716
- function getErrorMessage(data, fallback) {
717
- if (data && typeof data === "object" && !Array.isArray(data)) {
718
- const maybeMessage = data.message;
719
- if (typeof maybeMessage === "string" && maybeMessage.trim()) {
720
- return maybeMessage;
721
- }
722
- }
723
- if (typeof data === "string" && data.trim()) {
724
- const compact = data.replace(/\s+/g, " ").trim();
725
- const snippet = compact.length > 180 ? `${compact.slice(0, 180)}...` : compact;
726
- return `${fallback}. Server returned non-JSON response: ${snippet}`;
727
- }
728
- return fallback;
729
- }
730
- var DEFAULT_POLL_INTERVAL_MS, DEFAULT_TIMEOUT_MS, RobotRockError, RobotRock;
986
+ var DEFAULT_POLL_INTERVAL_MS, DEFAULT_TIMEOUT_MS, RobotRock;
731
987
  var init_client = __esm({
732
988
  "src/client.ts"() {
733
989
  "use strict";
734
990
  init_schemas2();
735
991
  init_approval_result();
992
+ init_http();
993
+ init_chats();
994
+ init_http();
736
995
  DEFAULT_POLL_INTERVAL_MS = 2e3;
737
996
  DEFAULT_TIMEOUT_MS = 24 * 60 * 60 * 1e3;
738
- RobotRockError = class extends Error {
739
- constructor(message, statusCode, response) {
740
- super(message);
741
- this.statusCode = statusCode;
742
- this.response = response;
743
- this.name = "RobotRockError";
744
- }
745
- };
746
997
  RobotRock = class {
747
998
  apiKey;
748
999
  baseUrl;
@@ -751,6 +1002,10 @@ var init_client = __esm({
751
1002
  contextVersion;
752
1003
  webhook;
753
1004
  polling;
1005
+ /** Task CRUD: `create`, `get`, `cancel`, `sendUpdate`. */
1006
+ tasks;
1007
+ /** Chat CRUD: `create`, `close`. */
1008
+ chats;
754
1009
  constructor(config) {
755
1010
  if (config.webhook && config.polling) {
756
1011
  throw new Error(
@@ -771,11 +1026,19 @@ var init_client = __esm({
771
1026
  this.contextVersion = config.advanced?.contextVersion ?? TASK_CONTEXT_FORMAT_VERSION2;
772
1027
  this.webhook = config.webhook;
773
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
+ });
774
1040
  }
775
- /**
776
- * Create a task via POST /v1 without waiting for a human response.
777
- */
778
- async createTask(task2) {
1041
+ async createTaskRequest(task2) {
779
1042
  const normalizedTask = normalizeSendToHumanInput(task2, {
780
1043
  webhook: this.webhook,
781
1044
  app: this.app,
@@ -828,7 +1091,7 @@ var init_client = __esm({
828
1091
  contextVersion: this.contextVersion,
829
1092
  agentVersion: this.agentVersion
830
1093
  });
831
- const createdTaskTask = await this.createTask(task2);
1094
+ const createdTaskTask = await this.createTaskRequest(task2);
832
1095
  const hasHandlers = normalizedTask.actions.some(
833
1096
  (action) => Array.isArray(action.handlers) && action.handlers.length > 0
834
1097
  );
@@ -845,7 +1108,7 @@ var init_client = __esm({
845
1108
  const deadline = validUntilMs !== void 0 ? Math.min(pollingDeadline, validUntilMs) : pollingDeadline;
846
1109
  const taskId = createdTaskTask.taskId;
847
1110
  while (Date.now() < deadline) {
848
- const existing = await this.getTask(taskId);
1111
+ const existing = await this.getTaskById(taskId);
849
1112
  if (existing?.status === "handled" && existing.handled) {
850
1113
  return {
851
1114
  mode: "handled",
@@ -867,10 +1130,35 @@ var init_client = __esm({
867
1130
  }
868
1131
  throw new TaskTimeoutError(`No human response within ${timeoutMs}ms`);
869
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
+ }
870
1140
  /**
871
1141
  * Get a task by public task id (returned as `task.taskId` from {@link sendToHuman}).
1142
+ * @deprecated Use `client.tasks.get()` instead.
872
1143
  */
873
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) {
874
1162
  const response = await fetch(`${this.baseUrl}/tasks/${taskId}`, {
875
1163
  method: "GET",
876
1164
  headers: {
@@ -890,11 +1178,11 @@ var init_client = __esm({
890
1178
  }
891
1179
  return data;
892
1180
  }
893
- /**
894
- * Log a status update against a thread. The update shows in the inbox status
895
- * bar and thread update log for every task in the thread.
896
- */
897
- async sendUpdate({ threadId, message, status }) {
1181
+ async sendThreadUpdate({
1182
+ threadId,
1183
+ message,
1184
+ status
1185
+ }) {
898
1186
  if (!threadId) {
899
1187
  throw new RobotRockError("threadId is required to send an update", 400);
900
1188
  }
@@ -927,7 +1215,7 @@ var init_client = __esm({
927
1215
  }
928
1216
  return data.update;
929
1217
  }
930
- async cancelTask(taskId) {
1218
+ async cancelTaskRequest(taskId) {
931
1219
  const response = await fetch(`${this.baseUrl}/tasks/${taskId}/cancel`, {
932
1220
  method: "POST",
933
1221
  headers: {
@@ -1470,7 +1758,7 @@ async function sendRobotRockUpdate(payload) {
1470
1758
  ...baseConfig.version ? { version: baseConfig.version } : {},
1471
1759
  ...baseConfig.advanced ? { advanced: baseConfig.advanced } : {}
1472
1760
  });
1473
- return client.sendUpdate(update);
1761
+ return client.tasks.sendUpdate(update);
1474
1762
  }
1475
1763
  async function sendUpdateInWorkflow(payload) {
1476
1764
  return sendRobotRockUpdate(payload);
@@ -1493,7 +1781,7 @@ var init_workflow = __esm({
1493
1781
  });
1494
1782
 
1495
1783
  // src/ai/approve-by-human-tool-core.ts
1496
- import { z as z3 } from "zod";
1784
+ import { z as z4 } from "zod";
1497
1785
 
1498
1786
  // src/ai/context.ts
1499
1787
  init_client();
@@ -1569,9 +1857,9 @@ async function sendUpdateForAi(context2, payload) {
1569
1857
  const client = createClient(
1570
1858
  resolveRobotRockConfig(context2.app ? { app: context2.app } : void 0)
1571
1859
  );
1572
- return client.sendUpdate(payload);
1860
+ return client.tasks.sendUpdate(payload);
1573
1861
  }
1574
- return context2.client.sendUpdate(payload);
1862
+ return context2.client.tasks.sendUpdate(payload);
1575
1863
  }
1576
1864
  async function approveByHumanForAi(context2, payload) {
1577
1865
  if (context2.mode === "trigger") {
@@ -1630,11 +1918,11 @@ function toHumanToolResult(result) {
1630
1918
  }
1631
1919
 
1632
1920
  // src/ai/approve-by-human-tool-core.ts
1633
- var approveByHumanInputSchema = z3.object({
1634
- type: z3.string().optional().describe("Task type slug; defaults to ai-approval"),
1635
- name: z3.string().describe("Short title for the approval request"),
1636
- description: z3.string().describe("What needs approval and the consequences of approving or declining"),
1637
- 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")
1638
1926
  });
1639
1927
  function resolveApproveByHumanToolConfig(clientOrContext, maybeOptions = {}) {
1640
1928
  const isDurable = typeof clientOrContext === "object" && clientOrContext !== null && "mode" in clientOrContext && (clientOrContext.mode === "trigger" || clientOrContext.mode === "workflow");
@@ -1676,16 +1964,16 @@ function buildApproveByHumanToolDefinition(clientOrContext, maybeOptions = {}) {
1676
1964
 
1677
1965
  // src/ai/create-send-to-human-tool-core.ts
1678
1966
  init_schemas2();
1679
- import { z as z4 } from "zod";
1680
- var sendToHumanToolInputSchema = z4.object({
1681
- type: z4.string().describe("Task type slug shown in the RobotRock inbox"),
1682
- name: z4.string().describe("Short title for the human reviewer"),
1683
- description: z4.string().optional().describe("What you need from the human and why you cannot proceed alone"),
1684
- context: z4.object({
1685
- data: z4.record(z4.string(), z4.unknown()).optional(),
1686
- 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()
1687
1975
  }).optional().describe("Optional structured context for the inbox UI"),
1688
- 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"),
1689
1977
  assignTo: assignToSchema2.optional().describe(
1690
1978
  "Assign to tenant member emails and/or group slugs; narrows who sees the task in the inbox"
1691
1979
  )
@@ -1731,12 +2019,12 @@ function buildSendToHumanToolDefinition(clientOrOptions, maybeOptions) {
1731
2019
  // src/ai/create-send-update-tool-core.ts
1732
2020
  init_schemas2();
1733
2021
  init_client();
1734
- import { z as z5 } from "zod";
1735
- var sendUpdateToolInputSchema = z5.object({
1736
- threadId: z5.string().optional().describe(
2022
+ import { z as z6 } from "zod";
2023
+ var sendUpdateToolInputSchema = z6.object({
2024
+ threadId: z6.string().optional().describe(
1737
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."
1738
2026
  ),
1739
- 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"),
1740
2028
  status: threadUpdateStatusSchema2.optional().describe(
1741
2029
  "Lifecycle status driving the status-bar icon/color: info, queued, running, waiting, succeeded, failed, cancelled"
1742
2030
  )
@@ -1787,6 +2075,84 @@ function buildSendUpdateToolDefinition(clientOrOptions, maybeOptions = {}) {
1787
2075
  };
1788
2076
  }
1789
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
+
1790
2156
  // src/ai/workflow-tools.ts
1791
2157
  function approveByHumanTool(clientOrContext, maybeOptions = {}) {
1792
2158
  return buildApproveByHumanToolDefinition(clientOrContext, maybeOptions);
@@ -1797,6 +2163,12 @@ function createSendToHumanTool(clientOrOptions, maybeOptions) {
1797
2163
  function createSendUpdateTool(clientOrOptions, maybeOptions = {}) {
1798
2164
  return buildSendUpdateToolDefinition(clientOrOptions, maybeOptions);
1799
2165
  }
2166
+ function requestActionInputTool(options = {}) {
2167
+ return buildRequestActionInputToolDefinition(options);
2168
+ }
2169
+ function reportStatusTool(options = {}) {
2170
+ return buildReportStatusToolDefinition(options);
2171
+ }
1800
2172
  function createRobotRockAiTools(options = {}) {
1801
2173
  const context2 = { mode: "workflow", app: options.app };
1802
2174
  return {
@@ -1811,7 +2183,9 @@ function createRobotRockAiTools(options = {}) {
1811
2183
  ...context2,
1812
2184
  ...options.threadId ? { threadId: options.threadId } : {},
1813
2185
  ...toolOptions
1814
- })
2186
+ }),
2187
+ requestActionInput: (toolOptions = {}) => buildRequestActionInputToolDefinition(toolOptions),
2188
+ reportStatus: (toolOptions = {}) => buildReportStatusToolDefinition(toolOptions)
1815
2189
  };
1816
2190
  }
1817
2191
 
@@ -2075,6 +2449,8 @@ export {
2075
2449
  createRobotRockToolApproval,
2076
2450
  createSendToHumanTool,
2077
2451
  createSendUpdateTool,
2452
+ reportStatusTool,
2453
+ requestActionInputTool,
2078
2454
  resolveToolApprovalsViaRobotRock,
2079
2455
  runWithRobotRockApprovals
2080
2456
  };