robotrock 0.3.0 → 0.5.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/README.md +41 -2
- package/dist/ai/index.d.ts +3 -3
- package/dist/ai/{index.js → index.mjs} +10 -3
- package/dist/ai/trigger.d.ts +2 -2
- package/dist/ai/{trigger.js → trigger.mjs} +6 -3
- package/dist/ai/workflow.d.ts +2 -2
- package/dist/ai/{workflow.js → workflow.mjs} +6 -3
- package/dist/{chunk-D2FBSEZK.js → chunk-3ZYQE5LF.mjs} +1 -1
- package/dist/{chunk-DSZ3GMT4.js → chunk-CWQTNK24.mjs} +117 -24
- package/dist/chunk-CWQTNK24.mjs.map +1 -0
- package/dist/{chunk-KOXJCIST.js → chunk-E7ZWBFZ6.mjs} +44 -4
- package/dist/chunk-E7ZWBFZ6.mjs.map +1 -0
- package/dist/chunk-VNXWLPRV.mjs +4203 -0
- package/dist/chunk-VNXWLPRV.mjs.map +1 -0
- package/dist/{client-Dhk9qxhL.d.ts → client-BOm2Ce2f.d.ts} +25 -2
- package/dist/index.d.ts +3 -3
- package/dist/{index.js → index.mjs} +25 -15
- package/dist/{index.js.map → index.mjs.map} +1 -1
- package/dist/schemas/index.d.ts +76 -1
- package/dist/schemas/index.mjs +23 -0
- package/dist/trigger/index.d.ts +1 -1
- package/dist/trigger/{index.js → index.mjs} +4 -4
- package/dist/workflow/index.d.ts +23 -3
- package/dist/workflow/{index.js → index.mjs} +21 -5
- package/dist/workflow/index.mjs.map +1 -0
- package/dist/{workflow-BYeIZgD0.d.ts → workflow-CUkzjf6m.d.ts} +97 -13
- package/package.json +6 -2
- package/dist/chunk-DSZ3GMT4.js.map +0 -1
- package/dist/chunk-KOXJCIST.js.map +0 -1
- package/dist/chunk-LXM7VS4Q.js +0 -129
- package/dist/chunk-LXM7VS4Q.js.map +0 -1
- package/dist/schemas/index.js +0 -11
- package/dist/workflow/index.js.map +0 -1
- /package/dist/ai/{index.js.map → index.mjs.map} +0 -0
- /package/dist/ai/{trigger.js.map → trigger.mjs.map} +0 -0
- /package/dist/ai/{workflow.js.map → workflow.mjs.map} +0 -0
- /package/dist/{chunk-D2FBSEZK.js.map → chunk-3ZYQE5LF.mjs.map} +0 -0
- /package/dist/schemas/{index.js.map → index.mjs.map} +0 -0
- /package/dist/trigger/{index.js.map → index.mjs.map} +0 -0
package/README.md
CHANGED
|
@@ -134,6 +134,45 @@ if (result.mode === "created") {
|
|
|
134
134
|
}
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
+
## Thread updates
|
|
138
|
+
|
|
139
|
+
Send short status updates (1-2 sentences) to a thread. The newest update shows in a status bar at the top of the inbox task detail, with an icon and color from an optional `status`; every update is logged in an expandable history. Updates are scoped to a `threadId`.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// Standalone update against an existing thread
|
|
143
|
+
const update = await robotrock.sendUpdate({
|
|
144
|
+
threadId, // from response.task.threadId
|
|
145
|
+
message: "Deployment started, running smoke tests.",
|
|
146
|
+
status: "running", // optional, defaults to "info"
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Or log an initial update when creating the task
|
|
150
|
+
await robotrock.sendToHuman({
|
|
151
|
+
type: "deploy-approval",
|
|
152
|
+
name: "Approve production rollout",
|
|
153
|
+
threadId: `deploy_${deploymentId}`,
|
|
154
|
+
update: { message: "Build finished, awaiting approval.", status: "waiting" },
|
|
155
|
+
actions: [{ id: "approve", title: "Approve" }],
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`status` is optional and one of: `info` | `queued` | `running` | `waiting` | `succeeded` | `failed` | `cancelled`. The `update` field is top-level (like `threadId` and `assignTo`), not inside `context`.
|
|
160
|
+
|
|
161
|
+
Updates are fire-and-forget, so the integration packages expose them too:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// Vercel Workflow: durable step, returns immediately (no suspend)
|
|
165
|
+
import { sendUpdateInWorkflow } from "robotrock/workflow";
|
|
166
|
+
await sendUpdateInWorkflow({ threadId, message: "Build started.", status: "running" });
|
|
167
|
+
|
|
168
|
+
// Vercel AI SDK: let an agent report progress on its thread
|
|
169
|
+
import { createSendUpdateTool } from "robotrock/ai";
|
|
170
|
+
const sendUpdate = createSendUpdateTool(robotrock, { threadId });
|
|
171
|
+
|
|
172
|
+
// Trigger.dev: no wrapper needed — call the SDK directly inside a task
|
|
173
|
+
await robotrock.sendUpdate({ threadId, message: "Job running.", status: "running" });
|
|
174
|
+
```
|
|
175
|
+
|
|
137
176
|
## Other client methods
|
|
138
177
|
|
|
139
178
|
```typescript
|
|
@@ -224,7 +263,7 @@ const result = await generateText({
|
|
|
224
263
|
});
|
|
225
264
|
```
|
|
226
265
|
|
|
227
|
-
For AI SDK tool execution approval (approve `deleteFile` before it runs), use `createRobotRockToolApproval`, `resolveToolApprovalsViaRobotRock`, and `runWithRobotRockApprovals` from `robotrock/ai`. See the [Vercel AI integration docs](https://
|
|
266
|
+
For AI SDK tool execution approval (approve `deleteFile` before it runs), use `createRobotRockToolApproval`, `resolveToolApprovalsViaRobotRock`, and `runWithRobotRockApprovals` from `robotrock/ai`. See the [Vercel AI integration docs](https://docs.robotrock.io/integrations/vercel-ai).
|
|
228
267
|
|
|
229
268
|
Run long polls inside Trigger.dev or a worker — not short serverless HTTP handlers.
|
|
230
269
|
|
|
@@ -234,7 +273,7 @@ Run long polls inside Trigger.dev or a worker — not short serverless HTTP hand
|
|
|
234
273
|
|--------|-------------|
|
|
235
274
|
| `robotrock` | `createClient`, `RobotRock`, env helpers, types, schemas |
|
|
236
275
|
| `robotrock/trigger` | `sendToHumanTask`, `approveByHumanTask` for Trigger.dev |
|
|
237
|
-
| `robotrock/workflow` | `sendToHumanInWorkflow`, `approveByHumanInWorkflow` for Vercel Workflow |
|
|
276
|
+
| `robotrock/workflow` | `sendToHumanInWorkflow`, `approveByHumanInWorkflow`, `sendUpdateInWorkflow` for Vercel Workflow |
|
|
238
277
|
| `robotrock/ai` | Vercel AI SDK tools and `toolApproval` bridge (peer: `ai`) |
|
|
239
278
|
| `robotrock/ai/trigger` | Same API, documented for `mode: "trigger"` in Trigger.dev workers |
|
|
240
279
|
| `robotrock/ai/workflow` | Same API, documented for `mode: "workflow"` in Vercel Workflow |
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as RobotRockToolCallInfo, F as FormatToolApprovalTaskOptions, H as HumanToolResult } from '../workflow-
|
|
2
|
-
export { A as APPROVE_BY_HUMAN_ACTIONS, d as ApproveByHumanToolDurableOptions, c as ApproveByHumanToolOptions,
|
|
3
|
-
import { a as SendToHumanInput } from '../client-
|
|
1
|
+
import { R as RobotRockToolCallInfo, F as FormatToolApprovalTaskOptions, H as HumanToolResult } from '../workflow-CUkzjf6m.js';
|
|
2
|
+
export { A as APPROVE_BY_HUMAN_ACTIONS, d as ApproveByHumanToolDurableOptions, c as ApproveByHumanToolOptions, x as CreateRobotRockAiToolsOptions, f as CreateSendToHumanToolDurableOptions, C as CreateSendToHumanToolOptions, j as CreateSendUpdateToolDurableOptions, i as CreateSendUpdateToolOptions, J as ResolveToolApprovalsOptions, o as RobotRockAiContext, p as RobotRockAiMode, q as RobotRockAiPollingContext, r as RobotRockAiTriggerContext, t as RobotRockAiWorkflowContext, K as RobotRockToolApprovalConfig, I as RobotRockToolApprovalDecision, L as RunWithRobotRockApprovalsOptions, S as SendUpdateToolResult, T as ToolApprovalRequestPart, y as applyRobotRockToolApprovalToTools, k as approveByHumanForAi, b as approveByHumanInputSchema, a as approveByHumanTool, z as collectApprovalRequests, u as createRobotRockAiTools, v as createRobotRockAiTriggerContext, w as createRobotRockAiWorkflowContext, B as createRobotRockNeedsApproval, D as createRobotRockToolApproval, e as createSendToHumanTool, g as createSendUpdateTool, n as normalizeRobotRockAiContext, E as resolveToolApprovalsViaRobotRock, G as runWithRobotRockApprovals, l as sendToHumanForAi, s as sendToHumanToolInputSchema, m as sendUpdateForAi, h as sendUpdateToolInputSchema } from '../workflow-CUkzjf6m.js';
|
|
3
|
+
import { a as SendToHumanInput } from '../client-BOm2Ce2f.js';
|
|
4
4
|
import { DiscriminatedApprovalResult } from '../schemas/index.js';
|
|
5
5
|
import 'ai';
|
|
6
6
|
import 'zod';
|
|
@@ -12,15 +12,19 @@ import {
|
|
|
12
12
|
createRobotRockNeedsApproval,
|
|
13
13
|
createRobotRockToolApproval,
|
|
14
14
|
createSendToHumanTool,
|
|
15
|
+
createSendUpdateTool,
|
|
15
16
|
defaultFormatToolApprovalTask,
|
|
16
17
|
normalizeRobotRockAiContext,
|
|
17
18
|
resolveToolApprovalsViaRobotRock,
|
|
18
19
|
runWithRobotRockApprovals,
|
|
19
20
|
sendToHumanForAi,
|
|
20
21
|
sendToHumanToolInputSchema,
|
|
22
|
+
sendUpdateForAi,
|
|
23
|
+
sendUpdateToolInputSchema,
|
|
21
24
|
toHumanToolResult
|
|
22
|
-
} from "../chunk-
|
|
23
|
-
import "../chunk-
|
|
25
|
+
} from "../chunk-CWQTNK24.mjs";
|
|
26
|
+
import "../chunk-E7ZWBFZ6.mjs";
|
|
27
|
+
import "../chunk-VNXWLPRV.mjs";
|
|
24
28
|
export {
|
|
25
29
|
APPROVE_BY_HUMAN_ACTIONS,
|
|
26
30
|
DEFAULT_APPROVE_ACTIONS,
|
|
@@ -35,12 +39,15 @@ export {
|
|
|
35
39
|
createRobotRockNeedsApproval,
|
|
36
40
|
createRobotRockToolApproval,
|
|
37
41
|
createSendToHumanTool,
|
|
42
|
+
createSendUpdateTool,
|
|
38
43
|
defaultFormatToolApprovalTask,
|
|
39
44
|
normalizeRobotRockAiContext,
|
|
40
45
|
resolveToolApprovalsViaRobotRock,
|
|
41
46
|
runWithRobotRockApprovals,
|
|
42
47
|
sendToHumanForAi,
|
|
43
48
|
sendToHumanToolInputSchema,
|
|
49
|
+
sendUpdateForAi,
|
|
50
|
+
sendUpdateToolInputSchema,
|
|
44
51
|
toHumanToolResult
|
|
45
52
|
};
|
|
46
|
-
//# sourceMappingURL=index.
|
|
53
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/ai/trigger.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { o as RobotRockAiContext, p as RobotRockAiMode, q as RobotRockAiPollingContext, r as RobotRockAiTriggerContext, y as applyRobotRockToolApprovalToTools, a as approveByHumanTool, u as createRobotRockAiTools, v as createRobotRockAiTriggerContext, B as createRobotRockNeedsApproval, D as createRobotRockToolApproval, e as createSendToHumanTool, g as createSendUpdateTool, E as resolveToolApprovalsViaRobotRock, G as runWithRobotRockApprovals } from '../workflow-CUkzjf6m.js';
|
|
2
2
|
import 'ai';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../client-
|
|
4
|
+
import '../client-BOm2Ce2f.js';
|
|
5
5
|
import '../schemas/index.js';
|
|
@@ -6,10 +6,12 @@ import {
|
|
|
6
6
|
createRobotRockNeedsApproval,
|
|
7
7
|
createRobotRockToolApproval,
|
|
8
8
|
createSendToHumanTool,
|
|
9
|
+
createSendUpdateTool,
|
|
9
10
|
resolveToolApprovalsViaRobotRock,
|
|
10
11
|
runWithRobotRockApprovals
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-CWQTNK24.mjs";
|
|
13
|
+
import "../chunk-E7ZWBFZ6.mjs";
|
|
14
|
+
import "../chunk-VNXWLPRV.mjs";
|
|
13
15
|
export {
|
|
14
16
|
applyRobotRockToolApprovalToTools,
|
|
15
17
|
approveByHumanTool,
|
|
@@ -18,7 +20,8 @@ export {
|
|
|
18
20
|
createRobotRockNeedsApproval,
|
|
19
21
|
createRobotRockToolApproval,
|
|
20
22
|
createSendToHumanTool,
|
|
23
|
+
createSendUpdateTool,
|
|
21
24
|
resolveToolApprovalsViaRobotRock,
|
|
22
25
|
runWithRobotRockApprovals
|
|
23
26
|
};
|
|
24
|
-
//# sourceMappingURL=trigger.
|
|
27
|
+
//# sourceMappingURL=trigger.mjs.map
|
package/dist/ai/workflow.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { o as RobotRockAiContext, p as RobotRockAiMode, q as RobotRockAiPollingContext, r as RobotRockAiTriggerContext, t as RobotRockAiWorkflowContext, y as applyRobotRockToolApprovalToTools, a as approveByHumanTool, u as createRobotRockAiTools, w as createRobotRockAiWorkflowContext, B as createRobotRockNeedsApproval, D as createRobotRockToolApproval, e as createSendToHumanTool, g as createSendUpdateTool, E as resolveToolApprovalsViaRobotRock, G as runWithRobotRockApprovals } from '../workflow-CUkzjf6m.js';
|
|
2
2
|
import 'ai';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../client-
|
|
4
|
+
import '../client-BOm2Ce2f.js';
|
|
5
5
|
import '../schemas/index.js';
|
|
@@ -6,10 +6,12 @@ import {
|
|
|
6
6
|
createRobotRockNeedsApproval,
|
|
7
7
|
createRobotRockToolApproval,
|
|
8
8
|
createSendToHumanTool,
|
|
9
|
+
createSendUpdateTool,
|
|
9
10
|
resolveToolApprovalsViaRobotRock,
|
|
10
11
|
runWithRobotRockApprovals
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-CWQTNK24.mjs";
|
|
13
|
+
import "../chunk-E7ZWBFZ6.mjs";
|
|
14
|
+
import "../chunk-VNXWLPRV.mjs";
|
|
13
15
|
export {
|
|
14
16
|
applyRobotRockToolApprovalToTools,
|
|
15
17
|
approveByHumanTool,
|
|
@@ -18,7 +20,8 @@ export {
|
|
|
18
20
|
createRobotRockNeedsApproval,
|
|
19
21
|
createRobotRockToolApproval,
|
|
20
22
|
createSendToHumanTool,
|
|
23
|
+
createSendUpdateTool,
|
|
21
24
|
resolveToolApprovalsViaRobotRock,
|
|
22
25
|
runWithRobotRockApprovals
|
|
23
26
|
};
|
|
24
|
-
//# sourceMappingURL=workflow.
|
|
27
|
+
//# sourceMappingURL=workflow.mjs.map
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
RobotRockError,
|
|
3
|
+
createClient,
|
|
4
|
+
resolveRobotRockConfig
|
|
5
|
+
} from "./chunk-E7ZWBFZ6.mjs";
|
|
6
|
+
import {
|
|
7
|
+
assignToSchema,
|
|
8
|
+
external_exports,
|
|
9
|
+
threadUpdateStatusSchema
|
|
10
|
+
} from "./chunk-VNXWLPRV.mjs";
|
|
4
11
|
|
|
5
12
|
// src/ai/context.ts
|
|
6
13
|
var APPROVE_BY_HUMAN_ACTIONS = [
|
|
@@ -27,7 +34,7 @@ function normalizeRobotRockAiContext(clientOrContext) {
|
|
|
27
34
|
}
|
|
28
35
|
async function sendToHumanForAi(context, payload) {
|
|
29
36
|
if (context.mode === "trigger") {
|
|
30
|
-
const { sendToHumanTask } = await import("./trigger/index.
|
|
37
|
+
const { sendToHumanTask } = await import("./trigger/index.mjs");
|
|
31
38
|
const waitResult = await sendToHumanTask.triggerAndWait({
|
|
32
39
|
...payload,
|
|
33
40
|
...context.app ? { app: context.app } : {}
|
|
@@ -38,7 +45,7 @@ async function sendToHumanForAi(context, payload) {
|
|
|
38
45
|
return waitResult.output;
|
|
39
46
|
}
|
|
40
47
|
if (context.mode === "workflow") {
|
|
41
|
-
const { sendToHumanInWorkflow } = await import("./workflow/index.
|
|
48
|
+
const { sendToHumanInWorkflow } = await import("./workflow/index.mjs");
|
|
42
49
|
const result2 = await sendToHumanInWorkflow({
|
|
43
50
|
...payload,
|
|
44
51
|
...context.app ? { app: context.app } : {}
|
|
@@ -59,9 +66,25 @@ async function sendToHumanForAi(context, payload) {
|
|
|
59
66
|
taskId: result.taskId
|
|
60
67
|
};
|
|
61
68
|
}
|
|
69
|
+
async function sendUpdateForAi(context, payload) {
|
|
70
|
+
if (context.mode === "workflow") {
|
|
71
|
+
const { sendUpdateInWorkflow } = await import("./workflow/index.mjs");
|
|
72
|
+
return sendUpdateInWorkflow({
|
|
73
|
+
...payload,
|
|
74
|
+
...context.app ? { app: context.app } : {}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (context.mode === "trigger") {
|
|
78
|
+
const client = createClient(
|
|
79
|
+
resolveRobotRockConfig(context.app ? { app: context.app } : void 0)
|
|
80
|
+
);
|
|
81
|
+
return client.sendUpdate(payload);
|
|
82
|
+
}
|
|
83
|
+
return context.client.sendUpdate(payload);
|
|
84
|
+
}
|
|
62
85
|
async function approveByHumanForAi(context, payload) {
|
|
63
86
|
if (context.mode === "trigger") {
|
|
64
|
-
const { approveByHumanTask } = await import("./trigger/index.
|
|
87
|
+
const { approveByHumanTask } = await import("./trigger/index.mjs");
|
|
65
88
|
const waitResult = await approveByHumanTask.triggerAndWait({
|
|
66
89
|
...payload,
|
|
67
90
|
...context.app ? { app: context.app } : {}
|
|
@@ -72,7 +95,7 @@ async function approveByHumanForAi(context, payload) {
|
|
|
72
95
|
return waitResult.output;
|
|
73
96
|
}
|
|
74
97
|
if (context.mode === "workflow") {
|
|
75
|
-
const { approveByHumanInWorkflow } = await import("./workflow/index.
|
|
98
|
+
const { approveByHumanInWorkflow } = await import("./workflow/index.mjs");
|
|
76
99
|
return await approveByHumanInWorkflow({
|
|
77
100
|
...payload,
|
|
78
101
|
...context.app ? { app: context.app } : {}
|
|
@@ -117,16 +140,15 @@ function toHumanToolResult(result) {
|
|
|
117
140
|
|
|
118
141
|
// src/ai/approve-by-human-tool.ts
|
|
119
142
|
import { tool } from "ai";
|
|
120
|
-
import { z } from "zod";
|
|
121
143
|
var APPROVE_BY_HUMAN_ACTIONS2 = [
|
|
122
144
|
{ id: "approve", title: "Approve" },
|
|
123
145
|
{ id: "decline", title: "Decline" }
|
|
124
146
|
];
|
|
125
|
-
var approveByHumanInputSchema =
|
|
126
|
-
type:
|
|
127
|
-
name:
|
|
128
|
-
description:
|
|
129
|
-
contextSummary:
|
|
147
|
+
var approveByHumanInputSchema = external_exports.object({
|
|
148
|
+
type: external_exports.string().optional().describe("Task type slug; defaults to ai-approval"),
|
|
149
|
+
name: external_exports.string().describe("Short title for the approval request"),
|
|
150
|
+
description: external_exports.string().describe("What needs approval and the consequences of approving or declining"),
|
|
151
|
+
contextSummary: external_exports.string().optional().describe("Optional markdown summary shown to the reviewer")
|
|
130
152
|
});
|
|
131
153
|
function approveByHumanTool(clientOrContext, maybeOptions = {}) {
|
|
132
154
|
const isDurable = typeof clientOrContext === "object" && clientOrContext !== null && "mode" in clientOrContext && (clientOrContext.mode === "trigger" || clientOrContext.mode === "workflow");
|
|
@@ -161,17 +183,16 @@ function approveByHumanTool(clientOrContext, maybeOptions = {}) {
|
|
|
161
183
|
|
|
162
184
|
// src/ai/create-send-to-human-tool.ts
|
|
163
185
|
import { tool as tool2 } from "ai";
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
ui: z2.record(z2.unknown()).optional()
|
|
186
|
+
var contextInputSchema = external_exports.object({
|
|
187
|
+
data: external_exports.record(external_exports.unknown()).optional(),
|
|
188
|
+
ui: external_exports.record(external_exports.unknown()).optional()
|
|
168
189
|
}).optional();
|
|
169
|
-
var sendToHumanToolInputSchema =
|
|
170
|
-
type:
|
|
171
|
-
name:
|
|
172
|
-
description:
|
|
190
|
+
var sendToHumanToolInputSchema = external_exports.object({
|
|
191
|
+
type: external_exports.string().describe("Task type slug shown in the RobotRock inbox"),
|
|
192
|
+
name: external_exports.string().describe("Short title for the human reviewer"),
|
|
193
|
+
description: external_exports.string().optional().describe("What you need from the human and why you cannot proceed alone"),
|
|
173
194
|
context: contextInputSchema.describe("Optional structured context for the inbox UI"),
|
|
174
|
-
validUntil:
|
|
195
|
+
validUntil: external_exports.string().datetime().optional().describe("Optional ISO deadline for the task"),
|
|
175
196
|
assignTo: assignToSchema.optional().describe(
|
|
176
197
|
"Assign to tenant member emails and/or group slugs; narrows who sees the task in the inbox"
|
|
177
198
|
)
|
|
@@ -201,7 +222,8 @@ function createSendToHumanTool(clientOrOptions, maybeOptions) {
|
|
|
201
222
|
context: taskContext,
|
|
202
223
|
validUntil: input.validUntil,
|
|
203
224
|
assignTo: input.assignTo,
|
|
204
|
-
actions: options.actions
|
|
225
|
+
actions: options.actions,
|
|
226
|
+
...options.threadId ? { threadId: options.threadId } : {}
|
|
205
227
|
};
|
|
206
228
|
const result = await sendToHumanForAi(aiContext, payload);
|
|
207
229
|
return toHumanToolResult(result);
|
|
@@ -209,6 +231,59 @@ function createSendToHumanTool(clientOrOptions, maybeOptions) {
|
|
|
209
231
|
});
|
|
210
232
|
}
|
|
211
233
|
|
|
234
|
+
// src/ai/create-send-update-tool.ts
|
|
235
|
+
import { tool as tool3 } from "ai";
|
|
236
|
+
var sendUpdateToolInputSchema = external_exports.object({
|
|
237
|
+
threadId: external_exports.string().optional().describe(
|
|
238
|
+
"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."
|
|
239
|
+
),
|
|
240
|
+
message: external_exports.string().describe("Short progress update (1-2 sentences) shown in the inbox status bar"),
|
|
241
|
+
status: threadUpdateStatusSchema.optional().describe(
|
|
242
|
+
"Lifecycle status driving the status-bar icon/color: info, queued, running, waiting, succeeded, failed, cancelled"
|
|
243
|
+
)
|
|
244
|
+
});
|
|
245
|
+
function createSendUpdateTool(clientOrOptions, maybeOptions = {}) {
|
|
246
|
+
const isDurable = typeof clientOrOptions === "object" && clientOrOptions !== null && "mode" in clientOrOptions && (clientOrOptions.mode === "trigger" || clientOrOptions.mode === "workflow");
|
|
247
|
+
const aiContext = normalizeRobotRockAiContext(
|
|
248
|
+
isDurable ? {
|
|
249
|
+
mode: clientOrOptions.mode,
|
|
250
|
+
app: clientOrOptions.app
|
|
251
|
+
} : clientOrOptions
|
|
252
|
+
);
|
|
253
|
+
const options = isDurable ? clientOrOptions : maybeOptions;
|
|
254
|
+
const description = options.description ?? "Post a short progress update to the RobotRock thread you are working on. Use to report status changes (running, succeeded, failed) so humans can follow along in the inbox.";
|
|
255
|
+
return tool3({
|
|
256
|
+
description,
|
|
257
|
+
inputSchema: sendUpdateToolInputSchema,
|
|
258
|
+
execute: async (input) => {
|
|
259
|
+
const threadId = input.threadId ?? options.threadId;
|
|
260
|
+
if (!threadId) {
|
|
261
|
+
throw new Error(
|
|
262
|
+
"createSendUpdateTool: no threadId. Pass `threadId` from a prior send-to-human result, or configure a session `threadId` in the tool options."
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
const update = await sendUpdateForAi(aiContext, {
|
|
267
|
+
threadId,
|
|
268
|
+
message: input.message,
|
|
269
|
+
status: input.status
|
|
270
|
+
});
|
|
271
|
+
return { posted: true, threadId, update };
|
|
272
|
+
} catch (error) {
|
|
273
|
+
if (error instanceof RobotRockError && error.statusCode === 404) {
|
|
274
|
+
return {
|
|
275
|
+
posted: false,
|
|
276
|
+
threadId,
|
|
277
|
+
reason: "thread_not_found",
|
|
278
|
+
message: `No task exists for thread "${threadId}" yet, so the update was not posted. Create a task on this thread with send-to-human before reporting progress.`
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
212
287
|
// src/ai/create-ai-tools.ts
|
|
213
288
|
function createRobotRockAiTools(options) {
|
|
214
289
|
const mode = options.mode ?? (options.client ? "polling" : "trigger");
|
|
@@ -221,7 +296,22 @@ function createRobotRockAiTools(options) {
|
|
|
221
296
|
return {
|
|
222
297
|
context,
|
|
223
298
|
approveByHuman: (toolOptions) => durableContext ? approveByHumanTool({ ...durableContext, ...toolOptions }) : approveByHumanTool(pollingClient, toolOptions),
|
|
224
|
-
sendToHuman: (toolOptions) => durableContext ? createSendToHumanTool({
|
|
299
|
+
sendToHuman: (toolOptions) => durableContext ? createSendToHumanTool({
|
|
300
|
+
...durableContext,
|
|
301
|
+
...options.threadId ? { threadId: options.threadId } : {},
|
|
302
|
+
...toolOptions
|
|
303
|
+
}) : createSendToHumanTool(pollingClient, {
|
|
304
|
+
...options.threadId ? { threadId: options.threadId } : {},
|
|
305
|
+
...toolOptions
|
|
306
|
+
}),
|
|
307
|
+
sendUpdate: (toolOptions = {}) => durableContext ? createSendUpdateTool({
|
|
308
|
+
...durableContext,
|
|
309
|
+
...options.threadId ? { threadId: options.threadId } : {},
|
|
310
|
+
...toolOptions
|
|
311
|
+
}) : createSendUpdateTool(pollingClient, {
|
|
312
|
+
...options.threadId ? { threadId: options.threadId } : {},
|
|
313
|
+
...toolOptions
|
|
314
|
+
})
|
|
225
315
|
};
|
|
226
316
|
}
|
|
227
317
|
function createRobotRockAiTriggerContext(options = {}) {
|
|
@@ -496,6 +586,7 @@ async function runWithRobotRockApprovals(options) {
|
|
|
496
586
|
export {
|
|
497
587
|
normalizeRobotRockAiContext,
|
|
498
588
|
sendToHumanForAi,
|
|
589
|
+
sendUpdateForAi,
|
|
499
590
|
approveByHumanForAi,
|
|
500
591
|
toHumanToolResult,
|
|
501
592
|
APPROVE_BY_HUMAN_ACTIONS2 as APPROVE_BY_HUMAN_ACTIONS,
|
|
@@ -503,6 +594,8 @@ export {
|
|
|
503
594
|
approveByHumanTool,
|
|
504
595
|
sendToHumanToolInputSchema,
|
|
505
596
|
createSendToHumanTool,
|
|
597
|
+
sendUpdateToolInputSchema,
|
|
598
|
+
createSendUpdateTool,
|
|
506
599
|
createRobotRockAiTools,
|
|
507
600
|
createRobotRockAiTriggerContext,
|
|
508
601
|
createRobotRockAiWorkflowContext,
|
|
@@ -515,4 +608,4 @@ export {
|
|
|
515
608
|
resolveToolApprovalsViaRobotRock,
|
|
516
609
|
runWithRobotRockApprovals
|
|
517
610
|
};
|
|
518
|
-
//# sourceMappingURL=chunk-
|
|
611
|
+
//# sourceMappingURL=chunk-CWQTNK24.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ai/context.ts","../src/ai/human-tool-result.ts","../src/ai/approve-by-human-tool.ts","../src/ai/create-send-to-human-tool.ts","../src/ai/create-send-update-tool.ts","../src/ai/create-ai-tools.ts","../src/ai/format-tool-approval-task.ts","../src/ai/tool-approval-bridge.ts"],"sourcesContent":["import {\n createClient,\n type RobotRock,\n type SendToHumanActionInput,\n type SendToHumanInput,\n type SendUpdateInput,\n} from \"../client.js\";\nimport { resolveRobotRockConfig } from \"../env.js\";\nimport type { DiscriminatedApprovalResult, ThreadUpdate } from \"../schemas/index.js\";\nconst APPROVE_BY_HUMAN_ACTIONS = [\n { id: \"approve\", title: \"Approve\" },\n { id: \"decline\", title: \"Decline\" },\n] as const;\n\n/** How RobotRock waits for a human inside AI SDK tool `execute`. */\nexport type RobotRockAiMode = \"polling\" | \"trigger\" | \"workflow\";\n\n/**\n * Polling: `client.sendToHuman()` blocks until handled (scripts, API routes with long timeout).\n * Trigger: `sendToHumanTask.triggerAndWait()` uses wait tokens (Trigger.dev workers).\n * Workflow: `sendToHumanInWorkflow()` uses workflow webhooks (Vercel Workflow).\n */\nexport type RobotRockAiPollingContext = {\n mode?: \"polling\";\n client: RobotRock;\n};\n\nexport type RobotRockAiTriggerContext = {\n mode: \"trigger\";\n /** Inbox app bucket; falls back to `ROBOTROCK_APP` in the Trigger worker. */\n app?: string;\n};\n\nexport type RobotRockAiWorkflowContext = {\n mode: \"workflow\";\n /** Inbox app bucket; falls back to `ROBOTROCK_APP` in the workflow run. */\n app?: string;\n};\n\nexport type RobotRockAiContext =\n | RobotRockAiPollingContext\n | RobotRockAiTriggerContext\n | RobotRockAiWorkflowContext;\n\nexport function isRobotRockClient(value: unknown): value is RobotRock {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"sendToHuman\" in value &&\n typeof (value as RobotRock).sendToHuman === \"function\"\n );\n}\n\nexport function normalizeRobotRockAiContext(\n clientOrContext: RobotRock | RobotRockAiContext\n): RobotRockAiContext {\n if (isRobotRockClient(clientOrContext)) {\n return { mode: \"polling\", client: clientOrContext };\n }\n\n if (clientOrContext.mode === \"trigger\" || clientOrContext.mode === \"workflow\") {\n return clientOrContext;\n }\n\n if (clientOrContext.mode === \"polling\" || clientOrContext.mode === undefined) {\n if (!(\"client\" in clientOrContext) || !clientOrContext.client) {\n throw new Error('RobotRock AI polling mode requires `client` on the context object.');\n }\n return { mode: \"polling\", client: clientOrContext.client };\n }\n\n throw new Error(`Unknown RobotRock AI mode: ${String((clientOrContext as { mode?: string }).mode)}`);\n}\n\nexport async function sendToHumanForAi<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n>(\n context: RobotRockAiContext,\n payload: SendToHumanInput<A>\n): Promise<DiscriminatedApprovalResult<A>> {\n if (context.mode === \"trigger\") {\n const { sendToHumanTask } = await import(\"../trigger/index.js\");\n const waitResult = await sendToHumanTask.triggerAndWait({\n ...payload,\n ...(context.app ? { app: context.app } : {}),\n });\n\n if (!waitResult.ok) {\n throw waitResult.error;\n }\n\n return waitResult.output as DiscriminatedApprovalResult<A>;\n }\n\n if (context.mode === \"workflow\") {\n const { sendToHumanInWorkflow } = await import(\"../workflow/index.js\");\n const result = await sendToHumanInWorkflow({\n ...payload,\n ...(context.app ? { app: context.app } : {}),\n });\n return result as unknown as DiscriminatedApprovalResult<A>;\n }\n\n const result = await context.client.sendToHuman(payload);\n\n if (result.mode !== \"handled\") {\n throw new Error(\n \"RobotRock task was created but not handled. Configure client polling or webhook, or use mode: 'trigger' / 'workflow' for durable waits.\"\n );\n }\n\n return {\n actionId: result.actionId,\n data: result.data,\n handledBy: result.handledBy,\n handledAt: result.handledAt,\n taskId: result.taskId,\n } as DiscriminatedApprovalResult<A>;\n}\n\n/**\n * Posts a thread update for an AI tool, routing by execution mode.\n *\n * `sendUpdate` is fire-and-forget (no human wait), so only the workflow path\n * needs durability — it runs inside a `\"use step\"`. Trigger and polling modes\n * issue the request directly.\n */\nexport async function sendUpdateForAi(\n context: RobotRockAiContext,\n payload: SendUpdateInput\n): Promise<ThreadUpdate> {\n if (context.mode === \"workflow\") {\n const { sendUpdateInWorkflow } = await import(\"../workflow/index.js\");\n return sendUpdateInWorkflow({\n ...payload,\n ...(context.app ? { app: context.app } : {}),\n });\n }\n\n if (context.mode === \"trigger\") {\n const client = createClient(\n resolveRobotRockConfig(context.app ? { app: context.app } : undefined)\n );\n return client.sendUpdate(payload);\n }\n\n return context.client.sendUpdate(payload);\n}\n\nexport async function approveByHumanForAi(\n context: RobotRockAiContext,\n payload: Omit<SendToHumanInput, \"actions\"> & { app?: string }\n): Promise<DiscriminatedApprovalResult<typeof APPROVE_BY_HUMAN_ACTIONS>> {\n if (context.mode === \"trigger\") {\n const { approveByHumanTask } = await import(\"../trigger/index.js\");\n const waitResult = await approveByHumanTask.triggerAndWait({\n ...payload,\n ...(context.app ? { app: context.app } : {}),\n });\n\n if (!waitResult.ok) {\n throw waitResult.error;\n }\n\n return waitResult.output;\n }\n\n if (context.mode === \"workflow\") {\n const { approveByHumanInWorkflow } = await import(\"../workflow/index.js\");\n return await approveByHumanInWorkflow({\n ...payload,\n ...(context.app ? { app: context.app } : {}),\n });\n }\n\n const result = await context.client.sendToHuman({\n ...payload,\n actions: APPROVE_BY_HUMAN_ACTIONS,\n });\n\n if (result.mode !== \"handled\") {\n throw new Error(\n \"RobotRock approval was not handled. Configure client polling or use mode: 'trigger' / 'workflow' for durable waits.\"\n );\n }\n\n return {\n actionId: result.actionId,\n data: result.data,\n handledBy: result.handledBy,\n handledAt: result.handledAt,\n taskId: result.taskId,\n } as DiscriminatedApprovalResult<typeof APPROVE_BY_HUMAN_ACTIONS>;\n}\n","import type { DiscriminatedApprovalResult } from \"../schemas/index.js\";\nimport type { HumanToolResult } from \"./types.js\";\n\nconst APPROVE_IDS = new Set([\"approve\", \"approved\"]);\nconst DECLINE_IDS = new Set([\"decline\", \"reject\", \"deny\", \"denied\"]);\n\nexport function toHumanToolResult(\n result: DiscriminatedApprovalResult<readonly { id: string }[]>\n): HumanToolResult {\n const payload: HumanToolResult = {\n taskId: result.taskId,\n actionId: result.actionId,\n data: result.data,\n handledBy: result.handledBy,\n handledAt: result.handledAt.toISOString(),\n };\n\n if (APPROVE_IDS.has(result.actionId)) {\n payload.approved = true;\n } else if (DECLINE_IDS.has(result.actionId)) {\n payload.approved = false;\n }\n\n return payload;\n}\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport type { RobotRock } from \"../client.js\";\nimport { approveByHumanForAi, normalizeRobotRockAiContext, type RobotRockAiContext } from \"./context.js\";\nimport { toHumanToolResult } from \"./human-tool-result.js\";\nimport type { HumanToolResult } from \"./types.js\";\n\nconst APPROVE_BY_HUMAN_ACTIONS = [\n { id: \"approve\", title: \"Approve\" },\n { id: \"decline\", title: \"Decline\" },\n] as const;\n\nconst approveByHumanInputSchema = z.object({\n type: z\n .string()\n .optional()\n .describe(\"Task type slug; defaults to ai-approval\"),\n name: z.string().describe(\"Short title for the approval request\"),\n description: z\n .string()\n .describe(\"What needs approval and the consequences of approving or declining\"),\n contextSummary: z\n .string()\n .optional()\n .describe(\"Optional markdown summary shown to the reviewer\"),\n});\n\nexport type ApproveByHumanToolOptions = {\n defaultType?: string;\n description?: string;\n toolName?: string;\n};\n\nexport type ApproveByHumanToolDurableOptions = ApproveByHumanToolOptions &\n RobotRockAiContext & { mode: \"trigger\" | \"workflow\" };\n\n/**\n * AI SDK tool with fixed approve/decline actions; blocks until a human decides.\n *\n * - `approveByHumanTool(robotrock)` — polling via `client.sendToHuman()` (default).\n * - `approveByHumanTool({ mode: \"trigger\", app?: \"my-agent\" })` — durable wait via Trigger.dev.\n * - `approveByHumanTool({ mode: \"workflow\", app?: \"my-agent\" })` — durable wait via Vercel Workflow.\n */\nexport function approveByHumanTool(\n clientOrContext: RobotRock | ApproveByHumanToolDurableOptions,\n maybeOptions: ApproveByHumanToolOptions = {}\n) {\n const isDurable =\n typeof clientOrContext === \"object\" &&\n clientOrContext !== null &&\n \"mode\" in clientOrContext &&\n (clientOrContext.mode === \"trigger\" || clientOrContext.mode === \"workflow\");\n\n const aiContext = normalizeRobotRockAiContext(\n isDurable\n ? {\n mode: (clientOrContext as ApproveByHumanToolDurableOptions).mode,\n app: (clientOrContext as ApproveByHumanToolDurableOptions).app,\n }\n : (clientOrContext as RobotRock)\n );\n const options = isDurable\n ? (clientOrContext as ApproveByHumanToolDurableOptions)\n : maybeOptions;\n const description =\n options.description ??\n \"Request explicit human approval before a sensitive or irreversible step. Returns whether the human approved or declined.\";\n\n return tool({\n description,\n inputSchema: approveByHumanInputSchema,\n execute: async (input: z.infer<typeof approveByHumanInputSchema>): Promise<HumanToolResult> => {\n const taskContext =\n input.contextSummary !== undefined\n ? {\n data: { summary: input.contextSummary },\n ui: {\n summary: { \"ui:widget\": \"textarea\", \"ui:options\": { rows: 6 } },\n },\n }\n : undefined;\n\n const result = await approveByHumanForAi(aiContext, {\n type: input.type ?? options.defaultType ?? \"ai-approval\",\n name: input.name,\n description: input.description,\n context: taskContext,\n });\n\n return toHumanToolResult(result);\n },\n });\n}\n\nexport { APPROVE_BY_HUMAN_ACTIONS, approveByHumanInputSchema };\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { assignToSchema } from \"../schemas/index.js\";\nimport type { RobotRock, SendToHumanActionInput, SendToHumanInput } from \"../client.js\";\nimport type { TaskContextInput } from \"../schemas/index.js\";\nimport {\n normalizeRobotRockAiContext,\n sendToHumanForAi,\n type RobotRockAiContext,\n} from \"./context.js\";\nimport { toHumanToolResult } from \"./human-tool-result.js\";\nimport type { HumanToolResult } from \"./types.js\";\n\nconst contextInputSchema = z\n .object({\n data: z.record(z.unknown()).optional(),\n ui: z.record(z.unknown()).optional(),\n })\n .optional();\n\nconst sendToHumanToolInputSchema = z.object({\n type: z.string().describe(\"Task type slug shown in the RobotRock inbox\"),\n name: z.string().describe(\"Short title for the human reviewer\"),\n description: z\n .string()\n .optional()\n .describe(\"What you need from the human and why you cannot proceed alone\"),\n context: contextInputSchema.describe(\"Optional structured context for the inbox UI\"),\n validUntil: z\n .string()\n .datetime()\n .optional()\n .describe(\"Optional ISO deadline for the task\"),\n assignTo: assignToSchema\n .optional()\n .describe(\n \"Assign to tenant member emails and/or group slugs; narrows who sees the task in the inbox\"\n ),\n});\n\nexport type CreateSendToHumanToolOptions<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = {\n actions: A;\n defaultType?: string;\n description?: string;\n toolName?: string;\n /**\n * Group every task this tool creates onto a shared thread. Pass the same\n * value to {@link createSendUpdateTool} so updates land on the same thread.\n */\n threadId?: string;\n};\n\nexport type CreateSendToHumanToolDurableOptions<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n> = CreateSendToHumanToolOptions<A> & RobotRockAiContext & { mode: \"trigger\" | \"workflow\" };\n\n/**\n * AI SDK tool that blocks until a human handles a RobotRock task with developer-defined actions.\n *\n * - `createSendToHumanTool(robotrock, options)` — polling (default).\n * - `createSendToHumanTool({ mode: \"trigger\", actions: [...], app?: \"my-agent\" })` — Trigger.dev wait tokens.\n * - `createSendToHumanTool({ mode: \"workflow\", actions: [...], app?: \"my-agent\" })` — Vercel Workflow webhooks.\n */\nexport function createSendToHumanTool<\n A extends readonly SendToHumanActionInput[] = readonly SendToHumanActionInput[],\n>(\n clientOrOptions: RobotRock | CreateSendToHumanToolDurableOptions<A>,\n maybeOptions?: CreateSendToHumanToolOptions<A>\n) {\n const isDurable =\n typeof clientOrOptions === \"object\" &&\n clientOrOptions !== null &&\n \"mode\" in clientOrOptions &&\n (clientOrOptions.mode === \"trigger\" || clientOrOptions.mode === \"workflow\");\n\n const aiContext = normalizeRobotRockAiContext(\n isDurable\n ? {\n mode: (clientOrOptions as CreateSendToHumanToolDurableOptions<A>).mode,\n app: (clientOrOptions as CreateSendToHumanToolDurableOptions<A>).app,\n }\n : (clientOrOptions as RobotRock)\n );\n const options = (isDurable ? clientOrOptions : maybeOptions!) as CreateSendToHumanToolOptions<A>;\n const description =\n options.description ??\n \"Request structured input or a decision from a human in the RobotRock inbox. Use when you lack required information, need policy approval, or must confirm an irreversible step.\";\n\n return tool({\n description,\n inputSchema: sendToHumanToolInputSchema,\n execute: async (\n input: z.infer<typeof sendToHumanToolInputSchema>\n ): Promise<HumanToolResult> => {\n const taskContext: TaskContextInput[\"context\"] | undefined = input.context\n ? ({\n data: input.context.data ?? {},\n ui: input.context.ui,\n } as TaskContextInput[\"context\"])\n : undefined;\n\n const payload: SendToHumanInput<A> = {\n type: input.type ?? options.defaultType ?? \"ai-human-input\",\n name: input.name,\n description: input.description,\n context: taskContext,\n validUntil: input.validUntil,\n assignTo: input.assignTo,\n actions: options.actions,\n ...(options.threadId ? { threadId: options.threadId } : {}),\n };\n\n const result = await sendToHumanForAi(aiContext, payload);\n\n return toHumanToolResult(result);\n },\n });\n}\n\nexport { sendToHumanToolInputSchema };\n","import { tool } from \"ai\";\nimport { z } from \"zod\";\nimport { threadUpdateStatusSchema } from \"../schemas/index.js\";\nimport { RobotRockError, type RobotRock } from \"../client.js\";\nimport type { ThreadUpdate } from \"../schemas/index.js\";\nimport {\n normalizeRobotRockAiContext,\n sendUpdateForAi,\n type RobotRockAiContext,\n} from \"./context.js\";\n\n/**\n * Result returned to the model by {@link createSendUpdateTool}.\n *\n * Updates are fire-and-forget, so a missing thread (no task created yet) is\n * reported as `{ posted: false }` instead of throwing — that way an agent loop\n * is never aborted by a non-critical progress update. Genuine failures (auth,\n * validation, server errors) still throw.\n */\nexport type SendUpdateToolResult =\n | { posted: true; threadId: string; update: ThreadUpdate }\n | {\n posted: false;\n threadId: string;\n reason: \"thread_not_found\";\n message: string;\n };\n\nconst sendUpdateToolInputSchema = z.object({\n threadId: z\n .string()\n .optional()\n .describe(\n \"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.\"\n ),\n message: z\n .string()\n .describe(\"Short progress update (1-2 sentences) shown in the inbox status bar\"),\n status: threadUpdateStatusSchema\n .optional()\n .describe(\n \"Lifecycle status driving the status-bar icon/color: info, queued, running, waiting, succeeded, failed, cancelled\"\n ),\n});\n\nexport type CreateSendUpdateToolOptions = {\n /**\n * Session thread to post updates to when the model does not supply `threadId`.\n * Pass the same value to {@link createSendToHumanTool} to auto-thread tasks\n * and updates together.\n */\n threadId?: string;\n description?: string;\n};\n\nexport type CreateSendUpdateToolDurableOptions = CreateSendUpdateToolOptions &\n RobotRockAiContext & { mode: \"trigger\" | \"workflow\" };\n\n/**\n * AI SDK tool that posts a progress update to a RobotRock thread.\n *\n * Fire-and-forget (no human wait): the agent reports status as it works.\n *\n * - `createSendUpdateTool(robotrock, options?)` — polling client (default).\n * - `createSendUpdateTool({ mode: \"trigger\", app?: \"my-agent\" })` — Trigger.dev worker.\n * - `createSendUpdateTool({ mode: \"workflow\", app?: \"my-agent\" })` — Vercel Workflow (durable step).\n *\n * The thread is resolved from the tool input `threadId`, falling back to a\n * session `threadId` in the options. Provide at least one.\n */\nexport function createSendUpdateTool(\n clientOrOptions: RobotRock | CreateSendUpdateToolDurableOptions,\n maybeOptions: CreateSendUpdateToolOptions = {}\n) {\n const isDurable =\n typeof clientOrOptions === \"object\" &&\n clientOrOptions !== null &&\n \"mode\" in clientOrOptions &&\n (clientOrOptions.mode === \"trigger\" || clientOrOptions.mode === \"workflow\");\n\n const aiContext: RobotRockAiContext = normalizeRobotRockAiContext(\n isDurable\n ? {\n mode: (clientOrOptions as CreateSendUpdateToolDurableOptions).mode,\n app: (clientOrOptions as CreateSendUpdateToolDurableOptions).app,\n }\n : (clientOrOptions as RobotRock)\n );\n const options = isDurable\n ? (clientOrOptions as CreateSendUpdateToolDurableOptions)\n : maybeOptions;\n const description =\n options.description ??\n \"Post a short progress update to the RobotRock thread you are working on. Use to report status changes (running, succeeded, failed) so humans can follow along in the inbox.\";\n\n return tool({\n description,\n inputSchema: sendUpdateToolInputSchema,\n execute: async (\n input: z.infer<typeof sendUpdateToolInputSchema>\n ): Promise<SendUpdateToolResult> => {\n const threadId = input.threadId ?? options.threadId;\n if (!threadId) {\n throw new Error(\n \"createSendUpdateTool: no threadId. Pass `threadId` from a prior send-to-human result, or configure a session `threadId` in the tool options.\"\n );\n }\n\n try {\n const update = await sendUpdateForAi(aiContext, {\n threadId,\n message: input.message,\n status: input.status,\n });\n return { posted: true, threadId, update };\n } catch (error) {\n if (error instanceof RobotRockError && error.statusCode === 404) {\n return {\n posted: false,\n threadId,\n reason: \"thread_not_found\",\n message: `No task exists for thread \"${threadId}\" yet, so the update was not posted. Create a task on this thread with send-to-human before reporting progress.`,\n };\n }\n throw error;\n }\n },\n });\n}\n\nexport { sendUpdateToolInputSchema };\n","import type { RobotRock, SendToHumanActionInput } from \"../client.js\";\nimport type {\n RobotRockAiContext,\n RobotRockAiTriggerContext,\n RobotRockAiWorkflowContext,\n} from \"./context.js\";\nimport { normalizeRobotRockAiContext } from \"./context.js\";\nimport { approveByHumanTool as buildApproveByHumanTool } from \"./approve-by-human-tool.js\";\nimport {\n createSendToHumanTool as buildSendToHumanTool,\n type CreateSendToHumanToolOptions,\n} from \"./create-send-to-human-tool.js\";\nimport {\n createSendUpdateTool as buildSendUpdateTool,\n type CreateSendUpdateToolOptions,\n} from \"./create-send-update-tool.js\";\nimport type { ApproveByHumanToolOptions } from \"./approve-by-human-tool.js\";\n\nexport type CreateRobotRockAiToolsOptions = {\n /** @default \"polling\" when `client` is passed; `\"trigger\"` or `\"workflow\"` for durable waits. */\n mode?: \"polling\" | \"trigger\" | \"workflow\";\n client?: RobotRock;\n app?: string;\n /**\n * Shared thread for tasks and updates these tools create. Enables the\n * `sendUpdate` tool to auto-thread onto tasks made by the `sendToHuman` tool.\n */\n threadId?: string;\n};\n\n/**\n * Build AI SDK tools for a given RobotRock execution mode.\n *\n * @example Polling (Next.js route, scripts)\n * ```ts\n * const tools = createRobotRockAiTools({ client: robotrock });\n * ```\n *\n * @example Trigger.dev worker\n * ```ts\n * const tools = createRobotRockAiTools({ mode: \"trigger\", app: \"my-agent\" });\n * ```\n *\n * @example Vercel Workflow + DurableAgent\n * ```ts\n * const tools = createRobotRockAiTools({ mode: \"workflow\", app: \"my-agent\" });\n * ```\n */\nexport function createRobotRockAiTools(options: CreateRobotRockAiToolsOptions) {\n const mode = options.mode ?? (options.client ? \"polling\" : \"trigger\");\n\n if (mode === \"polling\" && !options.client) {\n throw new Error('createRobotRockAiTools: polling mode requires `client`.');\n }\n\n const context: RobotRockAiContext =\n mode === \"trigger\"\n ? { mode: \"trigger\", app: options.app }\n : mode === \"workflow\"\n ? { mode: \"workflow\", app: options.app }\n : { mode: \"polling\", client: options.client! };\n\n const durableContext =\n context.mode === \"trigger\" || context.mode === \"workflow\" ? context : null;\n const pollingClient = context.mode === \"polling\" ? context.client : undefined;\n\n return {\n context,\n approveByHuman: (toolOptions?: ApproveByHumanToolOptions) =>\n durableContext\n ? buildApproveByHumanTool({ ...durableContext, ...toolOptions })\n : buildApproveByHumanTool(pollingClient!, toolOptions),\n sendToHuman: <A extends readonly SendToHumanActionInput[]>(\n toolOptions: CreateSendToHumanToolOptions<A>\n ) =>\n durableContext\n ? buildSendToHumanTool({\n ...durableContext,\n ...(options.threadId ? { threadId: options.threadId } : {}),\n ...toolOptions,\n })\n : buildSendToHumanTool(pollingClient!, {\n ...(options.threadId ? { threadId: options.threadId } : {}),\n ...toolOptions,\n }),\n sendUpdate: (toolOptions: CreateSendUpdateToolOptions = {}) =>\n durableContext\n ? buildSendUpdateTool({\n ...durableContext,\n ...(options.threadId ? { threadId: options.threadId } : {}),\n ...toolOptions,\n })\n : buildSendUpdateTool(pollingClient!, {\n ...(options.threadId ? { threadId: options.threadId } : {}),\n ...toolOptions,\n }),\n };\n}\n\n/** Shorthand for `{ mode: \"trigger\", app }`. */\nexport function createRobotRockAiTriggerContext(\n options: Omit<RobotRockAiTriggerContext, \"mode\"> = {}\n): RobotRockAiContext {\n return { mode: \"trigger\", ...options };\n}\n\n/** Shorthand for `{ mode: \"workflow\", app }`. */\nexport function createRobotRockAiWorkflowContext(\n options: Omit<RobotRockAiWorkflowContext, \"mode\"> = {}\n): RobotRockAiContext {\n return { mode: \"workflow\", ...options };\n}\n\nexport { normalizeRobotRockAiContext };\n","import type { SendToHumanInput } from \"../client.js\";\nimport type { FormatToolApprovalTaskOptions, RobotRockToolCallInfo } from \"./types.js\";\n\nconst DEFAULT_APPROVE_ACTIONS = [\n { id: \"approve\", title: \"Approve execution\" },\n { id: \"deny\", title: \"Deny\" },\n] as const;\n\n/**\n * Build a RobotRock task payload for an AI SDK tool approval request.\n */\nexport function defaultFormatToolApprovalTask(\n toolCall: RobotRockToolCallInfo,\n options: FormatToolApprovalTaskOptions = {}\n): SendToHumanInput {\n const approveId = options.approveActionId ?? \"approve\";\n const denyId = options.denyActionId ?? \"deny\";\n\n let inputPreview: string;\n try {\n inputPreview = JSON.stringify(toolCall.input, null, 2);\n } catch {\n inputPreview = String(toolCall.input);\n }\n\n return {\n type: options.type ?? \"ai-tool-approval\",\n name: `Approve: ${toolCall.toolName}`,\n description: `Review the proposed \\`${toolCall.toolName}\\` tool call before it runs.`,\n context: {\n data: {\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n input: toolCall.input,\n },\n ui: {\n toolName: { \"ui:widget\": \"text\" },\n toolCallId: { \"ui:widget\": \"text\" },\n input: { \"ui:widget\": \"textarea\" },\n },\n },\n actions: [\n { id: approveId, title: \"Approve execution\" },\n { id: denyId, title: \"Deny\" },\n ],\n };\n}\n\nexport { DEFAULT_APPROVE_ACTIONS };\n","import type { ToolApprovalResponse } from \"ai\";\nimport type { RobotRock } from \"../client.js\";\nimport {\n normalizeRobotRockAiContext,\n sendToHumanForAi,\n type RobotRockAiContext,\n} from \"./context.js\";\nimport { defaultFormatToolApprovalTask } from \"./format-tool-approval-task.js\";\nimport type {\n ResolveToolApprovalsOptions,\n RobotRockToolApprovalConfig,\n RobotRockToolCallInfo,\n RunWithRobotRockApprovalsOptions,\n ToolApprovalRequestPart,\n} from \"./types.js\";\n\nexport type RobotRockToolApprovalDecision = \"user-approval\" | undefined;\n\nfunction buildToolMatcher(config: RobotRockToolApprovalConfig) {\n const names = config.tools ? new Set(config.tools) : null;\n\n return (toolCall: RobotRockToolCallInfo): boolean => {\n if (config.when?.(toolCall)) {\n return true;\n }\n if (names && names.has(toolCall.toolName)) {\n return true;\n }\n return false;\n };\n}\n\n/**\n * AI SDK 7+: pass the return value to `toolApproval` on `generateText`, `streamText`, or `ToolLoopAgent`.\n * Returns `'user-approval'` for configured tools so execution pauses until a human responds via RobotRock.\n */\nexport function createRobotRockToolApproval(config: RobotRockToolApprovalConfig) {\n const matches = buildToolMatcher(config);\n\n const toolApproval = async (options: {\n toolCall: RobotRockToolCallInfo;\n }): Promise<RobotRockToolApprovalDecision> => {\n return matches(options.toolCall) ? \"user-approval\" : undefined;\n };\n\n return toolApproval;\n}\n\n/**\n * AI SDK 5–6: use as `needsApproval` on tool definitions (or via {@link applyRobotRockToolApprovalToTools}).\n */\nexport function createRobotRockNeedsApproval(config: RobotRockToolApprovalConfig) {\n const matches = buildToolMatcher(config);\n\n return async (\n _input: unknown,\n options: { toolCallId: string; messages?: unknown[] }\n ): Promise<boolean> => {\n const toolCall = findToolCallInMessages(options.messages, options.toolCallId);\n if (!toolCall) {\n return false;\n }\n return matches(toolCall);\n };\n}\n\n/**\n * AI SDK 5–6: merge `needsApproval` into each matching tool in a tools object.\n */\nexport function applyRobotRockToolApprovalToTools<T extends Record<string, object>>(\n tools: T,\n config: RobotRockToolApprovalConfig\n): T {\n const names = config.tools ? new Set(config.tools) : null;\n const needsApproval = createRobotRockNeedsApproval(config);\n\n const next = { ...tools } as T;\n\n for (const key of Object.keys(tools) as Array<keyof T>) {\n const name = String(key);\n const shouldApply =\n (names && names.has(name)) || (names === null && config.when !== undefined);\n\n if (!shouldApply) {\n continue;\n }\n\n const existing = tools[key];\n next[key] = {\n ...existing,\n needsApproval,\n } as T[keyof T];\n }\n\n return next;\n}\n\nfunction findToolCallInMessages(\n messages: unknown[] | undefined,\n toolCallId: string\n): RobotRockToolCallInfo | undefined {\n if (!messages) {\n return undefined;\n }\n\n for (const message of messages) {\n if (typeof message !== \"object\" || message === null) {\n continue;\n }\n const role = (message as { role?: string }).role;\n if (role !== \"assistant\") {\n continue;\n }\n const content = (message as { content?: unknown }).content;\n if (!Array.isArray(content)) {\n continue;\n }\n\n for (const part of content) {\n if (typeof part !== \"object\" || part === null) {\n continue;\n }\n const p = part as Record<string, unknown>;\n if (p.type === \"tool-call\" && p.toolCallId === toolCallId) {\n return {\n toolName: String(p.toolName ?? \"\"),\n toolCallId,\n input: p.input,\n };\n }\n }\n }\n\n return undefined;\n}\n\nfunction collectApprovalRequests(source: unknown): ToolApprovalRequestPart[] {\n const requests: ToolApprovalRequestPart[] = [];\n\n const visit = (value: unknown) => {\n if (!value) {\n return;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n visit(item);\n }\n return;\n }\n\n if (typeof value !== \"object\") {\n return;\n }\n\n const obj = value as Record<string, unknown>;\n\n if (obj.type === \"tool-approval-request\" && typeof obj.approvalId === \"string\") {\n if (obj.isAutomatic === true) {\n return;\n }\n\n const embedded = obj.toolCall as Record<string, unknown> | undefined;\n const toolCallId =\n typeof obj.toolCallId === \"string\"\n ? obj.toolCallId\n : typeof embedded?.toolCallId === \"string\"\n ? embedded.toolCallId\n : undefined;\n\n let toolCall: RobotRockToolCallInfo | undefined;\n if (embedded && typeof embedded.toolName === \"string\") {\n toolCall = {\n toolName: embedded.toolName,\n toolCallId: String(embedded.toolCallId ?? toolCallId ?? \"\"),\n input: embedded.input,\n };\n } else if (toolCallId) {\n toolCall = findToolCallInMessages(\n (source as { messages?: unknown[] }).messages,\n toolCallId\n );\n }\n\n requests.push({\n type: \"tool-approval-request\",\n approvalId: obj.approvalId,\n toolCallId,\n toolCall,\n isAutomatic: obj.isAutomatic === true,\n });\n return;\n }\n\n if (Array.isArray(obj.content)) {\n visit(obj.content);\n }\n if (Array.isArray(obj.steps)) {\n visit(obj.steps);\n }\n if (obj.response && typeof obj.response === \"object\") {\n visit((obj.response as { messages?: unknown[] }).messages);\n }\n };\n\n visit(source);\n\n if (typeof source === \"object\" && source !== null && Array.isArray((source as { content?: unknown[] }).content)) {\n visit((source as { content: unknown[] }).content);\n }\n\n const seen = new Set<string>();\n return requests.filter((r) => {\n if (seen.has(r.approvalId)) {\n return false;\n }\n seen.add(r.approvalId);\n return true;\n });\n}\n\nfunction resolveToolCallForRequest(\n request: ToolApprovalRequestPart,\n source: unknown,\n messages: unknown[]\n): RobotRockToolCallInfo {\n if (request.toolCall) {\n return request.toolCall;\n }\n\n const toolCallId = request.toolCallId;\n if (toolCallId) {\n const fromMessages = findToolCallInMessages(messages, toolCallId);\n if (fromMessages) {\n return fromMessages;\n }\n }\n\n if (typeof source === \"object\" && source !== null && Array.isArray((source as { toolCalls?: unknown[] }).toolCalls)) {\n for (const call of (source as { toolCalls: Array<Record<string, unknown>> }).toolCalls) {\n if (call.toolCallId === toolCallId) {\n return {\n toolName: String(call.toolName ?? \"\"),\n toolCallId: String(call.toolCallId ?? \"\"),\n input: call.input,\n };\n }\n }\n }\n\n throw new Error(\n `Could not resolve tool call for approval ${request.approvalId}. Pass messages that include the assistant tool-call.`\n );\n}\n\n/**\n * Create RobotRock tasks for pending AI SDK tool approvals and return `tool-approval-response` parts.\n */\nexport async function resolveToolApprovalsViaRobotRock(\n clientOrContext: RobotRock | RobotRockAiContext,\n source: unknown,\n options: ResolveToolApprovalsOptions = {}\n): Promise<{\n responses: ToolApprovalResponse[];\n messages: unknown[];\n}> {\n const context = normalizeRobotRockAiContext(clientOrContext);\n const approveId = options.approveActionId ?? \"approve\";\n const denyId = options.denyActionId ?? \"deny\";\n const formatTask = options.formatTask ?? defaultFormatToolApprovalTask;\n\n const baseMessages =\n typeof source === \"object\" && source !== null && Array.isArray((source as { messages?: unknown[] }).messages)\n ? [...(source as { messages: unknown[] }).messages]\n : [];\n\n const requests = collectApprovalRequests(source);\n const responses: ToolApprovalResponse[] = [];\n\n for (const request of requests) {\n const toolCall = resolveToolCallForRequest(request, source, baseMessages);\n const taskInput = formatTask(toolCall, {\n approveActionId: approveId,\n denyActionId: denyId,\n });\n\n const result = await sendToHumanForAi(context, taskInput);\n\n const approved = result.actionId === approveId;\n const reason =\n typeof result.data === \"object\" &&\n result.data !== null &&\n \"reason\" in result.data &&\n typeof (result.data as { reason?: unknown }).reason === \"string\"\n ? (result.data as { reason: string }).reason\n : approved\n ? \"Approved in RobotRock inbox\"\n : \"Denied in RobotRock inbox\";\n\n responses.push({\n type: \"tool-approval-response\",\n approvalId: request.approvalId,\n approved,\n reason,\n });\n }\n\n const messages = [...baseMessages];\n if (responses.length > 0) {\n messages.push({ role: \"tool\", content: responses });\n }\n\n return { responses, messages };\n}\n\n/**\n * Run `generate` in a loop until manual tool approvals are resolved via RobotRock or `maxRounds` is reached.\n */\nexport async function runWithRobotRockApprovals<T>(\n options: RunWithRobotRockApprovalsOptions<T>\n): Promise<T> {\n const clientOrContext =\n options.context ??\n (options.client\n ? options.client\n : (() => {\n throw new Error(\"runWithRobotRockApprovals requires `client` or `context`.\");\n })());\n\n const maxRounds = options.maxRounds ?? 20;\n let messages = options.messages ? [...options.messages] : [];\n let lastResult: T | undefined;\n\n for (let round = 0; round < maxRounds; round++) {\n lastResult = await options.generate(messages);\n const { responses, messages: nextMessages } = await resolveToolApprovalsViaRobotRock(\n clientOrContext,\n { ...(lastResult as object), messages },\n options.resolveOptions\n );\n\n if (responses.length === 0) {\n return lastResult;\n }\n\n messages = nextMessages;\n }\n\n throw new Error(`RobotRock approval loop exceeded maxRounds (${maxRounds})`);\n}\n\nexport { collectApprovalRequests };\n"],"mappings":";;;;;;;;;;;;AASA,IAAM,2BAA2B;AAAA,EAC/B,EAAE,IAAI,WAAW,OAAO,UAAU;AAAA,EAClC,EAAE,IAAI,WAAW,OAAO,UAAU;AACpC;AAgCO,SAAS,kBAAkB,OAAoC;AACpE,SACE,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB,SACjB,OAAQ,MAAoB,gBAAgB;AAEhD;AAEO,SAAS,4BACd,iBACoB;AACpB,MAAI,kBAAkB,eAAe,GAAG;AACtC,WAAO,EAAE,MAAM,WAAW,QAAQ,gBAAgB;AAAA,EACpD;AAEA,MAAI,gBAAgB,SAAS,aAAa,gBAAgB,SAAS,YAAY;AAC7E,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,SAAS,aAAa,gBAAgB,SAAS,QAAW;AAC5E,QAAI,EAAE,YAAY,oBAAoB,CAAC,gBAAgB,QAAQ;AAC7D,YAAM,IAAI,MAAM,oEAAoE;AAAA,IACtF;AACA,WAAO,EAAE,MAAM,WAAW,QAAQ,gBAAgB,OAAO;AAAA,EAC3D;AAEA,QAAM,IAAI,MAAM,8BAA8B,OAAQ,gBAAsC,IAAI,CAAC,EAAE;AACrG;AAEA,eAAsB,iBAGpB,SACA,SACyC;AACzC,MAAI,QAAQ,SAAS,WAAW;AAC9B,UAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,qBAAqB;AAC9D,UAAM,aAAa,MAAM,gBAAgB,eAAe;AAAA,MACtD,GAAG;AAAA,MACH,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,WAAW,IAAI;AAClB,YAAM,WAAW;AAAA,IACnB;AAEA,WAAO,WAAW;AAAA,EACpB;AAEA,MAAI,QAAQ,SAAS,YAAY;AAC/B,UAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,sBAAsB;AACrE,UAAMA,UAAS,MAAM,sBAAsB;AAAA,MACzC,GAAG;AAAA,MACH,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC5C,CAAC;AACD,WAAOA;AAAA,EACT;AAEA,QAAM,SAAS,MAAM,QAAQ,OAAO,YAAY,OAAO;AAEvD,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,MAAM,OAAO;AAAA,IACb,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO;AAAA,IAClB,QAAQ,OAAO;AAAA,EACjB;AACF;AASA,eAAsB,gBACpB,SACA,SACuB;AACvB,MAAI,QAAQ,SAAS,YAAY;AAC/B,UAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sBAAsB;AACpE,WAAO,qBAAqB;AAAA,MAC1B,GAAG;AAAA,MACH,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,SAAS,WAAW;AAC9B,UAAM,SAAS;AAAA,MACb,uBAAuB,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,MAAS;AAAA,IACvE;AACA,WAAO,OAAO,WAAW,OAAO;AAAA,EAClC;AAEA,SAAO,QAAQ,OAAO,WAAW,OAAO;AAC1C;AAEA,eAAsB,oBACpB,SACA,SACuE;AACvE,MAAI,QAAQ,SAAS,WAAW;AAC9B,UAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,qBAAqB;AACjE,UAAM,aAAa,MAAM,mBAAmB,eAAe;AAAA,MACzD,GAAG;AAAA,MACH,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC5C,CAAC;AAED,QAAI,CAAC,WAAW,IAAI;AAClB,YAAM,WAAW;AAAA,IACnB;AAEA,WAAO,WAAW;AAAA,EACpB;AAEA,MAAI,QAAQ,SAAS,YAAY;AAC/B,UAAM,EAAE,yBAAyB,IAAI,MAAM,OAAO,sBAAsB;AACxE,WAAO,MAAM,yBAAyB;AAAA,MACpC,GAAG;AAAA,MACH,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,MAAM,QAAQ,OAAO,YAAY;AAAA,IAC9C,GAAG;AAAA,IACH,SAAS;AAAA,EACX,CAAC;AAED,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,MAAM,OAAO;AAAA,IACb,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO;AAAA,IAClB,QAAQ,OAAO;AAAA,EACjB;AACF;;;AC9LA,IAAM,cAAc,oBAAI,IAAI,CAAC,WAAW,UAAU,CAAC;AACnD,IAAM,cAAc,oBAAI,IAAI,CAAC,WAAW,UAAU,QAAQ,QAAQ,CAAC;AAE5D,SAAS,kBACd,QACiB;AACjB,QAAM,UAA2B;AAAA,IAC/B,QAAQ,OAAO;AAAA,IACf,UAAU,OAAO;AAAA,IACjB,MAAM,OAAO;AAAA,IACb,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO,UAAU,YAAY;AAAA,EAC1C;AAEA,MAAI,YAAY,IAAI,OAAO,QAAQ,GAAG;AACpC,YAAQ,WAAW;AAAA,EACrB,WAAW,YAAY,IAAI,OAAO,QAAQ,GAAG;AAC3C,YAAQ,WAAW;AAAA,EACrB;AAEA,SAAO;AACT;;;ACxBA,SAAS,YAAY;AAOrB,IAAMC,4BAA2B;AAAA,EAC/B,EAAE,IAAI,WAAW,OAAO,UAAU;AAAA,EAClC,EAAE,IAAI,WAAW,OAAO,UAAU;AACpC;AAEA,IAAM,4BAA4B,iBAAE,OAAO;AAAA,EACzC,MAAM,iBACH,OAAO,EACP,SAAS,EACT,SAAS,yCAAyC;AAAA,EACrD,MAAM,iBAAE,OAAO,EAAE,SAAS,sCAAsC;AAAA,EAChE,aAAa,iBACV,OAAO,EACP,SAAS,oEAAoE;AAAA,EAChF,gBAAgB,iBACb,OAAO,EACP,SAAS,EACT,SAAS,iDAAiD;AAC/D,CAAC;AAkBM,SAAS,mBACd,iBACA,eAA0C,CAAC,GAC3C;AACA,QAAM,YACJ,OAAO,oBAAoB,YAC3B,oBAAoB,QACpB,UAAU,oBACT,gBAAgB,SAAS,aAAa,gBAAgB,SAAS;AAElE,QAAM,YAAY;AAAA,IAChB,YACI;AAAA,MACE,MAAO,gBAAqD;AAAA,MAC5D,KAAM,gBAAqD;AAAA,IAC7D,IACC;AAAA,EACP;AACA,QAAM,UAAU,YACX,kBACD;AACJ,QAAM,cACJ,QAAQ,eACR;AAEF,SAAO,KAAK;AAAA,IACV;AAAA,IACA,aAAa;AAAA,IACb,SAAS,OAAO,UAA+E;AAC7F,YAAM,cACJ,MAAM,mBAAmB,SACrB;AAAA,QACE,MAAM,EAAE,SAAS,MAAM,eAAe;AAAA,QACtC,IAAI;AAAA,UACF,SAAS,EAAE,aAAa,YAAY,cAAc,EAAE,MAAM,EAAE,EAAE;AAAA,QAChE;AAAA,MACF,IACA;AAEN,YAAM,SAAS,MAAM,oBAAoB,WAAW;AAAA,QAClD,MAAM,MAAM,QAAQ,QAAQ,eAAe;AAAA,QAC3C,MAAM,MAAM;AAAA,QACZ,aAAa,MAAM;AAAA,QACnB,SAAS;AAAA,MACX,CAAC;AAED,aAAO,kBAAkB,MAAM;AAAA,IACjC;AAAA,EACF,CAAC;AACH;;;AC5FA,SAAS,QAAAC,aAAY;AAarB,IAAM,qBAAqB,iBACxB,OAAO;AAAA,EACN,MAAM,iBAAE,OAAO,iBAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACrC,IAAI,iBAAE,OAAO,iBAAE,QAAQ,CAAC,EAAE,SAAS;AACrC,CAAC,EACA,SAAS;AAEZ,IAAM,6BAA6B,iBAAE,OAAO;AAAA,EAC1C,MAAM,iBAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,EACvE,MAAM,iBAAE,OAAO,EAAE,SAAS,oCAAoC;AAAA,EAC9D,aAAa,iBACV,OAAO,EACP,SAAS,EACT,SAAS,+DAA+D;AAAA,EAC3E,SAAS,mBAAmB,SAAS,8CAA8C;AAAA,EACnF,YAAY,iBACT,OAAO,EACP,SAAS,EACT,SAAS,EACT,SAAS,oCAAoC;AAAA,EAChD,UAAU,eACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AA2BM,SAAS,sBAGd,iBACA,cACA;AACA,QAAM,YACJ,OAAO,oBAAoB,YAC3B,oBAAoB,QACpB,UAAU,oBACT,gBAAgB,SAAS,aAAa,gBAAgB,SAAS;AAElE,QAAM,YAAY;AAAA,IAChB,YACI;AAAA,MACE,MAAO,gBAA2D;AAAA,MAClE,KAAM,gBAA2D;AAAA,IACnE,IACC;AAAA,EACP;AACA,QAAM,UAAW,YAAY,kBAAkB;AAC/C,QAAM,cACJ,QAAQ,eACR;AAEF,SAAOC,MAAK;AAAA,IACV;AAAA,IACA,aAAa;AAAA,IACb,SAAS,OACP,UAC6B;AAC7B,YAAM,cAAuD,MAAM,UAC9D;AAAA,QACC,MAAM,MAAM,QAAQ,QAAQ,CAAC;AAAA,QAC7B,IAAI,MAAM,QAAQ;AAAA,MACpB,IACA;AAEJ,YAAM,UAA+B;AAAA,QACnC,MAAM,MAAM,QAAQ,QAAQ,eAAe;AAAA,QAC3C,MAAM,MAAM;AAAA,QACZ,aAAa,MAAM;AAAA,QACnB,SAAS;AAAA,QACT,YAAY,MAAM;AAAA,QAClB,UAAU,MAAM;AAAA,QAChB,SAAS,QAAQ;AAAA,QACjB,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MAC3D;AAEA,YAAM,SAAS,MAAM,iBAAiB,WAAW,OAAO;AAExD,aAAO,kBAAkB,MAAM;AAAA,IACjC;AAAA,EACF,CAAC;AACH;;;ACvHA,SAAS,QAAAC,aAAY;AA4BrB,IAAM,4BAA4B,iBAAE,OAAO;AAAA,EACzC,UAAU,iBACP,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,SAAS,iBACN,OAAO,EACP,SAAS,qEAAqE;AAAA,EACjF,QAAQ,yBACL,SAAS,EACT;AAAA,IACC;AAAA,EACF;AACJ,CAAC;AA2BM,SAAS,qBACd,iBACA,eAA4C,CAAC,GAC7C;AACA,QAAM,YACJ,OAAO,oBAAoB,YAC3B,oBAAoB,QACpB,UAAU,oBACT,gBAAgB,SAAS,aAAa,gBAAgB,SAAS;AAElE,QAAM,YAAgC;AAAA,IACpC,YACI;AAAA,MACE,MAAO,gBAAuD;AAAA,MAC9D,KAAM,gBAAuD;AAAA,IAC/D,IACC;AAAA,EACP;AACA,QAAM,UAAU,YACX,kBACD;AACJ,QAAM,cACJ,QAAQ,eACR;AAEF,SAAOC,MAAK;AAAA,IACV;AAAA,IACA,aAAa;AAAA,IACb,SAAS,OACP,UACkC;AAClC,YAAM,WAAW,MAAM,YAAY,QAAQ;AAC3C,UAAI,CAAC,UAAU;AACb,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,gBAAgB,WAAW;AAAA,UAC9C;AAAA,UACA,SAAS,MAAM;AAAA,UACf,QAAQ,MAAM;AAAA,QAChB,CAAC;AACD,eAAO,EAAE,QAAQ,MAAM,UAAU,OAAO;AAAA,MAC1C,SAAS,OAAO;AACd,YAAI,iBAAiB,kBAAkB,MAAM,eAAe,KAAK;AAC/D,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR;AAAA,YACA,QAAQ;AAAA,YACR,SAAS,8BAA8B,QAAQ;AAAA,UACjD;AAAA,QACF;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AChFO,SAAS,uBAAuB,SAAwC;AAC7E,QAAM,OAAO,QAAQ,SAAS,QAAQ,SAAS,YAAY;AAE3D,MAAI,SAAS,aAAa,CAAC,QAAQ,QAAQ;AACzC,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAEA,QAAM,UACJ,SAAS,YACL,EAAE,MAAM,WAAW,KAAK,QAAQ,IAAI,IACpC,SAAS,aACP,EAAE,MAAM,YAAY,KAAK,QAAQ,IAAI,IACrC,EAAE,MAAM,WAAW,QAAQ,QAAQ,OAAQ;AAEnD,QAAM,iBACJ,QAAQ,SAAS,aAAa,QAAQ,SAAS,aAAa,UAAU;AACxE,QAAM,gBAAgB,QAAQ,SAAS,YAAY,QAAQ,SAAS;AAEpE,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,CAAC,gBACf,iBACI,mBAAwB,EAAE,GAAG,gBAAgB,GAAG,YAAY,CAAC,IAC7D,mBAAwB,eAAgB,WAAW;AAAA,IACzD,aAAa,CACX,gBAEA,iBACI,sBAAqB;AAAA,MACnB,GAAG;AAAA,MACH,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACzD,GAAG;AAAA,IACL,CAAC,IACD,sBAAqB,eAAgB;AAAA,MACnC,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACzD,GAAG;AAAA,IACL,CAAC;AAAA,IACP,YAAY,CAAC,cAA2C,CAAC,MACvD,iBACI,qBAAoB;AAAA,MAClB,GAAG;AAAA,MACH,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACzD,GAAG;AAAA,IACL,CAAC,IACD,qBAAoB,eAAgB;AAAA,MAClC,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACzD,GAAG;AAAA,IACL,CAAC;AAAA,EACT;AACF;AAGO,SAAS,gCACd,UAAmD,CAAC,GAChC;AACpB,SAAO,EAAE,MAAM,WAAW,GAAG,QAAQ;AACvC;AAGO,SAAS,iCACd,UAAoD,CAAC,GACjC;AACpB,SAAO,EAAE,MAAM,YAAY,GAAG,QAAQ;AACxC;;;AC5GA,IAAM,0BAA0B;AAAA,EAC9B,EAAE,IAAI,WAAW,OAAO,oBAAoB;AAAA,EAC5C,EAAE,IAAI,QAAQ,OAAO,OAAO;AAC9B;AAKO,SAAS,8BACd,UACA,UAAyC,CAAC,GACxB;AAClB,QAAM,YAAY,QAAQ,mBAAmB;AAC7C,QAAM,SAAS,QAAQ,gBAAgB;AAEvC,MAAI;AACJ,MAAI;AACF,mBAAe,KAAK,UAAU,SAAS,OAAO,MAAM,CAAC;AAAA,EACvD,QAAQ;AACN,mBAAe,OAAO,SAAS,KAAK;AAAA,EACtC;AAEA,SAAO;AAAA,IACL,MAAM,QAAQ,QAAQ;AAAA,IACtB,MAAM,YAAY,SAAS,QAAQ;AAAA,IACnC,aAAa,yBAAyB,SAAS,QAAQ;AAAA,IACvD,SAAS;AAAA,MACP,MAAM;AAAA,QACJ,UAAU,SAAS;AAAA,QACnB,YAAY,SAAS;AAAA,QACrB,OAAO,SAAS;AAAA,MAClB;AAAA,MACA,IAAI;AAAA,QACF,UAAU,EAAE,aAAa,OAAO;AAAA,QAChC,YAAY,EAAE,aAAa,OAAO;AAAA,QAClC,OAAO,EAAE,aAAa,WAAW;AAAA,MACnC;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,EAAE,IAAI,WAAW,OAAO,oBAAoB;AAAA,MAC5C,EAAE,IAAI,QAAQ,OAAO,OAAO;AAAA,IAC9B;AAAA,EACF;AACF;;;AC5BA,SAAS,iBAAiB,QAAqC;AAC7D,QAAM,QAAQ,OAAO,QAAQ,IAAI,IAAI,OAAO,KAAK,IAAI;AAErD,SAAO,CAAC,aAA6C;AACnD,QAAI,OAAO,OAAO,QAAQ,GAAG;AAC3B,aAAO;AAAA,IACT;AACA,QAAI,SAAS,MAAM,IAAI,SAAS,QAAQ,GAAG;AACzC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;AAMO,SAAS,4BAA4B,QAAqC;AAC/E,QAAM,UAAU,iBAAiB,MAAM;AAEvC,QAAM,eAAe,OAAO,YAEkB;AAC5C,WAAO,QAAQ,QAAQ,QAAQ,IAAI,kBAAkB;AAAA,EACvD;AAEA,SAAO;AACT;AAKO,SAAS,6BAA6B,QAAqC;AAChF,QAAM,UAAU,iBAAiB,MAAM;AAEvC,SAAO,OACL,QACA,YACqB;AACrB,UAAM,WAAW,uBAAuB,QAAQ,UAAU,QAAQ,UAAU;AAC5E,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,QAAQ;AAAA,EACzB;AACF;AAKO,SAAS,kCACd,OACA,QACG;AACH,QAAM,QAAQ,OAAO,QAAQ,IAAI,IAAI,OAAO,KAAK,IAAI;AACrD,QAAM,gBAAgB,6BAA6B,MAAM;AAEzD,QAAM,OAAO,EAAE,GAAG,MAAM;AAExB,aAAW,OAAO,OAAO,KAAK,KAAK,GAAqB;AACtD,UAAM,OAAO,OAAO,GAAG;AACvB,UAAM,cACH,SAAS,MAAM,IAAI,IAAI,KAAO,UAAU,QAAQ,OAAO,SAAS;AAEnE,QAAI,CAAC,aAAa;AAChB;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,GAAG;AAC1B,SAAK,GAAG,IAAI;AAAA,MACV,GAAG;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBACP,UACA,YACmC;AACnC,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,aAAW,WAAW,UAAU;AAC9B,QAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AACnD;AAAA,IACF;AACA,UAAM,OAAQ,QAA8B;AAC5C,QAAI,SAAS,aAAa;AACxB;AAAA,IACF;AACA,UAAM,UAAW,QAAkC;AACnD,QAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B;AAAA,IACF;AAEA,eAAW,QAAQ,SAAS;AAC1B,UAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C;AAAA,MACF;AACA,YAAM,IAAI;AACV,UAAI,EAAE,SAAS,eAAe,EAAE,eAAe,YAAY;AACzD,eAAO;AAAA,UACL,UAAU,OAAO,EAAE,YAAY,EAAE;AAAA,UACjC;AAAA,UACA,OAAO,EAAE;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,wBAAwB,QAA4C;AAC3E,QAAM,WAAsC,CAAC;AAE7C,QAAM,QAAQ,CAAC,UAAmB;AAChC,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,iBAAW,QAAQ,OAAO;AACxB,cAAM,IAAI;AAAA,MACZ;AACA;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,IACF;AAEA,UAAM,MAAM;AAEZ,QAAI,IAAI,SAAS,2BAA2B,OAAO,IAAI,eAAe,UAAU;AAC9E,UAAI,IAAI,gBAAgB,MAAM;AAC5B;AAAA,MACF;AAEA,YAAM,WAAW,IAAI;AACrB,YAAM,aACJ,OAAO,IAAI,eAAe,WACtB,IAAI,aACJ,OAAO,UAAU,eAAe,WAC9B,SAAS,aACT;AAER,UAAI;AACJ,UAAI,YAAY,OAAO,SAAS,aAAa,UAAU;AACrD,mBAAW;AAAA,UACT,UAAU,SAAS;AAAA,UACnB,YAAY,OAAO,SAAS,cAAc,cAAc,EAAE;AAAA,UAC1D,OAAO,SAAS;AAAA,QAClB;AAAA,MACF,WAAW,YAAY;AACrB,mBAAW;AAAA,UACR,OAAoC;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AAEA,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,YAAY,IAAI;AAAA,QAChB;AAAA,QACA;AAAA,QACA,aAAa,IAAI,gBAAgB;AAAA,MACnC,CAAC;AACD;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,IAAI,OAAO,GAAG;AAC9B,YAAM,IAAI,OAAO;AAAA,IACnB;AACA,QAAI,MAAM,QAAQ,IAAI,KAAK,GAAG;AAC5B,YAAM,IAAI,KAAK;AAAA,IACjB;AACA,QAAI,IAAI,YAAY,OAAO,IAAI,aAAa,UAAU;AACpD,YAAO,IAAI,SAAsC,QAAQ;AAAA,IAC3D;AAAA,EACF;AAEA,QAAM,MAAM;AAEZ,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAS,OAAmC,OAAO,GAAG;AAC/G,UAAO,OAAkC,OAAO;AAAA,EAClD;AAEA,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,SAAS,OAAO,CAAC,MAAM;AAC5B,QAAI,KAAK,IAAI,EAAE,UAAU,GAAG;AAC1B,aAAO;AAAA,IACT;AACA,SAAK,IAAI,EAAE,UAAU;AACrB,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,0BACP,SACA,QACA,UACuB;AACvB,MAAI,QAAQ,UAAU;AACpB,WAAO,QAAQ;AAAA,EACjB;AAEA,QAAM,aAAa,QAAQ;AAC3B,MAAI,YAAY;AACd,UAAM,eAAe,uBAAuB,UAAU,UAAU;AAChE,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAS,OAAqC,SAAS,GAAG;AACnH,eAAW,QAAS,OAAyD,WAAW;AACtF,UAAI,KAAK,eAAe,YAAY;AAClC,eAAO;AAAA,UACL,UAAU,OAAO,KAAK,YAAY,EAAE;AAAA,UACpC,YAAY,OAAO,KAAK,cAAc,EAAE;AAAA,UACxC,OAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,4CAA4C,QAAQ,UAAU;AAAA,EAChE;AACF;AAKA,eAAsB,iCACpB,iBACA,QACA,UAAuC,CAAC,GAIvC;AACD,QAAM,UAAU,4BAA4B,eAAe;AAC3D,QAAM,YAAY,QAAQ,mBAAmB;AAC7C,QAAM,SAAS,QAAQ,gBAAgB;AACvC,QAAM,aAAa,QAAQ,cAAc;AAEzC,QAAM,eACJ,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAS,OAAoC,QAAQ,IACxG,CAAC,GAAI,OAAmC,QAAQ,IAChD,CAAC;AAEP,QAAM,WAAW,wBAAwB,MAAM;AAC/C,QAAM,YAAoC,CAAC;AAE3C,aAAW,WAAW,UAAU;AAC9B,UAAM,WAAW,0BAA0B,SAAS,QAAQ,YAAY;AACxE,UAAM,YAAY,WAAW,UAAU;AAAA,MACrC,iBAAiB;AAAA,MACjB,cAAc;AAAA,IAChB,CAAC;AAED,UAAM,SAAS,MAAM,iBAAiB,SAAS,SAAS;AAExD,UAAM,WAAW,OAAO,aAAa;AACrC,UAAM,SACJ,OAAO,OAAO,SAAS,YACvB,OAAO,SAAS,QAChB,YAAY,OAAO,QACnB,OAAQ,OAAO,KAA8B,WAAW,WACnD,OAAO,KAA4B,SACpC,WACE,gCACA;AAER,cAAU,KAAK;AAAA,MACb,MAAM;AAAA,MACN,YAAY,QAAQ;AAAA,MACpB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,CAAC,GAAG,YAAY;AACjC,MAAI,UAAU,SAAS,GAAG;AACxB,aAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,UAAU,CAAC;AAAA,EACpD;AAEA,SAAO,EAAE,WAAW,SAAS;AAC/B;AAKA,eAAsB,0BACpB,SACY;AACZ,QAAM,kBACJ,QAAQ,YACP,QAAQ,SACL,QAAQ,UACP,MAAM;AACL,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E,GAAG;AAET,QAAM,YAAY,QAAQ,aAAa;AACvC,MAAI,WAAW,QAAQ,WAAW,CAAC,GAAG,QAAQ,QAAQ,IAAI,CAAC;AAC3D,MAAI;AAEJ,WAAS,QAAQ,GAAG,QAAQ,WAAW,SAAS;AAC9C,iBAAa,MAAM,QAAQ,SAAS,QAAQ;AAC5C,UAAM,EAAE,WAAW,UAAU,aAAa,IAAI,MAAM;AAAA,MAClD;AAAA,MACA,EAAE,GAAI,YAAuB,SAAS;AAAA,MACtC,QAAQ;AAAA,IACV;AAEA,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO;AAAA,IACT;AAEA,eAAW;AAAA,EACb;AAEA,QAAM,IAAI,MAAM,+CAA+C,SAAS,GAAG;AAC7E;","names":["result","APPROVE_BY_HUMAN_ACTIONS","tool","tool","tool","tool"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createTaskBodySchema
|
|
3
|
-
|
|
2
|
+
createTaskBodySchema,
|
|
3
|
+
threadUpdateBodySchema
|
|
4
|
+
} from "./chunk-VNXWLPRV.mjs";
|
|
4
5
|
|
|
5
6
|
// src/approval-result.ts
|
|
6
7
|
var TaskTimeoutError = class extends Error {
|
|
@@ -109,7 +110,8 @@ var RobotRock = class {
|
|
|
109
110
|
const bodyPayload = {
|
|
110
111
|
...normalizedTask,
|
|
111
112
|
...task.assignTo !== void 0 ? { assignTo: task.assignTo } : {},
|
|
112
|
-
...task.threadId !== void 0 ? { threadId: task.threadId } : {}
|
|
113
|
+
...task.threadId !== void 0 ? { threadId: task.threadId } : {},
|
|
114
|
+
...task.update !== void 0 ? { update: task.update } : {}
|
|
113
115
|
};
|
|
114
116
|
const validation = createTaskBodySchema.safeParse(bodyPayload);
|
|
115
117
|
if (!validation.success) {
|
|
@@ -209,6 +211,43 @@ var RobotRock = class {
|
|
|
209
211
|
}
|
|
210
212
|
return data;
|
|
211
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Log a status update against a thread. The update shows in the inbox status
|
|
216
|
+
* bar and thread update log for every task in the thread.
|
|
217
|
+
*/
|
|
218
|
+
async sendUpdate({ threadId, message, status }) {
|
|
219
|
+
if (!threadId) {
|
|
220
|
+
throw new RobotRockError("threadId is required to send an update", 400);
|
|
221
|
+
}
|
|
222
|
+
const validation = threadUpdateBodySchema.safeParse({ message, status });
|
|
223
|
+
if (!validation.success) {
|
|
224
|
+
throw new RobotRockError(
|
|
225
|
+
`Invalid update: ${validation.error.errors[0]?.message}`,
|
|
226
|
+
400,
|
|
227
|
+
validation.error.errors
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
const response = await fetch(
|
|
231
|
+
`${this.baseUrl}/threads/${encodeURIComponent(threadId)}/updates`,
|
|
232
|
+
{
|
|
233
|
+
method: "POST",
|
|
234
|
+
headers: {
|
|
235
|
+
"Content-Type": "application/json",
|
|
236
|
+
"X-Api-Key": this.apiKey
|
|
237
|
+
},
|
|
238
|
+
body: JSON.stringify(validation.data)
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
const data = await parseResponseBody(response);
|
|
242
|
+
if (!response.ok) {
|
|
243
|
+
throw new RobotRockError(
|
|
244
|
+
getErrorMessage(data, "Failed to send update"),
|
|
245
|
+
response.status,
|
|
246
|
+
data
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
return data.update;
|
|
250
|
+
}
|
|
212
251
|
async cancelTask(taskId) {
|
|
213
252
|
const response = await fetch(`${this.baseUrl}/tasks/${taskId}/cancel`, {
|
|
214
253
|
method: "POST",
|
|
@@ -250,6 +289,7 @@ function normalizeSendToHumanInput(task, clientDefaults) {
|
|
|
250
289
|
idempotencyKey: _idempotencyKey,
|
|
251
290
|
assignTo: _assignTo,
|
|
252
291
|
threadId: _threadId,
|
|
292
|
+
update: _update,
|
|
253
293
|
validUntil,
|
|
254
294
|
app: taskApp,
|
|
255
295
|
...rest
|
|
@@ -329,4 +369,4 @@ export {
|
|
|
329
369
|
resolveRobotRockConfig,
|
|
330
370
|
resolveRobotRockClient
|
|
331
371
|
};
|
|
332
|
-
//# sourceMappingURL=chunk-
|
|
372
|
+
//# sourceMappingURL=chunk-E7ZWBFZ6.mjs.map
|