robotrock 1.3.2 → 1.3.4
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 +22 -0
- package/dist/ai/index.js +8 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/trigger.js +8 -0
- package/dist/ai/trigger.js.map +1 -1
- package/dist/ai/workflow.js +8 -0
- package/dist/ai/workflow.js.map +1 -1
- package/dist/eve/agent/index.d.ts +67 -3
- package/dist/eve/agent/index.js +209 -153
- package/dist/eve/agent/index.js.map +1 -1
- package/dist/eve/index.d.ts +2 -1
- package/dist/eve/index.js +62 -47
- package/dist/eve/index.js.map +1 -1
- package/dist/eve/tools/admin/assign-tasks.d.ts +15 -4
- package/dist/eve/tools/admin/assign-tasks.js +8 -43
- package/dist/eve/tools/admin/assign-tasks.js.map +1 -1
- package/dist/eve/tools/admin/manage-groups.d.ts +2 -3
- package/dist/eve/tools/admin/manage-groups.js +18 -71
- package/dist/eve/tools/admin/manage-groups.js.map +1 -1
- package/dist/eve/tools/admin/manage-team-members.d.ts +2 -3
- package/dist/eve/tools/admin/manage-team-members.js +20 -64
- package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
- package/dist/eve/tools/admin/query-tasks.d.ts +5 -6
- package/dist/eve/tools/admin/query-tasks.js +22 -86
- package/dist/eve/tools/admin/query-tasks.js.map +1 -1
- package/dist/eve/tools/catalog/search-products.d.ts +4 -5
- package/dist/eve/tools/catalog/search-products.js +2 -33
- package/dist/eve/tools/catalog/search-products.js.map +1 -1
- package/dist/eve/tools/identity/index.d.ts +0 -1
- package/dist/eve/tools/identity/index.js +15 -44
- package/dist/eve/tools/identity/index.js.map +1 -1
- package/dist/eve/tools/identity/my-access.d.ts +2 -3
- package/dist/eve/tools/identity/my-access.js +15 -44
- package/dist/eve/tools/identity/my-access.js.map +1 -1
- package/dist/eve/tools/identity/whoami.js.map +1 -1
- package/dist/eve/tools/inbox/create-task.js.map +1 -1
- package/dist/eve/tools/inbox/index.js.map +1 -1
- package/dist/eve/tools/index.d.ts +1 -1
- package/dist/eve/tools/index.js +44 -193
- package/dist/eve/tools/index.js.map +1 -1
- package/dist/{index-DePyAbTI.d.ts → index-Blq0XoAr.d.ts} +17 -16
- package/dist/index.d.ts +2 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/tool-ui-hint-CMpug5sC.d.ts +13 -0
- package/package.json +2 -2
|
@@ -7,13 +7,14 @@ import { TaskPriority } from '../../schemas/index.js';
|
|
|
7
7
|
import { HookDefinition } from 'eve/hooks';
|
|
8
8
|
export { AgentAdminApi, createAgentAdminApi, createBoundAgentAdminClient, requireBoundAgentAdminClient } from '../../agent-admin.js';
|
|
9
9
|
export { ROBOTROCK_PLATFORM_USER_CONTEXT_PUBLIC_KEY_URL } from '@robotrock/core/eve/platform-user-context-public-key';
|
|
10
|
-
export { R as ROBOTROCK_READY_HOOK_SLUG } from '../../index-
|
|
10
|
+
export { R as ROBOTROCK_READY_HOOK_SLUG } from '../../index-Blq0XoAr.js';
|
|
11
11
|
export { ROBOTROCK_USER_CONTEXT_AUDIENCE, ROBOTROCK_USER_CONTEXT_ISSUER } from '@robotrock/core/eve/user-context-jwt';
|
|
12
12
|
import '@robotrock/core';
|
|
13
13
|
import 'zod';
|
|
14
14
|
import '../../chat-correlation-BsHD-tOQ.js';
|
|
15
15
|
import '@robotrock/core/schemas';
|
|
16
16
|
import '../../tool-reply-guidance-C3qrT1In.js';
|
|
17
|
+
import '../../tool-ui-hint-CMpug5sC.js';
|
|
17
18
|
|
|
18
19
|
/** Header carrying the dashboard user-context JWT on proxied Eve requests. */
|
|
19
20
|
declare const ROBOTROCK_USER_CONTEXT_HEADER = "x-robotrock-user-token";
|
|
@@ -33,9 +34,72 @@ declare function robotrockUserContextAuth(options?: RobotrockUserContextAuthOpti
|
|
|
33
34
|
* (`GET /eve/v1/info` during verify and tenant connect).
|
|
34
35
|
*/
|
|
35
36
|
declare function robotrockAgentServiceAuth(): AuthFn<Request>;
|
|
36
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Bearer token for RobotRock platform reachability and dashboard proxy calls.
|
|
39
|
+
*
|
|
40
|
+
* When a workspace admin connects a protected single-tenant deployment, they
|
|
41
|
+
* enter a Bearer token in **Settings → Agents**. RobotRock stores it in
|
|
42
|
+
* WorkOS Vault and sends `Authorization: Bearer <token>` on:
|
|
43
|
+
*
|
|
44
|
+
* - `GET /eve/v1/info` and `GET /eve/v1/health` (connect / re-sync)
|
|
45
|
+
* - `POST /eve/v1/session` and `POST /eve/v1/session/:sessionId` (chat + resume)
|
|
46
|
+
* - `GET /eve/v1/session/:sessionId/stream` (chat streaming)
|
|
47
|
+
* - optional icon paths (`/favicon.ico`, `/icon.svg`, `/icon.png`)
|
|
48
|
+
*
|
|
49
|
+
* Set `EVE_SELF_AUTH_TOKEN` on the agent to the same value. Use
|
|
50
|
+
* `robotrockEveChannel()` so this authenticator is registered on the Eve channel.
|
|
51
|
+
*/
|
|
37
52
|
declare function eveSelfServiceAuth(): AuthFn<Request>;
|
|
38
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Eve HTTP routes RobotRock reaches when connecting, re-syncing, or proxying
|
|
56
|
+
* dashboard chat. Use these paths when smoke-testing a protected deployment.
|
|
57
|
+
*
|
|
58
|
+
* Self-hosted agents that require deployment access: set `EVE_SELF_AUTH_TOKEN` on
|
|
59
|
+
* the agent to the same value the workspace admin enters under **Settings →
|
|
60
|
+
* Agents → Deployment access → Bearer token**. RobotRock stores that token in
|
|
61
|
+
* WorkOS Vault and sends it as `Authorization: Bearer <token>` on every call
|
|
62
|
+
* below (plus `X-RobotRock-User-Token` during inbox chat).
|
|
63
|
+
*/
|
|
64
|
+
/** Routes RobotRock calls directly from the dashboard backend (connect / re-sync). */
|
|
65
|
+
declare const ROBOTROCK_EVE_CONNECT_ROUTES: {
|
|
66
|
+
/** Agent manifest + `robotrock-ready` hook detection. */
|
|
67
|
+
readonly info: {
|
|
68
|
+
readonly method: "GET";
|
|
69
|
+
readonly path: "/eve/v1/info";
|
|
70
|
+
};
|
|
71
|
+
/** Optional health probe (same auth as `/info` when the channel is protected). */
|
|
72
|
+
readonly health: {
|
|
73
|
+
readonly method: "GET";
|
|
74
|
+
readonly path: "/eve/v1/health";
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
/** Static assets RobotRock may HEAD/GET for the agent avatar in Settings. */
|
|
78
|
+
declare const ROBOTROCK_EVE_ICON_PATHS: readonly ["/favicon.ico", "/icon.svg", "/icon.png"];
|
|
79
|
+
/**
|
|
80
|
+
* Routes proxied through `/{tenant}/api/eve/{connectionId}/…` during inbox chat
|
|
81
|
+
* and task-handled resume. The Eve client issues these against the proxy host;
|
|
82
|
+
* the proxy forwards them to the deployment with vault credentials attached.
|
|
83
|
+
*/
|
|
84
|
+
declare const ROBOTROCK_EVE_CHAT_ROUTES: {
|
|
85
|
+
readonly createSession: {
|
|
86
|
+
readonly method: "POST";
|
|
87
|
+
readonly path: "/eve/v1/session";
|
|
88
|
+
};
|
|
89
|
+
readonly continueSession: {
|
|
90
|
+
readonly method: "POST";
|
|
91
|
+
readonly path: "/eve/v1/session/:sessionId";
|
|
92
|
+
};
|
|
93
|
+
readonly messageStream: {
|
|
94
|
+
readonly method: "GET";
|
|
95
|
+
readonly path: "/eve/v1/session/:sessionId/stream";
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
/** Env var on the Eve agent that must match the dashboard Bearer token. */
|
|
99
|
+
declare const EVE_SELF_AUTH_TOKEN_ENV_VAR = "EVE_SELF_AUTH_TOKEN";
|
|
100
|
+
/** All Eve route paths that should accept the dashboard Bearer token on protected deployments. */
|
|
101
|
+
declare const ROBOTROCK_EVE_BEARER_PROTECTED_PATHS: readonly ["/eve/v1/info", "/eve/v1/health", "/eve/v1/session", "/eve/v1/session/:sessionId", "/eve/v1/session/:sessionId/stream", "/favicon.ico", "/icon.svg", "/icon.png"];
|
|
102
|
+
|
|
39
103
|
/** Resolve the platform RS256 public key used to verify dashboard user-context JWTs. */
|
|
40
104
|
declare function resolvePlatformUserContextPublicKeyPem(): Promise<string | null>;
|
|
41
105
|
|
|
@@ -161,4 +225,4 @@ declare const robotrockChatAuditHook: HookDefinition;
|
|
|
161
225
|
/** Alias for agents that prefer a factory name. */
|
|
162
226
|
declare function defineRobotRockChatAuditHook(): HookDefinition;
|
|
163
227
|
|
|
164
|
-
export { type CreateRobotRockCronChatInput, type CreateRobotRockTaskInput, ROBOTROCK_USER_CONTEXT_HEADER, type RobotRockChatAuditPayload, type RobotRockTaskActionInput, type RobotRockTaskAssignToInput, type RobotRockTaskContextInput, type RobotRockTaskToolInput, type RobotrockEveChannelOptions, type RobotrockUserContextAuthOptions, buildRobotRockTaskPayload, createRobotRockCronChat, createRobotRockTask, defineRobotRockChatAuditHook, defineRobotRockReadyHook, eveSelfServiceAuth, fetchRobotRockStagedHitl, postRobotRockChatInputAudit, postRobotRockLinkChatTask, postRobotRockStageHitl, resetBoundClientAuthWarning, resetChatAuditWarnings, resetRobotrockChatAuditIdempotencyKeys, resolvePlatformUserContextPublicKeyPem, resolveTaskHandledWebhookUrl, robotrockAgentServiceAuth, robotrockChatAuditHook, robotrockEveChannel, robotrockReadyHook, robotrockUserContextAuth, tryCreateBoundRobotRockClient };
|
|
228
|
+
export { type CreateRobotRockCronChatInput, type CreateRobotRockTaskInput, EVE_SELF_AUTH_TOKEN_ENV_VAR, ROBOTROCK_EVE_BEARER_PROTECTED_PATHS, ROBOTROCK_EVE_CHAT_ROUTES, ROBOTROCK_EVE_CONNECT_ROUTES, ROBOTROCK_EVE_ICON_PATHS, ROBOTROCK_USER_CONTEXT_HEADER, type RobotRockChatAuditPayload, type RobotRockTaskActionInput, type RobotRockTaskAssignToInput, type RobotRockTaskContextInput, type RobotRockTaskToolInput, type RobotrockEveChannelOptions, type RobotrockUserContextAuthOptions, buildRobotRockTaskPayload, createRobotRockCronChat, createRobotRockTask, defineRobotRockChatAuditHook, defineRobotRockReadyHook, eveSelfServiceAuth, fetchRobotRockStagedHitl, postRobotRockChatInputAudit, postRobotRockLinkChatTask, postRobotRockStageHitl, resetBoundClientAuthWarning, resetChatAuditWarnings, resetRobotrockChatAuditIdempotencyKeys, resolvePlatformUserContextPublicKeyPem, resolveTaskHandledWebhookUrl, robotrockAgentServiceAuth, robotrockChatAuditHook, robotrockEveChannel, robotrockReadyHook, robotrockUserContextAuth, tryCreateBoundRobotRockClient };
|
package/dist/eve/agent/index.js
CHANGED
|
@@ -118,6 +118,158 @@ function verifyRobotRockPlatformUserContextJwt(args) {
|
|
|
118
118
|
// ../core/src/eve/platform-user-context-public-key.ts
|
|
119
119
|
var ROBOTROCK_PLATFORM_USER_CONTEXT_PUBLIC_KEY_URL = "https://app.robotrock.io/.well-known/robotrock-user-context-public-key";
|
|
120
120
|
|
|
121
|
+
// ../core/src/utils/decode-html-entities.ts
|
|
122
|
+
function decodeHtmlEntities(value) {
|
|
123
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/'/g, "'").replace(/&#(\d+);/g, (_, code) => String.fromCharCode(Number(code))).replace(
|
|
124
|
+
/&#x([0-9a-f]+);/gi,
|
|
125
|
+
(_, code) => String.fromCharCode(parseInt(code, 16))
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ../core/src/utils/safe-url.ts
|
|
130
|
+
var BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
131
|
+
"localhost",
|
|
132
|
+
"metadata.google.internal",
|
|
133
|
+
"metadata.goog"
|
|
134
|
+
]);
|
|
135
|
+
function normalizeHostname(hostname) {
|
|
136
|
+
return hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
137
|
+
}
|
|
138
|
+
function isBlockedIpv4(host) {
|
|
139
|
+
const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
|
|
140
|
+
if (!match) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const octets = match.slice(1, 5).map((part) => Number(part));
|
|
144
|
+
if (octets.some((octet) => Number.isNaN(octet) || octet < 0 || octet > 255)) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
const [a, b, _c, _d] = octets;
|
|
148
|
+
if (a === void 0 || b === void 0) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
if (a === 127 || a === 0) return true;
|
|
152
|
+
if (a === 10) return true;
|
|
153
|
+
if (a === 169 && b === 254) return true;
|
|
154
|
+
if (a === 192 && b === 168) return true;
|
|
155
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
156
|
+
if (a === 100 && b >= 64 && b <= 127) return true;
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
function ipv4FromNumericHost(host) {
|
|
160
|
+
if (/^\d+$/.test(host)) {
|
|
161
|
+
const num = Number(host);
|
|
162
|
+
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
const a = num >>> 24 & 255;
|
|
166
|
+
const b = num >>> 16 & 255;
|
|
167
|
+
const c = num >>> 8 & 255;
|
|
168
|
+
const d = num & 255;
|
|
169
|
+
return `${a}.${b}.${c}.${d}`;
|
|
170
|
+
}
|
|
171
|
+
const hexMatch = /^0x([0-9a-f]{1,8})$/i.exec(host);
|
|
172
|
+
if (hexMatch) {
|
|
173
|
+
const num = Number.parseInt(hexMatch[1], 16);
|
|
174
|
+
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
const a = num >>> 24 & 255;
|
|
178
|
+
const b = num >>> 16 & 255;
|
|
179
|
+
const c = num >>> 8 & 255;
|
|
180
|
+
const d = num & 255;
|
|
181
|
+
return `${a}.${b}.${c}.${d}`;
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
function isBlockedIpv4Mapped(host) {
|
|
186
|
+
const mappedDotted = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/i.exec(host);
|
|
187
|
+
if (mappedDotted) {
|
|
188
|
+
return isBlockedIpv4(mappedDotted[1]);
|
|
189
|
+
}
|
|
190
|
+
const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(host);
|
|
191
|
+
if (mappedHex) {
|
|
192
|
+
const high = Number.parseInt(mappedHex[1], 16);
|
|
193
|
+
const low = Number.parseInt(mappedHex[2], 16);
|
|
194
|
+
if (Number.isFinite(high) && Number.isFinite(low)) {
|
|
195
|
+
const a = high >> 8 & 255;
|
|
196
|
+
const b = high & 255;
|
|
197
|
+
const c = low >> 8 & 255;
|
|
198
|
+
const d = low & 255;
|
|
199
|
+
return isBlockedIpv4(`${a}.${b}.${c}.${d}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
function isBlockedIpv6(host) {
|
|
205
|
+
if (host === "::1" || host === "0:0:0:0:0:0:0:1") {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
if (host.startsWith("fc") || host.startsWith("fd")) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
if (host.startsWith("fe80:")) {
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
if (isBlockedIpv4Mapped(host)) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
function isBlockedHostname(hostname) {
|
|
220
|
+
const host = normalizeHostname(hostname);
|
|
221
|
+
if (!host) {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
if (BLOCKED_HOSTNAMES.has(host)) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
if (host.endsWith(".localhost") || host.endsWith(".local")) {
|
|
228
|
+
return true;
|
|
229
|
+
}
|
|
230
|
+
const numericIpv4 = ipv4FromNumericHost(host);
|
|
231
|
+
if (numericIpv4 && isBlockedIpv4(numericIpv4)) {
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
return isBlockedIpv4(host) || isBlockedIpv6(host);
|
|
235
|
+
}
|
|
236
|
+
function isLoopbackHandlerUrl(urlString) {
|
|
237
|
+
let url;
|
|
238
|
+
try {
|
|
239
|
+
url = new URL(urlString);
|
|
240
|
+
} catch {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
if (url.username || url.password) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
const host = url.hostname.toLowerCase();
|
|
250
|
+
return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]" || host.endsWith(".localhost");
|
|
251
|
+
}
|
|
252
|
+
function isAllowedHandlerUrl(urlString) {
|
|
253
|
+
return isPublicHttpUrl(urlString) || isLoopbackHandlerUrl(urlString);
|
|
254
|
+
}
|
|
255
|
+
function isPublicHttpUrl(urlString) {
|
|
256
|
+
let url;
|
|
257
|
+
try {
|
|
258
|
+
url = new URL(urlString);
|
|
259
|
+
} catch {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
if (url.username || url.password) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
return !isBlockedHostname(url.hostname);
|
|
269
|
+
}
|
|
270
|
+
var PUBLIC_HTTP_URL_ERROR = "URL must be a public http:// or https:// address";
|
|
271
|
+
var HANDLER_URL_ERROR = "Handler URL must be a public or loopback http:// or https:// address";
|
|
272
|
+
|
|
121
273
|
// src/eve/input-request.ts
|
|
122
274
|
var EVE_INPUT_SUBMIT_ACTION_ID = "submit";
|
|
123
275
|
var EVE_INPUT_OTHER_CHOICE_ID = "__other__";
|
|
@@ -127,6 +279,9 @@ var CONFIRMATION_DEFAULT_OPTIONS = [
|
|
|
127
279
|
{ id: "deny", label: "Deny", style: "danger" }
|
|
128
280
|
];
|
|
129
281
|
var SELECT_PER_OPTION_THRESHOLD = 6;
|
|
282
|
+
function decodeDisplayText(value) {
|
|
283
|
+
return decodeHtmlEntities(value);
|
|
284
|
+
}
|
|
130
285
|
function resolveEveInputDisplay(request, toolName) {
|
|
131
286
|
if (request.display) {
|
|
132
287
|
return request.display;
|
|
@@ -143,11 +298,12 @@ function confirmationActions(request) {
|
|
|
143
298
|
const options = request.options && request.options.length > 0 ? request.options : CONFIRMATION_DEFAULT_OPTIONS;
|
|
144
299
|
return options.map((option) => ({
|
|
145
300
|
id: option.id,
|
|
146
|
-
title: option.label,
|
|
147
|
-
...option.description ? { description: option.description } : {}
|
|
301
|
+
title: decodeDisplayText(option.label),
|
|
302
|
+
...option.description ? { description: decodeDisplayText(option.description) } : {}
|
|
148
303
|
}));
|
|
149
304
|
}
|
|
150
305
|
function textSubmitAction(prompt) {
|
|
306
|
+
const decodedPrompt = decodeDisplayText(prompt);
|
|
151
307
|
return {
|
|
152
308
|
id: EVE_INPUT_SUBMIT_ACTION_ID,
|
|
153
309
|
title: "Submit",
|
|
@@ -163,7 +319,7 @@ function textSubmitAction(prompt) {
|
|
|
163
319
|
},
|
|
164
320
|
ui: {
|
|
165
321
|
answer: {
|
|
166
|
-
"ui:title":
|
|
322
|
+
"ui:title": decodedPrompt.trim() || "Your answer",
|
|
167
323
|
"ui:widget": "textarea"
|
|
168
324
|
}
|
|
169
325
|
}
|
|
@@ -172,15 +328,15 @@ function textSubmitAction(prompt) {
|
|
|
172
328
|
function selectPerOptionActions(options) {
|
|
173
329
|
return options.map((option) => ({
|
|
174
330
|
id: option.id,
|
|
175
|
-
title: option.label,
|
|
176
|
-
...option.description ? { description: option.description } : {}
|
|
331
|
+
title: decodeDisplayText(option.label),
|
|
332
|
+
...option.description ? { description: decodeDisplayText(option.description) } : {}
|
|
177
333
|
}));
|
|
178
334
|
}
|
|
179
335
|
function selectFormAction(request) {
|
|
180
336
|
const options = request.options ?? [];
|
|
181
337
|
const allowFreeform = request.allowFreeform === true;
|
|
182
338
|
const enumValues = options.map((option) => option.id);
|
|
183
|
-
const enumNames = options.map((option) => option.label);
|
|
339
|
+
const enumNames = options.map((option) => decodeDisplayText(option.label));
|
|
184
340
|
if (allowFreeform) {
|
|
185
341
|
enumValues.push(EVE_INPUT_OTHER_CHOICE_ID);
|
|
186
342
|
enumNames.push(EVE_INPUT_OTHER_CHOICE_LABEL);
|
|
@@ -303,6 +459,12 @@ function isEveApprovalInputRequest(request) {
|
|
|
303
459
|
const options = request.options ?? [];
|
|
304
460
|
return options.length === 2 && options[0]?.id === "approve" && options[1]?.id === "deny";
|
|
305
461
|
}
|
|
462
|
+
function buildOptionIdFormData(display, optionId) {
|
|
463
|
+
if (display === "select" || display === "confirmation") {
|
|
464
|
+
return { choice: optionId };
|
|
465
|
+
}
|
|
466
|
+
return {};
|
|
467
|
+
}
|
|
306
468
|
function eveInputResponseToActionSubmission(request, response, options) {
|
|
307
469
|
const display = resolveEveInputDisplay(request, options?.toolName);
|
|
308
470
|
const actions = eveInputRequestToActions(request, options);
|
|
@@ -312,7 +474,7 @@ function eveInputResponseToActionSubmission(request, response, options) {
|
|
|
312
474
|
return {
|
|
313
475
|
actionId: response.optionId,
|
|
314
476
|
actionTitle: action.title,
|
|
315
|
-
formData:
|
|
477
|
+
formData: buildOptionIdFormData(display, response.optionId)
|
|
316
478
|
};
|
|
317
479
|
}
|
|
318
480
|
const option = request.options?.find((entry) => entry.id === response.optionId);
|
|
@@ -320,13 +482,13 @@ function eveInputResponseToActionSubmission(request, response, options) {
|
|
|
320
482
|
return {
|
|
321
483
|
actionId: response.optionId,
|
|
322
484
|
actionTitle: option.label,
|
|
323
|
-
formData:
|
|
485
|
+
formData: buildOptionIdFormData(display, response.optionId)
|
|
324
486
|
};
|
|
325
487
|
}
|
|
326
488
|
return {
|
|
327
489
|
actionId: response.optionId,
|
|
328
490
|
actionTitle: response.optionId,
|
|
329
|
-
formData:
|
|
491
|
+
formData: buildOptionIdFormData(display, response.optionId)
|
|
330
492
|
};
|
|
331
493
|
}
|
|
332
494
|
const text = response.text?.trim();
|
|
@@ -638,6 +800,39 @@ function eveSelfServiceAuth() {
|
|
|
638
800
|
};
|
|
639
801
|
}
|
|
640
802
|
|
|
803
|
+
// src/eve/agent/deployment-access.ts
|
|
804
|
+
var ROBOTROCK_EVE_CONNECT_ROUTES = {
|
|
805
|
+
/** Agent manifest + `robotrock-ready` hook detection. */
|
|
806
|
+
info: { method: "GET", path: "/eve/v1/info" },
|
|
807
|
+
/** Optional health probe (same auth as `/info` when the channel is protected). */
|
|
808
|
+
health: { method: "GET", path: "/eve/v1/health" }
|
|
809
|
+
};
|
|
810
|
+
var ROBOTROCK_EVE_ICON_PATHS = [
|
|
811
|
+
"/favicon.ico",
|
|
812
|
+
"/icon.svg",
|
|
813
|
+
"/icon.png"
|
|
814
|
+
];
|
|
815
|
+
var ROBOTROCK_EVE_CHAT_ROUTES = {
|
|
816
|
+
createSession: { method: "POST", path: "/eve/v1/session" },
|
|
817
|
+
continueSession: {
|
|
818
|
+
method: "POST",
|
|
819
|
+
path: "/eve/v1/session/:sessionId"
|
|
820
|
+
},
|
|
821
|
+
messageStream: {
|
|
822
|
+
method: "GET",
|
|
823
|
+
path: "/eve/v1/session/:sessionId/stream"
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
var EVE_SELF_AUTH_TOKEN_ENV_VAR = "EVE_SELF_AUTH_TOKEN";
|
|
827
|
+
var ROBOTROCK_EVE_BEARER_PROTECTED_PATHS = [
|
|
828
|
+
ROBOTROCK_EVE_CONNECT_ROUTES.info.path,
|
|
829
|
+
ROBOTROCK_EVE_CONNECT_ROUTES.health.path,
|
|
830
|
+
ROBOTROCK_EVE_CHAT_ROUTES.createSession.path,
|
|
831
|
+
ROBOTROCK_EVE_CHAT_ROUTES.continueSession.path,
|
|
832
|
+
ROBOTROCK_EVE_CHAT_ROUTES.messageStream.path,
|
|
833
|
+
...ROBOTROCK_EVE_ICON_PATHS
|
|
834
|
+
];
|
|
835
|
+
|
|
641
836
|
// src/eve/agent/channel.ts
|
|
642
837
|
import { eveChannel } from "eve/channels/eve";
|
|
643
838
|
import { localDev, vercelOidc } from "eve/channels/auth";
|
|
@@ -672,150 +867,6 @@ function robotrockEveChannel(options) {
|
|
|
672
867
|
// src/schemas/index.ts
|
|
673
868
|
import { z as z4 } from "zod";
|
|
674
869
|
|
|
675
|
-
// ../core/src/utils/safe-url.ts
|
|
676
|
-
var BLOCKED_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
677
|
-
"localhost",
|
|
678
|
-
"metadata.google.internal",
|
|
679
|
-
"metadata.goog"
|
|
680
|
-
]);
|
|
681
|
-
function normalizeHostname(hostname) {
|
|
682
|
-
return hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
683
|
-
}
|
|
684
|
-
function isBlockedIpv4(host) {
|
|
685
|
-
const match = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
|
|
686
|
-
if (!match) {
|
|
687
|
-
return false;
|
|
688
|
-
}
|
|
689
|
-
const octets = match.slice(1, 5).map((part) => Number(part));
|
|
690
|
-
if (octets.some((octet) => Number.isNaN(octet) || octet < 0 || octet > 255)) {
|
|
691
|
-
return true;
|
|
692
|
-
}
|
|
693
|
-
const [a, b, _c, _d] = octets;
|
|
694
|
-
if (a === void 0 || b === void 0) {
|
|
695
|
-
return true;
|
|
696
|
-
}
|
|
697
|
-
if (a === 127 || a === 0) return true;
|
|
698
|
-
if (a === 10) return true;
|
|
699
|
-
if (a === 169 && b === 254) return true;
|
|
700
|
-
if (a === 192 && b === 168) return true;
|
|
701
|
-
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
702
|
-
if (a === 100 && b >= 64 && b <= 127) return true;
|
|
703
|
-
return false;
|
|
704
|
-
}
|
|
705
|
-
function ipv4FromNumericHost(host) {
|
|
706
|
-
if (/^\d+$/.test(host)) {
|
|
707
|
-
const num = Number(host);
|
|
708
|
-
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
709
|
-
return null;
|
|
710
|
-
}
|
|
711
|
-
const a = num >>> 24 & 255;
|
|
712
|
-
const b = num >>> 16 & 255;
|
|
713
|
-
const c = num >>> 8 & 255;
|
|
714
|
-
const d = num & 255;
|
|
715
|
-
return `${a}.${b}.${c}.${d}`;
|
|
716
|
-
}
|
|
717
|
-
const hexMatch = /^0x([0-9a-f]{1,8})$/i.exec(host);
|
|
718
|
-
if (hexMatch) {
|
|
719
|
-
const num = Number.parseInt(hexMatch[1], 16);
|
|
720
|
-
if (!Number.isFinite(num) || num < 0 || num > 4294967295) {
|
|
721
|
-
return null;
|
|
722
|
-
}
|
|
723
|
-
const a = num >>> 24 & 255;
|
|
724
|
-
const b = num >>> 16 & 255;
|
|
725
|
-
const c = num >>> 8 & 255;
|
|
726
|
-
const d = num & 255;
|
|
727
|
-
return `${a}.${b}.${c}.${d}`;
|
|
728
|
-
}
|
|
729
|
-
return null;
|
|
730
|
-
}
|
|
731
|
-
function isBlockedIpv4Mapped(host) {
|
|
732
|
-
const mappedDotted = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/i.exec(host);
|
|
733
|
-
if (mappedDotted) {
|
|
734
|
-
return isBlockedIpv4(mappedDotted[1]);
|
|
735
|
-
}
|
|
736
|
-
const mappedHex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i.exec(host);
|
|
737
|
-
if (mappedHex) {
|
|
738
|
-
const high = Number.parseInt(mappedHex[1], 16);
|
|
739
|
-
const low = Number.parseInt(mappedHex[2], 16);
|
|
740
|
-
if (Number.isFinite(high) && Number.isFinite(low)) {
|
|
741
|
-
const a = high >> 8 & 255;
|
|
742
|
-
const b = high & 255;
|
|
743
|
-
const c = low >> 8 & 255;
|
|
744
|
-
const d = low & 255;
|
|
745
|
-
return isBlockedIpv4(`${a}.${b}.${c}.${d}`);
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
return false;
|
|
749
|
-
}
|
|
750
|
-
function isBlockedIpv6(host) {
|
|
751
|
-
if (host === "::1" || host === "0:0:0:0:0:0:0:1") {
|
|
752
|
-
return true;
|
|
753
|
-
}
|
|
754
|
-
if (host.startsWith("fc") || host.startsWith("fd")) {
|
|
755
|
-
return true;
|
|
756
|
-
}
|
|
757
|
-
if (host.startsWith("fe80:")) {
|
|
758
|
-
return true;
|
|
759
|
-
}
|
|
760
|
-
if (isBlockedIpv4Mapped(host)) {
|
|
761
|
-
return true;
|
|
762
|
-
}
|
|
763
|
-
return false;
|
|
764
|
-
}
|
|
765
|
-
function isBlockedHostname(hostname) {
|
|
766
|
-
const host = normalizeHostname(hostname);
|
|
767
|
-
if (!host) {
|
|
768
|
-
return true;
|
|
769
|
-
}
|
|
770
|
-
if (BLOCKED_HOSTNAMES.has(host)) {
|
|
771
|
-
return true;
|
|
772
|
-
}
|
|
773
|
-
if (host.endsWith(".localhost") || host.endsWith(".local")) {
|
|
774
|
-
return true;
|
|
775
|
-
}
|
|
776
|
-
const numericIpv4 = ipv4FromNumericHost(host);
|
|
777
|
-
if (numericIpv4 && isBlockedIpv4(numericIpv4)) {
|
|
778
|
-
return true;
|
|
779
|
-
}
|
|
780
|
-
return isBlockedIpv4(host) || isBlockedIpv6(host);
|
|
781
|
-
}
|
|
782
|
-
function isLoopbackHandlerUrl(urlString) {
|
|
783
|
-
let url;
|
|
784
|
-
try {
|
|
785
|
-
url = new URL(urlString);
|
|
786
|
-
} catch {
|
|
787
|
-
return false;
|
|
788
|
-
}
|
|
789
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
790
|
-
return false;
|
|
791
|
-
}
|
|
792
|
-
if (url.username || url.password) {
|
|
793
|
-
return false;
|
|
794
|
-
}
|
|
795
|
-
const host = url.hostname.toLowerCase();
|
|
796
|
-
return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]" || host.endsWith(".localhost");
|
|
797
|
-
}
|
|
798
|
-
function isAllowedHandlerUrl(urlString) {
|
|
799
|
-
return isPublicHttpUrl(urlString) || isLoopbackHandlerUrl(urlString);
|
|
800
|
-
}
|
|
801
|
-
function isPublicHttpUrl(urlString) {
|
|
802
|
-
let url;
|
|
803
|
-
try {
|
|
804
|
-
url = new URL(urlString);
|
|
805
|
-
} catch {
|
|
806
|
-
return false;
|
|
807
|
-
}
|
|
808
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
809
|
-
return false;
|
|
810
|
-
}
|
|
811
|
-
if (url.username || url.password) {
|
|
812
|
-
return false;
|
|
813
|
-
}
|
|
814
|
-
return !isBlockedHostname(url.hostname);
|
|
815
|
-
}
|
|
816
|
-
var PUBLIC_HTTP_URL_ERROR = "URL must be a public http:// or https:// address";
|
|
817
|
-
var HANDLER_URL_ERROR = "Handler URL must be a public or loopback http:// or https:// address";
|
|
818
|
-
|
|
819
870
|
// ../core/src/schemas/task.ts
|
|
820
871
|
import { z } from "zod";
|
|
821
872
|
|
|
@@ -2706,6 +2757,11 @@ function requireBoundAgentAdminClient(ctx) {
|
|
|
2706
2757
|
return createBoundAgentAdminClient(ctx);
|
|
2707
2758
|
}
|
|
2708
2759
|
export {
|
|
2760
|
+
EVE_SELF_AUTH_TOKEN_ENV_VAR,
|
|
2761
|
+
ROBOTROCK_EVE_BEARER_PROTECTED_PATHS,
|
|
2762
|
+
ROBOTROCK_EVE_CHAT_ROUTES,
|
|
2763
|
+
ROBOTROCK_EVE_CONNECT_ROUTES,
|
|
2764
|
+
ROBOTROCK_EVE_ICON_PATHS,
|
|
2709
2765
|
ROBOTROCK_PLATFORM_USER_CONTEXT_PUBLIC_KEY_URL,
|
|
2710
2766
|
ROBOTROCK_READY_HOOK_SLUG,
|
|
2711
2767
|
ROBOTROCK_USER_CONTEXT_AUDIENCE,
|