robotrock 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-admin.d.ts +2 -1
- package/dist/agent-admin.js +44 -0
- package/dist/agent-admin.js.map +1 -1
- package/dist/ai/index.d.ts +6 -6
- package/dist/ai/index.js +34 -2
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/trigger.d.ts +4 -4
- package/dist/ai/trigger.js +34 -2
- package/dist/ai/trigger.js.map +1 -1
- package/dist/ai/workflow.d.ts +4 -4
- package/dist/ai/workflow.js +34 -2
- package/dist/ai/workflow.js.map +1 -1
- package/dist/{auth-headers-qL-ZeEtd.d.ts → chat-correlation-BsHD-tOQ.d.ts} +6 -1
- package/dist/{client-YO9Y1rkH.d.ts → client-CZ5eWH5v.d.ts} +6 -1
- package/dist/eve/agent/index.d.ts +69 -6
- package/dist/eve/agent/index.js +165 -238
- package/dist/eve/agent/index.js.map +1 -1
- package/dist/eve/index.d.ts +3 -3
- package/dist/eve/index.js +1 -26
- package/dist/eve/index.js.map +1 -1
- package/dist/eve/tools/admin/assign-tasks.js +44 -0
- package/dist/eve/tools/admin/assign-tasks.js.map +1 -1
- package/dist/eve/tools/admin/manage-groups.js +44 -0
- package/dist/eve/tools/admin/manage-groups.js.map +1 -1
- package/dist/eve/tools/admin/manage-team-members.js +44 -0
- package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
- package/dist/eve/tools/admin/query-tasks.js +44 -0
- package/dist/eve/tools/admin/query-tasks.js.map +1 -1
- package/dist/eve/tools/identity/index.d.ts +1 -1
- package/dist/eve/tools/identity/index.js +2 -0
- package/dist/eve/tools/identity/index.js.map +1 -1
- package/dist/eve/tools/identity/my-access.js +2 -0
- package/dist/eve/tools/identity/my-access.js.map +1 -1
- package/dist/eve/tools/identity/whoami.d.ts +1 -1
- package/dist/eve/tools/identity/whoami.js +2 -0
- package/dist/eve/tools/identity/whoami.js.map +1 -1
- package/dist/eve/tools/inbox/create-task.d.ts +1 -1
- package/dist/eve/tools/inbox/create-task.js +56 -31
- package/dist/eve/tools/inbox/create-task.js.map +1 -1
- package/dist/eve/tools/inbox/index.d.ts +1 -1
- package/dist/eve/tools/inbox/index.js +56 -31
- 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 +68 -31
- package/dist/eve/tools/index.js.map +1 -1
- package/dist/{index-DoQN48Bm.d.ts → index-DePyAbTI.d.ts} +6 -3
- package/dist/index.d.ts +4 -4
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/{tenant-5YKDrdC-.d.ts → tenant-DmN0MMyC.d.ts} +1 -0
- package/dist/{tool-approval-bridge-aMA79Z1B.d.ts → tool-approval-bridge-DnGaRES4.d.ts} +1 -1
- package/dist/trigger/index.d.ts +2 -2
- package/dist/trigger/index.js +26 -2
- package/dist/trigger/index.js.map +1 -1
- package/dist/{trigger-CXrbKVCL.d.ts → trigger--qTIK0s6.d.ts} +2 -2
- package/dist/workflow/index.d.ts +2 -2
- package/dist/workflow/index.js +26 -2
- package/dist/workflow/index.js.map +1 -1
- package/package.json +1 -1
package/dist/eve/agent/index.js
CHANGED
|
@@ -89,6 +89,7 @@ function verifyRobotRockPlatformUserContextJwt(args) {
|
|
|
89
89
|
const connectionId = readStringClaim(payload, "connectionId");
|
|
90
90
|
const role = parseTenantRoleClaim(readStringClaim(payload, "role"));
|
|
91
91
|
const workosUserId = readStringClaim(payload, "workosUserId");
|
|
92
|
+
const chatId = readStringClaim(payload, "chatId");
|
|
92
93
|
const iat = payload.iat;
|
|
93
94
|
const exp = payload.exp;
|
|
94
95
|
if (!sub || !email || !name || !tenantSlug || !connectionId || !role || typeof iat !== "number" || typeof exp !== "number") {
|
|
@@ -107,6 +108,7 @@ function verifyRobotRockPlatformUserContextJwt(args) {
|
|
|
107
108
|
role,
|
|
108
109
|
groups: readGroupsClaim(payload),
|
|
109
110
|
...workosUserId ? { workosUserId } : {},
|
|
111
|
+
...chatId ? { chatId } : {},
|
|
110
112
|
iat,
|
|
111
113
|
exp
|
|
112
114
|
}
|
|
@@ -387,89 +389,6 @@ function parseEveAskQuestionToolOutput(output) {
|
|
|
387
389
|
return { ...optionId ? { optionId } : {}, ...text ? { text } : {} };
|
|
388
390
|
}
|
|
389
391
|
|
|
390
|
-
// src/eve/tool-audit.ts
|
|
391
|
-
var MANAGE_TEAM_MEMBERS_TOOL_NAME = "manage_team_members";
|
|
392
|
-
var MANAGE_GROUPS_TOOL_NAME = "manage_groups";
|
|
393
|
-
var CREATE_INBOX_TASK_TOOL_NAME = "create_robotrock_task";
|
|
394
|
-
var MUTATING_TEAM_MEMBER_ACTIONS = /* @__PURE__ */ new Set([
|
|
395
|
-
"invite",
|
|
396
|
-
"update_role",
|
|
397
|
-
"remove"
|
|
398
|
-
]);
|
|
399
|
-
var MUTATING_GROUP_ACTIONS = /* @__PURE__ */ new Set([
|
|
400
|
-
"create",
|
|
401
|
-
"update",
|
|
402
|
-
"delete",
|
|
403
|
-
"add_member",
|
|
404
|
-
"remove_member"
|
|
405
|
-
]);
|
|
406
|
-
var SKIP_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
407
|
-
CREATE_INBOX_TASK_TOOL_NAME,
|
|
408
|
-
"ask_question",
|
|
409
|
-
"closeChat",
|
|
410
|
-
"requestActionInput"
|
|
411
|
-
]);
|
|
412
|
-
function readAction(input) {
|
|
413
|
-
const action = input.action;
|
|
414
|
-
return typeof action === "string" && action.trim().length > 0 ? action.trim() : void 0;
|
|
415
|
-
}
|
|
416
|
-
function shouldAuditToolExecution(toolName, input) {
|
|
417
|
-
if (SKIP_TOOL_NAMES.has(toolName)) {
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
420
|
-
const action = readAction(input);
|
|
421
|
-
if (toolName === MANAGE_TEAM_MEMBERS_TOOL_NAME) {
|
|
422
|
-
return action != null && MUTATING_TEAM_MEMBER_ACTIONS.has(action);
|
|
423
|
-
}
|
|
424
|
-
if (toolName === MANAGE_GROUPS_TOOL_NAME) {
|
|
425
|
-
return action != null && MUTATING_GROUP_ACTIONS.has(action);
|
|
426
|
-
}
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
var AUDIT_INPUT_KEYS = /* @__PURE__ */ new Set([
|
|
430
|
-
"action",
|
|
431
|
-
"email",
|
|
432
|
-
"userId",
|
|
433
|
-
"role",
|
|
434
|
-
"name",
|
|
435
|
-
"groupId",
|
|
436
|
-
"description"
|
|
437
|
-
]);
|
|
438
|
-
function sanitizeToolAuditInput(input) {
|
|
439
|
-
const sanitized = {};
|
|
440
|
-
for (const [key, value] of Object.entries(input)) {
|
|
441
|
-
if (!AUDIT_INPUT_KEYS.has(key)) {
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
if (value == null || value === "") {
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
if (typeof value === "string" || typeof value === "boolean") {
|
|
448
|
-
sanitized[key] = value;
|
|
449
|
-
continue;
|
|
450
|
-
}
|
|
451
|
-
if (typeof value === "number") {
|
|
452
|
-
sanitized[key] = value;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
return sanitized;
|
|
456
|
-
}
|
|
457
|
-
function buildChatToolAuditPayload(input) {
|
|
458
|
-
const sanitized = sanitizeToolAuditInput(input.toolInput);
|
|
459
|
-
if (!shouldAuditToolExecution(input.toolName, sanitized)) {
|
|
460
|
-
return null;
|
|
461
|
-
}
|
|
462
|
-
const success = input.status === "completed" && input.isError !== true;
|
|
463
|
-
return {
|
|
464
|
-
toolCallId: input.toolCallId,
|
|
465
|
-
toolName: input.toolName,
|
|
466
|
-
input: sanitized,
|
|
467
|
-
success,
|
|
468
|
-
status: input.status,
|
|
469
|
-
...input.error ? { error: input.error } : {}
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
|
|
473
392
|
// src/eve/index.ts
|
|
474
393
|
var ROBOTROCK_READY_HOOK_SLUG = "robotrock-ready";
|
|
475
394
|
|
|
@@ -521,6 +440,7 @@ function tryResolveTenantCaller(ctx) {
|
|
|
521
440
|
}
|
|
522
441
|
const workosUserId = readStringAttribute(caller.attributes, "workosUserId");
|
|
523
442
|
const connectionId = readStringAttribute(caller.attributes, "connectionId");
|
|
443
|
+
const chatId = readStringAttribute(caller.attributes, "chatId");
|
|
524
444
|
const groups = readStringArrayAttribute(caller.attributes, "groups");
|
|
525
445
|
return {
|
|
526
446
|
userId: caller.principalId,
|
|
@@ -528,6 +448,7 @@ function tryResolveTenantCaller(ctx) {
|
|
|
528
448
|
name: name ?? email.split("@")[0] ?? email,
|
|
529
449
|
tenantSlug,
|
|
530
450
|
...connectionId ? { connectionId } : {},
|
|
451
|
+
...chatId ? { chatId } : {},
|
|
531
452
|
role,
|
|
532
453
|
isAdmin: role === "admin",
|
|
533
454
|
groups,
|
|
@@ -601,7 +522,8 @@ function mapVerifiedClaimsToSessionAuth(claims) {
|
|
|
601
522
|
role: claims.role,
|
|
602
523
|
groups: claims.groups,
|
|
603
524
|
...claims.connectionId ? { connectionId: claims.connectionId } : {},
|
|
604
|
-
...claims.workosUserId ? { workosUserId: claims.workosUserId } : {}
|
|
525
|
+
...claims.workosUserId ? { workosUserId: claims.workosUserId } : {},
|
|
526
|
+
...claims.chatId ? { chatId: claims.chatId } : {}
|
|
605
527
|
}
|
|
606
528
|
};
|
|
607
529
|
}
|
|
@@ -665,12 +587,14 @@ function robotrockUserContextAuth(options) {
|
|
|
665
587
|
result.sessionAuth.attributes,
|
|
666
588
|
"workosUserId"
|
|
667
589
|
);
|
|
590
|
+
const chatId = readStringAttribute(result.sessionAuth.attributes, "chatId");
|
|
668
591
|
return mapVerifiedClaimsToSessionAuth({
|
|
669
592
|
sub: subject,
|
|
670
593
|
email,
|
|
671
594
|
name: name ?? email.split("@")[0] ?? email,
|
|
672
595
|
tenantSlug,
|
|
673
596
|
connectionId,
|
|
597
|
+
chatId,
|
|
674
598
|
role,
|
|
675
599
|
groups,
|
|
676
600
|
workosUserId
|
|
@@ -714,6 +638,39 @@ function eveSelfServiceAuth() {
|
|
|
714
638
|
};
|
|
715
639
|
}
|
|
716
640
|
|
|
641
|
+
// src/eve/agent/deployment-access.ts
|
|
642
|
+
var ROBOTROCK_EVE_CONNECT_ROUTES = {
|
|
643
|
+
/** Agent manifest + `robotrock-ready` hook detection. */
|
|
644
|
+
info: { method: "GET", path: "/eve/v1/info" },
|
|
645
|
+
/** Optional health probe (same auth as `/info` when the channel is protected). */
|
|
646
|
+
health: { method: "GET", path: "/eve/v1/health" }
|
|
647
|
+
};
|
|
648
|
+
var ROBOTROCK_EVE_ICON_PATHS = [
|
|
649
|
+
"/favicon.ico",
|
|
650
|
+
"/icon.svg",
|
|
651
|
+
"/icon.png"
|
|
652
|
+
];
|
|
653
|
+
var ROBOTROCK_EVE_CHAT_ROUTES = {
|
|
654
|
+
createSession: { method: "POST", path: "/eve/v1/session" },
|
|
655
|
+
continueSession: {
|
|
656
|
+
method: "POST",
|
|
657
|
+
path: "/eve/v1/session/:sessionId"
|
|
658
|
+
},
|
|
659
|
+
messageStream: {
|
|
660
|
+
method: "GET",
|
|
661
|
+
path: "/eve/v1/session/:sessionId/stream"
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
var EVE_SELF_AUTH_TOKEN_ENV_VAR = "EVE_SELF_AUTH_TOKEN";
|
|
665
|
+
var ROBOTROCK_EVE_BEARER_PROTECTED_PATHS = [
|
|
666
|
+
ROBOTROCK_EVE_CONNECT_ROUTES.info.path,
|
|
667
|
+
ROBOTROCK_EVE_CONNECT_ROUTES.health.path,
|
|
668
|
+
ROBOTROCK_EVE_CHAT_ROUTES.createSession.path,
|
|
669
|
+
ROBOTROCK_EVE_CHAT_ROUTES.continueSession.path,
|
|
670
|
+
ROBOTROCK_EVE_CHAT_ROUTES.messageStream.path,
|
|
671
|
+
...ROBOTROCK_EVE_ICON_PATHS
|
|
672
|
+
];
|
|
673
|
+
|
|
717
674
|
// src/eve/agent/channel.ts
|
|
718
675
|
import { eveChannel } from "eve/channels/eve";
|
|
719
676
|
import { localDev, vercelOidc } from "eve/channels/auth";
|
|
@@ -1611,11 +1568,42 @@ function resolveRobotRockAuthConfig(overrides) {
|
|
|
1611
1568
|
return { kind: "apiKey", apiKey };
|
|
1612
1569
|
}
|
|
1613
1570
|
|
|
1571
|
+
// src/chat-correlation.ts
|
|
1572
|
+
var ROBOTROCK_CHAT_ID_HEADER = "x-robotrock-chat-id";
|
|
1573
|
+
var ROBOTROCK_EVE_SESSION_ID_HEADER = "x-robotrock-eve-session-id";
|
|
1574
|
+
function resolveChatCorrelationFromEnv() {
|
|
1575
|
+
const chatId = process.env.ROBOTROCK_CHAT_ID?.trim();
|
|
1576
|
+
const eveSessionId = process.env.ROBOTROCK_EVE_SESSION_ID?.trim();
|
|
1577
|
+
if (!chatId && !eveSessionId) {
|
|
1578
|
+
return void 0;
|
|
1579
|
+
}
|
|
1580
|
+
return {
|
|
1581
|
+
...chatId ? { chatId } : {},
|
|
1582
|
+
...eveSessionId ? { eveSessionId } : {}
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
function buildChatCorrelationHeaders(correlation) {
|
|
1586
|
+
if (!correlation) {
|
|
1587
|
+
return {};
|
|
1588
|
+
}
|
|
1589
|
+
const headers = {};
|
|
1590
|
+
const chatId = correlation.chatId?.trim();
|
|
1591
|
+
const eveSessionId = correlation.eveSessionId?.trim();
|
|
1592
|
+
if (chatId) {
|
|
1593
|
+
headers[ROBOTROCK_CHAT_ID_HEADER] = chatId;
|
|
1594
|
+
}
|
|
1595
|
+
if (eveSessionId) {
|
|
1596
|
+
headers[ROBOTROCK_EVE_SESSION_ID_HEADER] = eveSessionId;
|
|
1597
|
+
}
|
|
1598
|
+
return headers;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1614
1601
|
// src/chats.ts
|
|
1615
1602
|
function createChatsApi(config) {
|
|
1616
1603
|
const headers = () => ({
|
|
1617
1604
|
"Content-Type": "application/json",
|
|
1618
|
-
...buildRobotRockAuthHeaders(config.auth)
|
|
1605
|
+
...buildRobotRockAuthHeaders(config.auth),
|
|
1606
|
+
...buildChatCorrelationHeaders(config.chatCorrelation)
|
|
1619
1607
|
});
|
|
1620
1608
|
return {
|
|
1621
1609
|
async create(input) {
|
|
@@ -1825,6 +1813,7 @@ function serializeValidUntil(value) {
|
|
|
1825
1813
|
}
|
|
1826
1814
|
var RobotRock = class {
|
|
1827
1815
|
auth;
|
|
1816
|
+
chatCorrelation;
|
|
1828
1817
|
baseUrl;
|
|
1829
1818
|
app;
|
|
1830
1819
|
agentVersion;
|
|
@@ -1852,6 +1841,7 @@ var RobotRock = class {
|
|
|
1852
1841
|
...apiKey ? { apiKey } : {},
|
|
1853
1842
|
...agentService ? { agentService } : {}
|
|
1854
1843
|
});
|
|
1844
|
+
this.chatCorrelation = config.chatCorrelation;
|
|
1855
1845
|
this.baseUrl = config.baseUrl ?? getRobotRockApiBaseUrl();
|
|
1856
1846
|
this.app = config.app;
|
|
1857
1847
|
this.agentVersion = config.version ?? resolveAgentVersionFromEnv();
|
|
@@ -1869,13 +1859,15 @@ var RobotRock = class {
|
|
|
1869
1859
|
this.chats = createChatsApi({
|
|
1870
1860
|
baseUrl: this.baseUrl,
|
|
1871
1861
|
auth: this.auth,
|
|
1872
|
-
app: this.app
|
|
1862
|
+
app: this.app,
|
|
1863
|
+
chatCorrelation: this.chatCorrelation
|
|
1873
1864
|
});
|
|
1874
1865
|
}
|
|
1875
1866
|
authHeaders(extra) {
|
|
1876
1867
|
return {
|
|
1877
1868
|
"Content-Type": "application/json",
|
|
1878
1869
|
...buildRobotRockAuthHeaders(this.auth),
|
|
1870
|
+
...buildChatCorrelationHeaders(this.chatCorrelation),
|
|
1879
1871
|
...extra
|
|
1880
1872
|
};
|
|
1881
1873
|
}
|
|
@@ -2146,51 +2138,39 @@ function normalizeSendToHumanInput(task, clientDefaults) {
|
|
|
2146
2138
|
};
|
|
2147
2139
|
}
|
|
2148
2140
|
|
|
2149
|
-
// src/env.ts
|
|
2150
|
-
function resolveRobotRockConfig(overrides) {
|
|
2151
|
-
const agentService = overrides?.agentService;
|
|
2152
|
-
const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;
|
|
2153
|
-
if (agentService && apiKey) {
|
|
2154
|
-
throw new Error(
|
|
2155
|
-
"RobotRock client cannot configure both apiKey and agentService."
|
|
2156
|
-
);
|
|
2157
|
-
}
|
|
2158
|
-
const baseUrl = overrides?.baseUrl ?? getRobotRockApiBaseUrl();
|
|
2159
|
-
const app = overrides?.app ?? process.env.ROBOTROCK_APP;
|
|
2160
|
-
if (agentService) {
|
|
2161
|
-
return app ? { agentService, baseUrl, app } : { agentService, baseUrl };
|
|
2162
|
-
}
|
|
2163
|
-
if (!apiKey) {
|
|
2164
|
-
throw new Error(
|
|
2165
|
-
"RobotRock API key is required. Set ROBOTROCK_API_KEY or pass agentService when creating the client."
|
|
2166
|
-
);
|
|
2167
|
-
}
|
|
2168
|
-
return app ? { apiKey, baseUrl, app } : { apiKey, baseUrl };
|
|
2169
|
-
}
|
|
2170
|
-
|
|
2171
2141
|
// src/eve/agent/client-from-session.ts
|
|
2172
2142
|
var warnedMissingAuth = false;
|
|
2143
|
+
function resolveBoundChatCorrelation(ctx) {
|
|
2144
|
+
const caller = tryResolveTenantCaller(ctx);
|
|
2145
|
+
return {
|
|
2146
|
+
eveSessionId: ctx.session.id,
|
|
2147
|
+
...caller?.chatId ? { chatId: caller.chatId } : {},
|
|
2148
|
+
...resolveChatCorrelationFromEnv()
|
|
2149
|
+
};
|
|
2150
|
+
}
|
|
2173
2151
|
function tryCreateBoundRobotRockClient(ctx) {
|
|
2174
2152
|
const caller = tryResolveTenantCaller(ctx);
|
|
2175
2153
|
const serviceToken = process.env.ROBOTROCK_AGENT_SERVICE_TOKEN?.trim();
|
|
2154
|
+
const chatCorrelation = resolveBoundChatCorrelation(ctx);
|
|
2176
2155
|
if (caller?.connectionId && serviceToken) {
|
|
2177
2156
|
return createClient({
|
|
2178
2157
|
baseUrl: process.env.ROBOTROCK_BASE_URL?.trim(),
|
|
2158
|
+
chatCorrelation,
|
|
2179
2159
|
agentService: {
|
|
2180
2160
|
token: serviceToken,
|
|
2181
2161
|
tenantSlug: caller.tenantSlug,
|
|
2182
|
-
connectionId: caller.connectionId
|
|
2162
|
+
connectionId: caller.connectionId,
|
|
2163
|
+
actingUserId: caller.userId
|
|
2183
2164
|
}
|
|
2184
2165
|
});
|
|
2185
2166
|
}
|
|
2186
2167
|
const apiKey = process.env.ROBOTROCK_API_KEY?.trim();
|
|
2187
2168
|
if (apiKey) {
|
|
2188
|
-
return createClient(
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
);
|
|
2169
|
+
return createClient({
|
|
2170
|
+
apiKey,
|
|
2171
|
+
baseUrl: process.env.ROBOTROCK_BASE_URL?.trim(),
|
|
2172
|
+
chatCorrelation
|
|
2173
|
+
});
|
|
2194
2174
|
}
|
|
2195
2175
|
if (!warnedMissingAuth) {
|
|
2196
2176
|
warnedMissingAuth = true;
|
|
@@ -2238,23 +2218,6 @@ function logAuditFailure(label, error) {
|
|
|
2238
2218
|
const hint = error instanceof RobotRockError && error.statusCode === 405 ? " \u2014 set ROBOTROCK_BASE_URL=http://localhost:4001/v1 and run the local API" : "";
|
|
2239
2219
|
console.warn(`robotrock-chat-audit: failed to ${label}${hint}`, error);
|
|
2240
2220
|
}
|
|
2241
|
-
async function postRobotRockChatToolAudit(ctx, payload) {
|
|
2242
|
-
const client = tryCreateBoundRobotRockClient(ctx);
|
|
2243
|
-
if (!client) {
|
|
2244
|
-
if (!warnedMissingAuth2) {
|
|
2245
|
-
warnedMissingAuth2 = true;
|
|
2246
|
-
console.warn(
|
|
2247
|
-
"robotrock-chat-audit: RobotRock auth is unset; skipping tool audit logging."
|
|
2248
|
-
);
|
|
2249
|
-
}
|
|
2250
|
-
return;
|
|
2251
|
-
}
|
|
2252
|
-
try {
|
|
2253
|
-
await client.chats.logToolExecution(payload);
|
|
2254
|
-
} catch (error) {
|
|
2255
|
-
logAuditFailure("log tool execution", error);
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
2221
|
async function postRobotRockChatInputAudit(ctx, payload) {
|
|
2259
2222
|
const client = tryCreateBoundRobotRockClient(ctx);
|
|
2260
2223
|
if (!client) {
|
|
@@ -2422,6 +2385,28 @@ function buildRobotRockTaskPayload(input, options) {
|
|
|
2422
2385
|
return payload;
|
|
2423
2386
|
}
|
|
2424
2387
|
|
|
2388
|
+
// src/env.ts
|
|
2389
|
+
function resolveRobotRockConfig(overrides) {
|
|
2390
|
+
const agentService = overrides?.agentService;
|
|
2391
|
+
const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;
|
|
2392
|
+
if (agentService && apiKey) {
|
|
2393
|
+
throw new Error(
|
|
2394
|
+
"RobotRock client cannot configure both apiKey and agentService."
|
|
2395
|
+
);
|
|
2396
|
+
}
|
|
2397
|
+
const baseUrl = overrides?.baseUrl ?? getRobotRockApiBaseUrl();
|
|
2398
|
+
const app = overrides?.app ?? process.env.ROBOTROCK_APP;
|
|
2399
|
+
if (agentService) {
|
|
2400
|
+
return app ? { agentService, baseUrl, app } : { agentService, baseUrl };
|
|
2401
|
+
}
|
|
2402
|
+
if (!apiKey) {
|
|
2403
|
+
throw new Error(
|
|
2404
|
+
"RobotRock API key is required. Set ROBOTROCK_API_KEY or pass agentService when creating the client."
|
|
2405
|
+
);
|
|
2406
|
+
}
|
|
2407
|
+
return app ? { apiKey, baseUrl, app } : { apiKey, baseUrl };
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2425
2410
|
// src/eve/agent/cron-chat.ts
|
|
2426
2411
|
function resolveCronAgentIdentifier(agentIdentifier) {
|
|
2427
2412
|
return agentIdentifier?.trim() || process.env.ROBOTROCK_CRON_AGENT_IDENTIFIER?.trim() || "robotrock-agent";
|
|
@@ -2451,8 +2436,6 @@ function defineRobotRockReadyHook() {
|
|
|
2451
2436
|
// src/eve/agent/hooks/chat-audit.ts
|
|
2452
2437
|
import { defineHook as defineHook2 } from "eve/hooks";
|
|
2453
2438
|
var loggedIdempotencyKeys = /* @__PURE__ */ new Set();
|
|
2454
|
-
var loggedToolCallIds = /* @__PURE__ */ new Set();
|
|
2455
|
-
var pendingToolCallsBySession = /* @__PURE__ */ new Map();
|
|
2456
2439
|
function toEveInputRequest(request) {
|
|
2457
2440
|
return {
|
|
2458
2441
|
requestId: request.requestId,
|
|
@@ -2462,22 +2445,6 @@ function toEveInputRequest(request) {
|
|
|
2462
2445
|
...request.options ? { options: request.options } : {}
|
|
2463
2446
|
};
|
|
2464
2447
|
}
|
|
2465
|
-
function stashPendingToolCall(sessionId, callId, toolName, input) {
|
|
2466
|
-
const sessionCalls = pendingToolCallsBySession.get(sessionId) ?? /* @__PURE__ */ new Map();
|
|
2467
|
-
sessionCalls.set(callId, { toolName, input });
|
|
2468
|
-
pendingToolCallsBySession.set(sessionId, sessionCalls);
|
|
2469
|
-
}
|
|
2470
|
-
function takePendingToolCall(sessionId, callId) {
|
|
2471
|
-
const sessionCalls = pendingToolCallsBySession.get(sessionId);
|
|
2472
|
-
const pending = sessionCalls?.get(callId);
|
|
2473
|
-
if (pending && sessionCalls) {
|
|
2474
|
-
sessionCalls.delete(callId);
|
|
2475
|
-
if (sessionCalls.size === 0) {
|
|
2476
|
-
pendingToolCallsBySession.delete(sessionId);
|
|
2477
|
-
}
|
|
2478
|
-
}
|
|
2479
|
-
return pending;
|
|
2480
|
-
}
|
|
2481
2448
|
async function logPendingInputResponse(ctx, pending, response) {
|
|
2482
2449
|
const caller = tryResolveTenantCaller(ctx);
|
|
2483
2450
|
if (!caller) {
|
|
@@ -2514,70 +2481,11 @@ async function logPendingInputResponse(ctx, pending, response) {
|
|
|
2514
2481
|
});
|
|
2515
2482
|
loggedIdempotencyKeys.add(idempotencyKey);
|
|
2516
2483
|
}
|
|
2517
|
-
async function logToolExecutionFromResult(ctx, event) {
|
|
2518
|
-
const result = event.data.result;
|
|
2519
|
-
if (result.kind !== "tool-result") {
|
|
2520
|
-
return;
|
|
2521
|
-
}
|
|
2522
|
-
const callId = result.callId;
|
|
2523
|
-
const toolName = result.toolName;
|
|
2524
|
-
if (!callId || !toolName) {
|
|
2525
|
-
return;
|
|
2526
|
-
}
|
|
2527
|
-
const dedupeKey = `${ctx.session.id}:${callId}`;
|
|
2528
|
-
if (loggedToolCallIds.has(dedupeKey)) {
|
|
2529
|
-
return;
|
|
2530
|
-
}
|
|
2531
|
-
const pending = takePendingToolCall(ctx.session.id, callId) ?? { toolName, input: {} };
|
|
2532
|
-
const payload = buildChatToolAuditPayload({
|
|
2533
|
-
toolCallId: callId,
|
|
2534
|
-
toolName: pending.toolName,
|
|
2535
|
-
toolInput: pending.input,
|
|
2536
|
-
status: event.data.status,
|
|
2537
|
-
isError: result.isError,
|
|
2538
|
-
error: event.data.error?.message
|
|
2539
|
-
});
|
|
2540
|
-
if (!payload) {
|
|
2541
|
-
return;
|
|
2542
|
-
}
|
|
2543
|
-
const caller = tryResolveTenantCaller(ctx);
|
|
2544
|
-
if (!caller) {
|
|
2545
|
-
return;
|
|
2546
|
-
}
|
|
2547
|
-
await postRobotRockChatToolAudit(ctx, {
|
|
2548
|
-
eveSessionId: ctx.session.id,
|
|
2549
|
-
userId: caller.userId,
|
|
2550
|
-
toolCallId: payload.toolCallId,
|
|
2551
|
-
toolName: payload.toolName,
|
|
2552
|
-
input: payload.input,
|
|
2553
|
-
success: payload.success,
|
|
2554
|
-
status: payload.status,
|
|
2555
|
-
...payload.error ? { error: payload.error } : {},
|
|
2556
|
-
idempotencyKey: dedupeKey
|
|
2557
|
-
});
|
|
2558
|
-
loggedToolCallIds.add(dedupeKey);
|
|
2559
|
-
}
|
|
2560
2484
|
function resetRobotrockChatAuditIdempotencyKeys() {
|
|
2561
2485
|
loggedIdempotencyKeys.clear();
|
|
2562
|
-
loggedToolCallIds.clear();
|
|
2563
|
-
pendingToolCallsBySession.clear();
|
|
2564
2486
|
}
|
|
2565
2487
|
var robotrockChatAuditHook = defineHook2({
|
|
2566
2488
|
events: {
|
|
2567
|
-
async "actions.requested"(event, ctx) {
|
|
2568
|
-
for (const action of event.data.actions) {
|
|
2569
|
-
if (action.kind !== "tool-call") {
|
|
2570
|
-
continue;
|
|
2571
|
-
}
|
|
2572
|
-
const input = action.input != null && typeof action.input === "object" && !Array.isArray(action.input) ? action.input : {};
|
|
2573
|
-
stashPendingToolCall(
|
|
2574
|
-
ctx.session.id,
|
|
2575
|
-
action.callId,
|
|
2576
|
-
action.toolName,
|
|
2577
|
-
input
|
|
2578
|
-
);
|
|
2579
|
-
}
|
|
2580
|
-
},
|
|
2581
2489
|
async "input.requested"(event, ctx) {
|
|
2582
2490
|
const requests = [];
|
|
2583
2491
|
for (const request of event.data.requests) {
|
|
@@ -2621,37 +2529,39 @@ var robotrockChatAuditHook = defineHook2({
|
|
|
2621
2529
|
},
|
|
2622
2530
|
async "action.result"(event, ctx) {
|
|
2623
2531
|
const result = event.data.result;
|
|
2624
|
-
if (result.kind
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2532
|
+
if (result.kind !== "tool-result") {
|
|
2533
|
+
return;
|
|
2534
|
+
}
|
|
2535
|
+
const staged = await fetchRobotRockStagedHitl(ctx, ctx.session.id);
|
|
2536
|
+
const pending = staged.find((entry) => entry.toolCallId === result.callId);
|
|
2537
|
+
if (!pending) {
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2540
|
+
const idempotencyKey = `${ctx.session.id}:${pending.requestId}`;
|
|
2541
|
+
if (loggedIdempotencyKeys.has(idempotencyKey)) {
|
|
2542
|
+
return;
|
|
2543
|
+
}
|
|
2544
|
+
if (pending.toolName === "ask_question") {
|
|
2545
|
+
const parsed = parseEveAskQuestionToolOutput(result.output);
|
|
2546
|
+
if (parsed) {
|
|
2547
|
+
await logPendingInputResponse(ctx, pending, {
|
|
2548
|
+
requestId: pending.requestId,
|
|
2549
|
+
...parsed
|
|
2550
|
+
});
|
|
2551
|
+
}
|
|
2552
|
+
} else if (isEveApprovalInputRequest(toEveInputRequest(pending))) {
|
|
2553
|
+
if (event.data.status === "rejected") {
|
|
2554
|
+
await logPendingInputResponse(ctx, pending, {
|
|
2555
|
+
requestId: pending.requestId,
|
|
2556
|
+
optionId: "deny"
|
|
2557
|
+
});
|
|
2558
|
+
} else if (event.data.status === "completed") {
|
|
2559
|
+
await logPendingInputResponse(ctx, pending, {
|
|
2560
|
+
requestId: pending.requestId,
|
|
2561
|
+
optionId: "approve"
|
|
2562
|
+
});
|
|
2652
2563
|
}
|
|
2653
2564
|
}
|
|
2654
|
-
await logToolExecutionFromResult(ctx, event);
|
|
2655
2565
|
}
|
|
2656
2566
|
}
|
|
2657
2567
|
});
|
|
@@ -2671,6 +2581,7 @@ async function agentAdminFetch(config, path, init) {
|
|
|
2671
2581
|
headers: {
|
|
2672
2582
|
"Content-Type": "application/json",
|
|
2673
2583
|
...buildRobotRockAuthHeaders(config.auth),
|
|
2584
|
+
...buildChatCorrelationHeaders(config.chatCorrelation),
|
|
2674
2585
|
...init?.headers ?? {}
|
|
2675
2586
|
}
|
|
2676
2587
|
});
|
|
@@ -2780,13 +2691,23 @@ function createAgentAdminApi(config) {
|
|
|
2780
2691
|
}
|
|
2781
2692
|
};
|
|
2782
2693
|
}
|
|
2694
|
+
function resolveBoundChatCorrelation2(ctx) {
|
|
2695
|
+
const caller = tryResolveTenantCaller(ctx);
|
|
2696
|
+
return {
|
|
2697
|
+
eveSessionId: ctx.session.id,
|
|
2698
|
+
...caller?.chatId ? { chatId: caller.chatId } : {},
|
|
2699
|
+
...resolveChatCorrelationFromEnv()
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2783
2702
|
function createBoundAgentAdminClient(ctx) {
|
|
2784
2703
|
const caller = requireTenantCaller(ctx);
|
|
2785
2704
|
const baseUrl = process.env.ROBOTROCK_BASE_URL?.trim();
|
|
2786
2705
|
const serviceToken = process.env.ROBOTROCK_AGENT_SERVICE_TOKEN?.trim();
|
|
2706
|
+
const chatCorrelation = resolveBoundChatCorrelation2(ctx);
|
|
2787
2707
|
if (caller.connectionId && serviceToken) {
|
|
2788
2708
|
return createAgentAdminApi({
|
|
2789
2709
|
baseUrl,
|
|
2710
|
+
chatCorrelation,
|
|
2790
2711
|
auth: resolveRobotRockAuthConfig({
|
|
2791
2712
|
agentService: {
|
|
2792
2713
|
token: serviceToken,
|
|
@@ -2801,6 +2722,7 @@ function createBoundAgentAdminClient(ctx) {
|
|
|
2801
2722
|
if (apiKey) {
|
|
2802
2723
|
return createAgentAdminApi({
|
|
2803
2724
|
baseUrl,
|
|
2725
|
+
chatCorrelation,
|
|
2804
2726
|
auth: {
|
|
2805
2727
|
kind: "apiKey",
|
|
2806
2728
|
apiKey,
|
|
@@ -2817,6 +2739,11 @@ function requireBoundAgentAdminClient(ctx) {
|
|
|
2817
2739
|
return createBoundAgentAdminClient(ctx);
|
|
2818
2740
|
}
|
|
2819
2741
|
export {
|
|
2742
|
+
EVE_SELF_AUTH_TOKEN_ENV_VAR,
|
|
2743
|
+
ROBOTROCK_EVE_BEARER_PROTECTED_PATHS,
|
|
2744
|
+
ROBOTROCK_EVE_CHAT_ROUTES,
|
|
2745
|
+
ROBOTROCK_EVE_CONNECT_ROUTES,
|
|
2746
|
+
ROBOTROCK_EVE_ICON_PATHS,
|
|
2820
2747
|
ROBOTROCK_PLATFORM_USER_CONTEXT_PUBLIC_KEY_URL,
|
|
2821
2748
|
ROBOTROCK_READY_HOOK_SLUG,
|
|
2822
2749
|
ROBOTROCK_USER_CONTEXT_AUDIENCE,
|