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.
- package/dist/ai/index.d.ts +18 -7
- package/dist/ai/index.js +976 -281
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/trigger.d.ts +4 -3
- package/dist/ai/trigger.js +934 -281
- package/dist/ai/trigger.js.map +1 -1
- package/dist/ai/workflow.d.ts +15 -4
- package/dist/ai/workflow.js +854 -282
- package/dist/ai/workflow.js.map +1 -1
- package/dist/client-CzVmjXpz.d.ts +219 -0
- package/dist/index.d.ts +17 -9
- package/dist/index.js +495 -273
- package/dist/index.js.map +1 -1
- package/dist/otel-platform-DzHyHkGk.d.ts +108 -0
- package/dist/schemas/index.d.ts +172 -104
- package/dist/schemas/index.js +98 -118
- package/dist/schemas/index.js.map +1 -1
- package/dist/{tool-approval-bridge-BKDY5NAY.d.ts → tool-approval-bridge-DbwUEBHv.d.ts} +93 -2
- package/dist/trigger/index.d.ts +7 -4
- package/dist/trigger/index.js +558 -201
- package/dist/trigger/index.js.map +1 -1
- package/dist/{trigger-CsOLTjsH.d.ts → trigger-BCKBbAV7.d.ts} +64 -3
- package/dist/workflow/index.d.ts +7 -4
- package/dist/workflow/index.js +553 -199
- package/dist/workflow/index.js.map +1 -1
- package/package.json +1 -5
- package/dist/client-D-XEBOWd.d.ts +0 -137
- package/dist/handler-webhook-BqEi6Bk-.d.ts +0 -16
- package/dist/otel/index.d.ts +0 -49
- package/dist/otel/index.js +0 -633
- package/dist/otel/index.js.map +0 -1
package/dist/ai/index.js
CHANGED
|
@@ -259,12 +259,12 @@ function validateUrlValue(value, widget) {
|
|
|
259
259
|
}
|
|
260
260
|
return null;
|
|
261
261
|
}
|
|
262
|
-
function validateContextPublicUrls(
|
|
263
|
-
if (!
|
|
262
|
+
function validateContextPublicUrls(context2) {
|
|
263
|
+
if (!context2?.data) {
|
|
264
264
|
return null;
|
|
265
265
|
}
|
|
266
|
-
for (const [field, value] of Object.entries(
|
|
267
|
-
const widget = widgetType(
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
419
|
-
|
|
420
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
614
|
-
|
|
615
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
...
|
|
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
|
-
|
|
1091
|
+
contextVersion: this.contextVersion,
|
|
1092
|
+
agentVersion: this.agentVersion
|
|
889
1093
|
});
|
|
890
|
-
const createdTaskTask = await this.
|
|
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.
|
|
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
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
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
|
|
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, ...
|
|
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
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
)
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
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, ...
|
|
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
|
|
1228
|
-
|
|
1229
|
-
|
|
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" }
|
|
@@ -1294,7 +1784,7 @@ var init_workflow = __esm({
|
|
|
1294
1784
|
import { tool } from "ai";
|
|
1295
1785
|
|
|
1296
1786
|
// src/ai/approve-by-human-tool-core.ts
|
|
1297
|
-
import { z as
|
|
1787
|
+
import { z as z4 } from "zod";
|
|
1298
1788
|
|
|
1299
1789
|
// src/ai/context.ts
|
|
1300
1790
|
init_client();
|
|
@@ -1327,27 +1817,27 @@ function normalizeRobotRockAiContext(clientOrContext) {
|
|
|
1327
1817
|
}
|
|
1328
1818
|
throw new Error(`Unknown RobotRock AI mode: ${String(clientOrContext.mode)}`);
|
|
1329
1819
|
}
|
|
1330
|
-
async function sendToHumanForAi(
|
|
1331
|
-
if (
|
|
1820
|
+
async function sendToHumanForAi(context2, payload) {
|
|
1821
|
+
if (context2.mode === "trigger") {
|
|
1332
1822
|
const { sendToHumanTask: sendToHumanTask2 } = await Promise.resolve().then(() => (init_trigger(), trigger_exports));
|
|
1333
1823
|
const waitResult = await sendToHumanTask2.triggerAndWait({
|
|
1334
1824
|
...payload,
|
|
1335
|
-
...
|
|
1825
|
+
...context2.app ? { app: context2.app } : {}
|
|
1336
1826
|
});
|
|
1337
1827
|
if (!waitResult.ok) {
|
|
1338
1828
|
throw waitResult.error;
|
|
1339
1829
|
}
|
|
1340
1830
|
return waitResult.output;
|
|
1341
1831
|
}
|
|
1342
|
-
if (
|
|
1832
|
+
if (context2.mode === "workflow") {
|
|
1343
1833
|
const { sendToHumanInWorkflow: sendToHumanInWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1344
1834
|
const result2 = await sendToHumanInWorkflow2({
|
|
1345
1835
|
...payload,
|
|
1346
|
-
...
|
|
1836
|
+
...context2.app ? { app: context2.app } : {}
|
|
1347
1837
|
});
|
|
1348
1838
|
return result2;
|
|
1349
1839
|
}
|
|
1350
|
-
const result = await
|
|
1840
|
+
const result = await context2.client.sendToHuman(payload);
|
|
1351
1841
|
if (result.mode !== "handled") {
|
|
1352
1842
|
throw new Error(
|
|
1353
1843
|
"RobotRock task was created but not handled. Configure client polling or webhook, or use mode: 'trigger' / 'workflow' for durable waits."
|
|
@@ -1361,42 +1851,52 @@ async function sendToHumanForAi(context, payload) {
|
|
|
1361
1851
|
taskId: result.taskId
|
|
1362
1852
|
};
|
|
1363
1853
|
}
|
|
1364
|
-
async function sendUpdateForAi(
|
|
1365
|
-
if (
|
|
1854
|
+
async function sendUpdateForAi(context2, payload) {
|
|
1855
|
+
if (context2.mode === "workflow") {
|
|
1366
1856
|
const { sendUpdateInWorkflow: sendUpdateInWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1367
1857
|
return sendUpdateInWorkflow2({
|
|
1368
1858
|
...payload,
|
|
1369
|
-
...
|
|
1859
|
+
...context2.app ? { app: context2.app } : {}
|
|
1370
1860
|
});
|
|
1371
1861
|
}
|
|
1372
|
-
if (
|
|
1862
|
+
if (context2.mode === "trigger") {
|
|
1863
|
+
const client = createClient(
|
|
1864
|
+
resolveRobotRockConfig(context2.app ? { app: context2.app } : void 0)
|
|
1865
|
+
);
|
|
1866
|
+
return client.tasks.sendUpdate(payload);
|
|
1867
|
+
}
|
|
1868
|
+
return context2.client.tasks.sendUpdate(payload);
|
|
1869
|
+
}
|
|
1870
|
+
async function closeChatForAi(context2, payload) {
|
|
1871
|
+
if (context2.mode === "trigger" || context2.mode === "workflow") {
|
|
1373
1872
|
const client = createClient(
|
|
1374
|
-
resolveRobotRockConfig(
|
|
1873
|
+
resolveRobotRockConfig(context2.app ? { app: context2.app } : void 0)
|
|
1375
1874
|
);
|
|
1376
|
-
|
|
1875
|
+
await client.chats.close(payload.chatId, { reason: payload.reason });
|
|
1876
|
+
return;
|
|
1377
1877
|
}
|
|
1378
|
-
|
|
1878
|
+
await context2.client.chats.close(payload.chatId, { reason: payload.reason });
|
|
1379
1879
|
}
|
|
1380
|
-
async function approveByHumanForAi(
|
|
1381
|
-
if (
|
|
1880
|
+
async function approveByHumanForAi(context2, payload) {
|
|
1881
|
+
if (context2.mode === "trigger") {
|
|
1382
1882
|
const { approveByHumanTask: approveByHumanTask2 } = await Promise.resolve().then(() => (init_trigger(), trigger_exports));
|
|
1383
1883
|
const waitResult = await approveByHumanTask2.triggerAndWait({
|
|
1384
1884
|
...payload,
|
|
1385
|
-
...
|
|
1885
|
+
...context2.app ? { app: context2.app } : {}
|
|
1386
1886
|
});
|
|
1387
1887
|
if (!waitResult.ok) {
|
|
1388
1888
|
throw waitResult.error;
|
|
1389
1889
|
}
|
|
1390
1890
|
return waitResult.output;
|
|
1391
1891
|
}
|
|
1392
|
-
if (
|
|
1892
|
+
if (context2.mode === "workflow") {
|
|
1393
1893
|
const { approveByHumanInWorkflow: approveByHumanInWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1394
1894
|
return await approveByHumanInWorkflow2({
|
|
1395
1895
|
...payload,
|
|
1396
|
-
...
|
|
1896
|
+
...context2.app ? { app: context2.app } : {}
|
|
1397
1897
|
});
|
|
1398
1898
|
}
|
|
1399
|
-
const result = await
|
|
1899
|
+
const result = await context2.client.sendToHuman({
|
|
1400
1900
|
...payload,
|
|
1401
1901
|
actions: APPROVE_BY_HUMAN_ACTIONS3
|
|
1402
1902
|
});
|
|
@@ -1438,11 +1938,11 @@ var APPROVE_BY_HUMAN_ACTIONS4 = [
|
|
|
1438
1938
|
{ id: "approve", title: "Approve" },
|
|
1439
1939
|
{ id: "decline", title: "Decline" }
|
|
1440
1940
|
];
|
|
1441
|
-
var approveByHumanInputSchema =
|
|
1442
|
-
type:
|
|
1443
|
-
name:
|
|
1444
|
-
description:
|
|
1445
|
-
contextSummary:
|
|
1941
|
+
var approveByHumanInputSchema = z4.object({
|
|
1942
|
+
type: z4.string().optional().describe("Task type slug; defaults to ai-approval"),
|
|
1943
|
+
name: z4.string().describe("Short title for the approval request"),
|
|
1944
|
+
description: z4.string().describe("What needs approval and the consequences of approving or declining"),
|
|
1945
|
+
contextSummary: z4.string().optional().describe("Optional markdown summary shown to the reviewer")
|
|
1446
1946
|
});
|
|
1447
1947
|
function resolveApproveByHumanToolConfig(clientOrContext, maybeOptions = {}) {
|
|
1448
1948
|
const isDurable = typeof clientOrContext === "object" && clientOrContext !== null && "mode" in clientOrContext && (clientOrContext.mode === "trigger" || clientOrContext.mode === "workflow");
|
|
@@ -1492,16 +1992,16 @@ import { tool as tool2 } from "ai";
|
|
|
1492
1992
|
|
|
1493
1993
|
// src/ai/create-send-to-human-tool-core.ts
|
|
1494
1994
|
init_schemas2();
|
|
1495
|
-
import { z as
|
|
1496
|
-
var sendToHumanToolInputSchema =
|
|
1497
|
-
type:
|
|
1498
|
-
name:
|
|
1499
|
-
description:
|
|
1500
|
-
context:
|
|
1501
|
-
data:
|
|
1502
|
-
ui:
|
|
1995
|
+
import { z as z5 } from "zod";
|
|
1996
|
+
var sendToHumanToolInputSchema = z5.object({
|
|
1997
|
+
type: z5.string().describe("Task type slug shown in the RobotRock inbox"),
|
|
1998
|
+
name: z5.string().describe("Short title for the human reviewer"),
|
|
1999
|
+
description: z5.string().optional().describe("What you need from the human and why you cannot proceed alone"),
|
|
2000
|
+
context: z5.object({
|
|
2001
|
+
data: z5.record(z5.string(), z5.unknown()).optional(),
|
|
2002
|
+
ui: z5.record(z5.string(), z5.unknown()).optional()
|
|
1503
2003
|
}).optional().describe("Optional structured context for the inbox UI"),
|
|
1504
|
-
validUntil:
|
|
2004
|
+
validUntil: z5.string().datetime().optional().describe("Optional ISO deadline for the task"),
|
|
1505
2005
|
assignTo: assignToSchema2.optional().describe(
|
|
1506
2006
|
"Assign to tenant member emails and/or group slugs; narrows who sees the task in the inbox"
|
|
1507
2007
|
)
|
|
@@ -1555,12 +2055,12 @@ import { tool as tool3 } from "ai";
|
|
|
1555
2055
|
// src/ai/create-send-update-tool-core.ts
|
|
1556
2056
|
init_schemas2();
|
|
1557
2057
|
init_client();
|
|
1558
|
-
import { z as
|
|
1559
|
-
var sendUpdateToolInputSchema =
|
|
1560
|
-
threadId:
|
|
2058
|
+
import { z as z6 } from "zod";
|
|
2059
|
+
var sendUpdateToolInputSchema = z6.object({
|
|
2060
|
+
threadId: z6.string().optional().describe(
|
|
1561
2061
|
"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."
|
|
1562
2062
|
),
|
|
1563
|
-
message:
|
|
2063
|
+
message: z6.string().describe("Short progress update (1-2 sentences) shown in the inbox status bar"),
|
|
1564
2064
|
status: threadUpdateStatusSchema2.optional().describe(
|
|
1565
2065
|
"Lifecycle status driving the status-bar icon/color: info, queued, running, waiting, succeeded, failed, cancelled"
|
|
1566
2066
|
)
|
|
@@ -1616,17 +2116,185 @@ function createSendUpdateTool(clientOrOptions, maybeOptions = {}) {
|
|
|
1616
2116
|
return tool3(buildSendUpdateToolDefinition(clientOrOptions, maybeOptions));
|
|
1617
2117
|
}
|
|
1618
2118
|
|
|
2119
|
+
// src/ai/request-action-input-tool.ts
|
|
2120
|
+
import { tool as tool4 } from "ai";
|
|
2121
|
+
|
|
2122
|
+
// src/ai/request-action-input-tool-core.ts
|
|
2123
|
+
import { z as z7 } from "zod";
|
|
2124
|
+
var REQUEST_ACTION_INPUT_TOOL_NAME = "requestActionInput";
|
|
2125
|
+
function defaultRequestActionInputActionId(title) {
|
|
2126
|
+
const slug = title.trim().toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
2127
|
+
return slug.length > 0 ? slug : "submit";
|
|
2128
|
+
}
|
|
2129
|
+
var requestActionInputActionSchema = z7.object({
|
|
2130
|
+
id: z7.string().min(1).optional().describe(
|
|
2131
|
+
"Stable action identifier echoed in tool output (e.g. pick-blog-topic). Strongly recommended \u2014 auto-derived from title when omitted."
|
|
2132
|
+
),
|
|
2133
|
+
title: z7.string().min(1),
|
|
2134
|
+
description: z7.string().optional(),
|
|
2135
|
+
schema: z7.record(z7.string(), z7.unknown()).optional().describe("JSON Schema object for the human feedback form"),
|
|
2136
|
+
ui: z7.record(z7.string(), z7.unknown()).optional().describe(
|
|
2137
|
+
'RJSF ui schema overrides (ui:widget, ui:enumNames, etc.). Use ui:widget "radio" for 2\u20136 discrete choices rendered as tappable cards.'
|
|
2138
|
+
),
|
|
2139
|
+
data: z7.record(z7.string(), z7.unknown()).optional().describe("Optional default form field values")
|
|
2140
|
+
});
|
|
2141
|
+
function normalizeRequestActionInputToolInput(input) {
|
|
2142
|
+
const parsed = requestActionInputToolInputSchema.parse(input);
|
|
2143
|
+
return {
|
|
2144
|
+
...parsed,
|
|
2145
|
+
action: {
|
|
2146
|
+
...parsed.action,
|
|
2147
|
+
id: parsed.action.id?.trim() || defaultRequestActionInputActionId(parsed.action.title)
|
|
2148
|
+
}
|
|
2149
|
+
};
|
|
2150
|
+
}
|
|
2151
|
+
var requestActionInputToolOutputSchema = z7.object({
|
|
2152
|
+
actionId: z7.string().min(1),
|
|
2153
|
+
data: z7.record(z7.string(), z7.unknown())
|
|
2154
|
+
});
|
|
2155
|
+
var requestActionInputToolInputSchema = z7.object({
|
|
2156
|
+
prompt: z7.string().optional().describe("Optional heading shown above the action widget in chat"),
|
|
2157
|
+
action: requestActionInputActionSchema.describe(
|
|
2158
|
+
"Action widget config: JSON Schema form fields and optional RJSF ui overrides (same shape as RobotRock inbox actions)"
|
|
2159
|
+
)
|
|
2160
|
+
});
|
|
2161
|
+
function buildRequestActionInputToolDefinition(options = {}) {
|
|
2162
|
+
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.`;
|
|
2163
|
+
return {
|
|
2164
|
+
description,
|
|
2165
|
+
inputSchema: requestActionInputToolInputSchema,
|
|
2166
|
+
outputSchema: requestActionInputToolOutputSchema
|
|
2167
|
+
};
|
|
2168
|
+
}
|
|
2169
|
+
function isRequestActionInputToolPart(part, toolName = REQUEST_ACTION_INPUT_TOOL_NAME) {
|
|
2170
|
+
return part.type === `tool-${toolName}`;
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
// src/ai/request-action-input-tool.ts
|
|
2174
|
+
function requestActionInputTool(options = {}) {
|
|
2175
|
+
const definition = buildRequestActionInputToolDefinition(options);
|
|
2176
|
+
return tool4(definition);
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
// src/ai/report-status-tool.ts
|
|
2180
|
+
import { tool as tool5 } from "ai";
|
|
2181
|
+
|
|
2182
|
+
// src/ai/report-status-tool-core.ts
|
|
2183
|
+
import { z as z8 } from "zod";
|
|
2184
|
+
var REPORT_STATUS_TOOL_NAME = "reportStatus";
|
|
2185
|
+
var reportStatusPhaseSchema = z8.enum([
|
|
2186
|
+
"info",
|
|
2187
|
+
"running",
|
|
2188
|
+
"waiting",
|
|
2189
|
+
"succeeded",
|
|
2190
|
+
"failed"
|
|
2191
|
+
]);
|
|
2192
|
+
var reportStatusToolInputSchema = z8.object({
|
|
2193
|
+
message: z8.string().min(1).describe(
|
|
2194
|
+
"Short progress update shown in chat (1-2 sentences). Use while researching, drafting, or waiting on external work."
|
|
2195
|
+
),
|
|
2196
|
+
phase: reportStatusPhaseSchema.optional().describe(
|
|
2197
|
+
"Lifecycle phase for the status marker. Defaults to running. Use succeeded or failed when a step finishes."
|
|
2198
|
+
)
|
|
2199
|
+
});
|
|
2200
|
+
var reportStatusToolOutputSchema = z8.object({
|
|
2201
|
+
message: z8.string().min(1),
|
|
2202
|
+
phase: reportStatusPhaseSchema
|
|
2203
|
+
});
|
|
2204
|
+
function normalizeReportStatusToolInput(input) {
|
|
2205
|
+
const parsed = reportStatusToolInputSchema.parse(input);
|
|
2206
|
+
return {
|
|
2207
|
+
message: parsed.message.trim(),
|
|
2208
|
+
phase: parsed.phase
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
async function executeReportStatusTool(input) {
|
|
2212
|
+
const normalized = normalizeReportStatusToolInput(input);
|
|
2213
|
+
return {
|
|
2214
|
+
message: normalized.message,
|
|
2215
|
+
phase: normalized.phase ?? "running"
|
|
2216
|
+
};
|
|
2217
|
+
}
|
|
2218
|
+
function buildReportStatusToolDefinition(options = {}) {
|
|
2219
|
+
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.';
|
|
2220
|
+
return {
|
|
2221
|
+
description,
|
|
2222
|
+
inputSchema: reportStatusToolInputSchema,
|
|
2223
|
+
outputSchema: reportStatusToolOutputSchema,
|
|
2224
|
+
execute: executeReportStatusTool
|
|
2225
|
+
};
|
|
2226
|
+
}
|
|
2227
|
+
function isReportStatusToolPart(part, toolName = REPORT_STATUS_TOOL_NAME) {
|
|
2228
|
+
return part.type === `tool-${toolName}`;
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
// src/ai/report-status-tool.ts
|
|
2232
|
+
function reportStatusTool(options = {}) {
|
|
2233
|
+
return tool5(buildReportStatusToolDefinition(options));
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
// src/ai/close-chat-tool.ts
|
|
2237
|
+
import { tool as tool6 } from "ai";
|
|
2238
|
+
|
|
2239
|
+
// src/ai/close-chat-tool-core.ts
|
|
2240
|
+
import { z as z9 } from "zod";
|
|
2241
|
+
var CLOSE_CHAT_TOOL_NAME = "closeChat";
|
|
2242
|
+
var closeChatToolInputSchema = z9.object({
|
|
2243
|
+
reason: z9.string().optional().describe(
|
|
2244
|
+
"Short reason the conversation is being closed (recorded on the audit trail)."
|
|
2245
|
+
)
|
|
2246
|
+
});
|
|
2247
|
+
function resolveCloseChatToolConfig(clientOrOptions, maybeOptions) {
|
|
2248
|
+
const isDurable = typeof clientOrOptions === "object" && clientOrOptions !== null && "mode" in clientOrOptions && (clientOrOptions.mode === "trigger" || clientOrOptions.mode === "workflow");
|
|
2249
|
+
const aiContext = normalizeRobotRockAiContext(
|
|
2250
|
+
isDurable ? {
|
|
2251
|
+
mode: clientOrOptions.mode,
|
|
2252
|
+
app: clientOrOptions.app
|
|
2253
|
+
} : clientOrOptions
|
|
2254
|
+
);
|
|
2255
|
+
const options = isDurable ? clientOrOptions : maybeOptions;
|
|
2256
|
+
if (!options?.chatId) {
|
|
2257
|
+
throw new Error(
|
|
2258
|
+
"closeChatTool: `chatId` is required. Pass the chatId of the chat the agent is running in."
|
|
2259
|
+
);
|
|
2260
|
+
}
|
|
2261
|
+
return { aiContext, options };
|
|
2262
|
+
}
|
|
2263
|
+
function buildCloseChatToolDefinition(clientOrOptions, maybeOptions) {
|
|
2264
|
+
const { aiContext, options } = resolveCloseChatToolConfig(
|
|
2265
|
+
clientOrOptions,
|
|
2266
|
+
maybeOptions
|
|
2267
|
+
);
|
|
2268
|
+
const description = options.description ?? "Close the current chat when the conversation is complete and no further human input is needed. Records the close on the audit trail.";
|
|
2269
|
+
return {
|
|
2270
|
+
description,
|
|
2271
|
+
inputSchema: closeChatToolInputSchema,
|
|
2272
|
+
execute: async (input) => {
|
|
2273
|
+
await closeChatForAi(aiContext, {
|
|
2274
|
+
chatId: options.chatId,
|
|
2275
|
+
reason: input.reason
|
|
2276
|
+
});
|
|
2277
|
+
return { closed: true, chatId: options.chatId };
|
|
2278
|
+
}
|
|
2279
|
+
};
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
// src/ai/close-chat-tool.ts
|
|
2283
|
+
function closeChatTool(clientOrOptions, maybeOptions) {
|
|
2284
|
+
return tool6(buildCloseChatToolDefinition(clientOrOptions, maybeOptions));
|
|
2285
|
+
}
|
|
2286
|
+
|
|
1619
2287
|
// src/ai/create-ai-tools.ts
|
|
1620
2288
|
function createRobotRockAiTools(options) {
|
|
1621
2289
|
const mode = options.mode ?? (options.client ? "polling" : "trigger");
|
|
1622
2290
|
if (mode === "polling" && !options.client) {
|
|
1623
2291
|
throw new Error("createRobotRockAiTools: polling mode requires `client`.");
|
|
1624
2292
|
}
|
|
1625
|
-
const
|
|
1626
|
-
const durableContext =
|
|
1627
|
-
const pollingClient =
|
|
2293
|
+
const context2 = mode === "trigger" ? { mode: "trigger", app: options.app } : mode === "workflow" ? { mode: "workflow", app: options.app } : { mode: "polling", client: options.client };
|
|
2294
|
+
const durableContext = context2.mode === "trigger" || context2.mode === "workflow" ? context2 : null;
|
|
2295
|
+
const pollingClient = context2.mode === "polling" ? context2.client : void 0;
|
|
1628
2296
|
return {
|
|
1629
|
-
context,
|
|
2297
|
+
context: context2,
|
|
1630
2298
|
approveByHuman: (toolOptions) => durableContext ? approveByHumanTool({ ...durableContext, ...toolOptions }) : approveByHumanTool(pollingClient, toolOptions),
|
|
1631
2299
|
sendToHuman: (toolOptions) => durableContext ? createSendToHumanTool({
|
|
1632
2300
|
...durableContext,
|
|
@@ -1643,7 +2311,19 @@ function createRobotRockAiTools(options) {
|
|
|
1643
2311
|
}) : createSendUpdateTool(pollingClient, {
|
|
1644
2312
|
...options.threadId ? { threadId: options.threadId } : {},
|
|
1645
2313
|
...toolOptions
|
|
1646
|
-
})
|
|
2314
|
+
}),
|
|
2315
|
+
requestActionInput: (toolOptions = {}) => requestActionInputTool(toolOptions),
|
|
2316
|
+
reportStatus: (toolOptions = {}) => reportStatusTool(toolOptions),
|
|
2317
|
+
closeChat: (toolOptions) => {
|
|
2318
|
+
const chatId = toolOptions?.chatId ?? options.chatId;
|
|
2319
|
+
if (!chatId) {
|
|
2320
|
+
throw new Error(
|
|
2321
|
+
"createRobotRockAiTools: closeChat requires `chatId`. Pass it on `createRobotRockAiTools({ chatId })` or `closeChat({ chatId })`."
|
|
2322
|
+
);
|
|
2323
|
+
}
|
|
2324
|
+
const resolvedOptions = { ...toolOptions, chatId };
|
|
2325
|
+
return durableContext ? closeChatTool({ ...durableContext, ...resolvedOptions }) : closeChatTool(pollingClient, resolvedOptions);
|
|
2326
|
+
}
|
|
1647
2327
|
};
|
|
1648
2328
|
}
|
|
1649
2329
|
|
|
@@ -1655,12 +2335,6 @@ var DEFAULT_APPROVE_ACTIONS = [
|
|
|
1655
2335
|
function defaultFormatToolApprovalTask(toolCall, options = {}) {
|
|
1656
2336
|
const approveId = options.approveActionId ?? "approve";
|
|
1657
2337
|
const denyId = options.denyActionId ?? "deny";
|
|
1658
|
-
let inputPreview;
|
|
1659
|
-
try {
|
|
1660
|
-
inputPreview = JSON.stringify(toolCall.input, null, 2);
|
|
1661
|
-
} catch {
|
|
1662
|
-
inputPreview = String(toolCall.input);
|
|
1663
|
-
}
|
|
1664
2338
|
return {
|
|
1665
2339
|
type: options.type ?? "ai-tool-approval",
|
|
1666
2340
|
name: `Approve: ${toolCall.toolName}`,
|
|
@@ -1858,7 +2532,7 @@ function resolveToolCallForRequest(request, source, messages) {
|
|
|
1858
2532
|
);
|
|
1859
2533
|
}
|
|
1860
2534
|
async function resolveToolApprovalsViaRobotRock(clientOrContext, source, options = {}) {
|
|
1861
|
-
const
|
|
2535
|
+
const context2 = normalizeRobotRockAiContext(clientOrContext);
|
|
1862
2536
|
const approveId = options.approveActionId ?? "approve";
|
|
1863
2537
|
const denyId = options.denyActionId ?? "deny";
|
|
1864
2538
|
const formatTask = options.formatTask ?? defaultFormatToolApprovalTask;
|
|
@@ -1871,7 +2545,7 @@ async function resolveToolApprovalsViaRobotRock(clientOrContext, source, options
|
|
|
1871
2545
|
approveActionId: approveId,
|
|
1872
2546
|
denyActionId: denyId
|
|
1873
2547
|
});
|
|
1874
|
-
const result = await sendToHumanForAi(
|
|
2548
|
+
const result = await sendToHumanForAi(context2, taskInput);
|
|
1875
2549
|
const approved = result.actionId === approveId;
|
|
1876
2550
|
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";
|
|
1877
2551
|
responses.push({
|
|
@@ -1910,11 +2584,19 @@ async function runWithRobotRockApprovals(options) {
|
|
|
1910
2584
|
}
|
|
1911
2585
|
export {
|
|
1912
2586
|
APPROVE_BY_HUMAN_ACTIONS4 as APPROVE_BY_HUMAN_ACTIONS,
|
|
2587
|
+
CLOSE_CHAT_TOOL_NAME,
|
|
1913
2588
|
DEFAULT_APPROVE_ACTIONS,
|
|
2589
|
+
REPORT_STATUS_TOOL_NAME,
|
|
2590
|
+
REQUEST_ACTION_INPUT_TOOL_NAME,
|
|
1914
2591
|
applyRobotRockToolApprovalToTools,
|
|
1915
2592
|
approveByHumanForAi,
|
|
1916
2593
|
approveByHumanInputSchema,
|
|
1917
2594
|
approveByHumanTool,
|
|
2595
|
+
buildReportStatusToolDefinition,
|
|
2596
|
+
buildRequestActionInputToolDefinition,
|
|
2597
|
+
closeChatForAi,
|
|
2598
|
+
closeChatTool,
|
|
2599
|
+
closeChatToolInputSchema,
|
|
1918
2600
|
collectApprovalRequests,
|
|
1919
2601
|
createRobotRockAiTools,
|
|
1920
2602
|
createRobotRockAiTriggerContext,
|
|
@@ -1924,7 +2606,20 @@ export {
|
|
|
1924
2606
|
createSendToHumanTool,
|
|
1925
2607
|
createSendUpdateTool,
|
|
1926
2608
|
defaultFormatToolApprovalTask,
|
|
2609
|
+
defaultRequestActionInputActionId,
|
|
2610
|
+
executeReportStatusTool,
|
|
2611
|
+
isReportStatusToolPart,
|
|
2612
|
+
isRequestActionInputToolPart,
|
|
2613
|
+
normalizeReportStatusToolInput,
|
|
2614
|
+
normalizeRequestActionInputToolInput,
|
|
1927
2615
|
normalizeRobotRockAiContext,
|
|
2616
|
+
reportStatusPhaseSchema,
|
|
2617
|
+
reportStatusTool,
|
|
2618
|
+
reportStatusToolInputSchema,
|
|
2619
|
+
reportStatusToolOutputSchema,
|
|
2620
|
+
requestActionInputTool,
|
|
2621
|
+
requestActionInputToolInputSchema,
|
|
2622
|
+
requestActionInputToolOutputSchema,
|
|
1928
2623
|
resolveToolApprovalsViaRobotRock,
|
|
1929
2624
|
runWithRobotRockApprovals,
|
|
1930
2625
|
sendToHumanForAi,
|