robotrock 1.3.0 → 1.3.2

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.
Files changed (60) hide show
  1. package/README.md +2 -2
  2. package/dist/agent-admin.d.ts +2 -1
  3. package/dist/agent-admin.js +44 -0
  4. package/dist/agent-admin.js.map +1 -1
  5. package/dist/ai/index.d.ts +6 -6
  6. package/dist/ai/index.js +34 -2
  7. package/dist/ai/index.js.map +1 -1
  8. package/dist/ai/trigger.d.ts +4 -4
  9. package/dist/ai/trigger.js +34 -2
  10. package/dist/ai/trigger.js.map +1 -1
  11. package/dist/ai/workflow.d.ts +4 -4
  12. package/dist/ai/workflow.js +34 -2
  13. package/dist/ai/workflow.js.map +1 -1
  14. package/dist/{auth-headers-qL-ZeEtd.d.ts → chat-correlation-BsHD-tOQ.d.ts} +6 -1
  15. package/dist/{client-YO9Y1rkH.d.ts → client-CZ5eWH5v.d.ts} +6 -1
  16. package/dist/eve/agent/index.d.ts +4 -4
  17. package/dist/eve/agent/index.js +127 -238
  18. package/dist/eve/agent/index.js.map +1 -1
  19. package/dist/eve/index.d.ts +3 -3
  20. package/dist/eve/index.js +1 -26
  21. package/dist/eve/index.js.map +1 -1
  22. package/dist/eve/tools/admin/assign-tasks.js +44 -0
  23. package/dist/eve/tools/admin/assign-tasks.js.map +1 -1
  24. package/dist/eve/tools/admin/manage-groups.js +44 -0
  25. package/dist/eve/tools/admin/manage-groups.js.map +1 -1
  26. package/dist/eve/tools/admin/manage-team-members.js +44 -0
  27. package/dist/eve/tools/admin/manage-team-members.js.map +1 -1
  28. package/dist/eve/tools/admin/query-tasks.js +44 -0
  29. package/dist/eve/tools/admin/query-tasks.js.map +1 -1
  30. package/dist/eve/tools/identity/index.d.ts +1 -1
  31. package/dist/eve/tools/identity/index.js +2 -0
  32. package/dist/eve/tools/identity/index.js.map +1 -1
  33. package/dist/eve/tools/identity/my-access.js +2 -0
  34. package/dist/eve/tools/identity/my-access.js.map +1 -1
  35. package/dist/eve/tools/identity/whoami.d.ts +1 -1
  36. package/dist/eve/tools/identity/whoami.js +2 -0
  37. package/dist/eve/tools/identity/whoami.js.map +1 -1
  38. package/dist/eve/tools/inbox/create-task.d.ts +1 -1
  39. package/dist/eve/tools/inbox/create-task.js +56 -31
  40. package/dist/eve/tools/inbox/create-task.js.map +1 -1
  41. package/dist/eve/tools/inbox/index.d.ts +1 -1
  42. package/dist/eve/tools/inbox/index.js +56 -31
  43. package/dist/eve/tools/inbox/index.js.map +1 -1
  44. package/dist/eve/tools/index.d.ts +1 -1
  45. package/dist/eve/tools/index.js +68 -31
  46. package/dist/eve/tools/index.js.map +1 -1
  47. package/dist/{index-DoQN48Bm.d.ts → index-DePyAbTI.d.ts} +6 -3
  48. package/dist/index.d.ts +4 -4
  49. package/dist/index.js +26 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/{tenant-5YKDrdC-.d.ts → tenant-DmN0MMyC.d.ts} +1 -0
  52. package/dist/{tool-approval-bridge-aMA79Z1B.d.ts → tool-approval-bridge-DnGaRES4.d.ts} +1 -1
  53. package/dist/trigger/index.d.ts +2 -2
  54. package/dist/trigger/index.js +26 -2
  55. package/dist/trigger/index.js.map +1 -1
  56. package/dist/{trigger-CXrbKVCL.d.ts → trigger--qTIK0s6.d.ts} +2 -2
  57. package/dist/workflow/index.d.ts +2 -2
  58. package/dist/workflow/index.js +26 -2
  59. package/dist/workflow/index.js.map +1 -1
  60. package/package.json +3 -3
@@ -10,4 +10,9 @@ type RobotRockAuthConfig = {
10
10
  actingUserId?: string;
11
11
  };
12
12
 
13
- export type { RobotRockAuthConfig as R };
13
+ type ChatCorrelation = {
14
+ chatId?: string;
15
+ eveSessionId?: string;
16
+ };
17
+
18
+ export type { ChatCorrelation as C, RobotRockAuthConfig as R };
@@ -1,7 +1,7 @@
1
1
  import { TaskContextInput, AssignToInput, TaskPriority, ThreadUpdateStatus, TaskResponse, Task, ThreadUpdate, TaskContextFormatVersion, DiscriminatedApprovalResult } from './schemas/index.js';
2
2
  import { AgentChatSeedMessage, AgentChatStageHitlBody, AgentChatAuditInputBody, AgentChatAuditToolBody, AgentChatLinkTaskBody, listTasksQuerySchema, AgentAdminTaskSummary } from '@robotrock/core';
3
3
  import { z } from 'zod';
4
- import { R as RobotRockAuthConfig } from './auth-headers-qL-ZeEtd.js';
4
+ import { R as RobotRockAuthConfig, C as ChatCorrelation } from './chat-correlation-BsHD-tOQ.js';
5
5
 
6
6
  /** A chat created via {@link ChatsApi.create}. */
7
7
  type CreatedChat = {
@@ -66,6 +66,7 @@ declare function createChatsApi(config: {
66
66
  baseUrl: string;
67
67
  auth: RobotRockAuthConfig;
68
68
  app?: string;
69
+ chatCorrelation?: ChatCorrelation;
69
70
  }): ChatsApi;
70
71
 
71
72
  type RobotRockWebhookConfig = {
@@ -88,6 +89,8 @@ type RobotRockAdvancedConfig = {
88
89
  contextVersion?: TaskContextFormatVersion;
89
90
  };
90
91
  type RobotRockClientBaseConfig = {
92
+ /** Optional chat correlation headers for audit logging from agent sessions. */
93
+ chatCorrelation?: ChatCorrelation;
91
94
  /** Optional override for API key. Falls back to ROBOTROCK_API_KEY when agentService is unset. */
92
95
  apiKey?: string;
93
96
  /** Hosted-agent service auth (mutually exclusive with apiKey). */
@@ -95,6 +98,7 @@ type RobotRockClientBaseConfig = {
95
98
  token: string;
96
99
  tenantSlug: string;
97
100
  connectionId: string;
101
+ actingUserId?: string;
98
102
  };
99
103
  /**
100
104
  * Base URL for the RobotRock API
@@ -214,6 +218,7 @@ interface TasksApi {
214
218
  */
215
219
  declare class RobotRock {
216
220
  private readonly auth;
221
+ private readonly chatCorrelation?;
217
222
  private readonly baseUrl;
218
223
  private readonly app?;
219
224
  private readonly agentVersion?;
@@ -1,17 +1,17 @@
1
- export { a as TenantCaller, T as TenantRole, i as isAdminCaller, r as requireAdminCaller, b as requireTenantCaller, t as tryResolveTenantCaller } from '../../tenant-5YKDrdC-.js';
1
+ export { a as TenantCaller, T as TenantRole, i as isAdminCaller, r as requireAdminCaller, b as requireTenantCaller, t as tryResolveTenantCaller } from '../../tenant-DmN0MMyC.js';
2
2
  import { AuthFn, vercelOidc } from 'eve/channels/auth';
3
3
  import * as eve_channels_eve from 'eve/channels/eve';
4
- import { R as RobotRock, q as StagedChatHitlRequest, a as SendToHumanInput, S as SendToHumanActionInput, e as CreateChatResult } from '../../client-YO9Y1rkH.js';
4
+ import { R as RobotRock, q as StagedChatHitlRequest, a as SendToHumanInput, S as SendToHumanActionInput, e as CreateChatResult } from '../../client-CZ5eWH5v.js';
5
5
  import { SessionContext } from 'eve/context';
6
6
  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-DoQN48Bm.js';
10
+ export { R as ROBOTROCK_READY_HOOK_SLUG } from '../../index-DePyAbTI.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
- import '../../auth-headers-qL-ZeEtd.js';
14
+ import '../../chat-correlation-BsHD-tOQ.js';
15
15
  import '@robotrock/core/schemas';
16
16
  import '../../tool-reply-guidance-C3qrT1In.js';
17
17
 
@@ -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
@@ -1611,11 +1535,42 @@ function resolveRobotRockAuthConfig(overrides) {
1611
1535
  return { kind: "apiKey", apiKey };
1612
1536
  }
1613
1537
 
1538
+ // src/chat-correlation.ts
1539
+ var ROBOTROCK_CHAT_ID_HEADER = "x-robotrock-chat-id";
1540
+ var ROBOTROCK_EVE_SESSION_ID_HEADER = "x-robotrock-eve-session-id";
1541
+ function resolveChatCorrelationFromEnv() {
1542
+ const chatId = process.env.ROBOTROCK_CHAT_ID?.trim();
1543
+ const eveSessionId = process.env.ROBOTROCK_EVE_SESSION_ID?.trim();
1544
+ if (!chatId && !eveSessionId) {
1545
+ return void 0;
1546
+ }
1547
+ return {
1548
+ ...chatId ? { chatId } : {},
1549
+ ...eveSessionId ? { eveSessionId } : {}
1550
+ };
1551
+ }
1552
+ function buildChatCorrelationHeaders(correlation) {
1553
+ if (!correlation) {
1554
+ return {};
1555
+ }
1556
+ const headers = {};
1557
+ const chatId = correlation.chatId?.trim();
1558
+ const eveSessionId = correlation.eveSessionId?.trim();
1559
+ if (chatId) {
1560
+ headers[ROBOTROCK_CHAT_ID_HEADER] = chatId;
1561
+ }
1562
+ if (eveSessionId) {
1563
+ headers[ROBOTROCK_EVE_SESSION_ID_HEADER] = eveSessionId;
1564
+ }
1565
+ return headers;
1566
+ }
1567
+
1614
1568
  // src/chats.ts
1615
1569
  function createChatsApi(config) {
1616
1570
  const headers = () => ({
1617
1571
  "Content-Type": "application/json",
1618
- ...buildRobotRockAuthHeaders(config.auth)
1572
+ ...buildRobotRockAuthHeaders(config.auth),
1573
+ ...buildChatCorrelationHeaders(config.chatCorrelation)
1619
1574
  });
1620
1575
  return {
1621
1576
  async create(input) {
@@ -1825,6 +1780,7 @@ function serializeValidUntil(value) {
1825
1780
  }
1826
1781
  var RobotRock = class {
1827
1782
  auth;
1783
+ chatCorrelation;
1828
1784
  baseUrl;
1829
1785
  app;
1830
1786
  agentVersion;
@@ -1852,6 +1808,7 @@ var RobotRock = class {
1852
1808
  ...apiKey ? { apiKey } : {},
1853
1809
  ...agentService ? { agentService } : {}
1854
1810
  });
1811
+ this.chatCorrelation = config.chatCorrelation;
1855
1812
  this.baseUrl = config.baseUrl ?? getRobotRockApiBaseUrl();
1856
1813
  this.app = config.app;
1857
1814
  this.agentVersion = config.version ?? resolveAgentVersionFromEnv();
@@ -1869,13 +1826,15 @@ var RobotRock = class {
1869
1826
  this.chats = createChatsApi({
1870
1827
  baseUrl: this.baseUrl,
1871
1828
  auth: this.auth,
1872
- app: this.app
1829
+ app: this.app,
1830
+ chatCorrelation: this.chatCorrelation
1873
1831
  });
1874
1832
  }
1875
1833
  authHeaders(extra) {
1876
1834
  return {
1877
1835
  "Content-Type": "application/json",
1878
1836
  ...buildRobotRockAuthHeaders(this.auth),
1837
+ ...buildChatCorrelationHeaders(this.chatCorrelation),
1879
1838
  ...extra
1880
1839
  };
1881
1840
  }
@@ -2146,51 +2105,39 @@ function normalizeSendToHumanInput(task, clientDefaults) {
2146
2105
  };
2147
2106
  }
2148
2107
 
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
2108
  // src/eve/agent/client-from-session.ts
2172
2109
  var warnedMissingAuth = false;
2110
+ function resolveBoundChatCorrelation(ctx) {
2111
+ const caller = tryResolveTenantCaller(ctx);
2112
+ return {
2113
+ eveSessionId: ctx.session.id,
2114
+ ...caller?.chatId ? { chatId: caller.chatId } : {},
2115
+ ...resolveChatCorrelationFromEnv()
2116
+ };
2117
+ }
2173
2118
  function tryCreateBoundRobotRockClient(ctx) {
2174
2119
  const caller = tryResolveTenantCaller(ctx);
2175
2120
  const serviceToken = process.env.ROBOTROCK_AGENT_SERVICE_TOKEN?.trim();
2121
+ const chatCorrelation = resolveBoundChatCorrelation(ctx);
2176
2122
  if (caller?.connectionId && serviceToken) {
2177
2123
  return createClient({
2178
2124
  baseUrl: process.env.ROBOTROCK_BASE_URL?.trim(),
2125
+ chatCorrelation,
2179
2126
  agentService: {
2180
2127
  token: serviceToken,
2181
2128
  tenantSlug: caller.tenantSlug,
2182
- connectionId: caller.connectionId
2129
+ connectionId: caller.connectionId,
2130
+ actingUserId: caller.userId
2183
2131
  }
2184
2132
  });
2185
2133
  }
2186
2134
  const apiKey = process.env.ROBOTROCK_API_KEY?.trim();
2187
2135
  if (apiKey) {
2188
- return createClient(
2189
- resolveRobotRockConfig({
2190
- apiKey,
2191
- baseUrl: process.env.ROBOTROCK_BASE_URL?.trim()
2192
- })
2193
- );
2136
+ return createClient({
2137
+ apiKey,
2138
+ baseUrl: process.env.ROBOTROCK_BASE_URL?.trim(),
2139
+ chatCorrelation
2140
+ });
2194
2141
  }
2195
2142
  if (!warnedMissingAuth) {
2196
2143
  warnedMissingAuth = true;
@@ -2238,23 +2185,6 @@ function logAuditFailure(label, error) {
2238
2185
  const hint = error instanceof RobotRockError && error.statusCode === 405 ? " \u2014 set ROBOTROCK_BASE_URL=http://localhost:4001/v1 and run the local API" : "";
2239
2186
  console.warn(`robotrock-chat-audit: failed to ${label}${hint}`, error);
2240
2187
  }
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
2188
  async function postRobotRockChatInputAudit(ctx, payload) {
2259
2189
  const client = tryCreateBoundRobotRockClient(ctx);
2260
2190
  if (!client) {
@@ -2422,6 +2352,28 @@ function buildRobotRockTaskPayload(input, options) {
2422
2352
  return payload;
2423
2353
  }
2424
2354
 
2355
+ // src/env.ts
2356
+ function resolveRobotRockConfig(overrides) {
2357
+ const agentService = overrides?.agentService;
2358
+ const apiKey = overrides?.apiKey ?? process.env.ROBOTROCK_API_KEY;
2359
+ if (agentService && apiKey) {
2360
+ throw new Error(
2361
+ "RobotRock client cannot configure both apiKey and agentService."
2362
+ );
2363
+ }
2364
+ const baseUrl = overrides?.baseUrl ?? getRobotRockApiBaseUrl();
2365
+ const app = overrides?.app ?? process.env.ROBOTROCK_APP;
2366
+ if (agentService) {
2367
+ return app ? { agentService, baseUrl, app } : { agentService, baseUrl };
2368
+ }
2369
+ if (!apiKey) {
2370
+ throw new Error(
2371
+ "RobotRock API key is required. Set ROBOTROCK_API_KEY or pass agentService when creating the client."
2372
+ );
2373
+ }
2374
+ return app ? { apiKey, baseUrl, app } : { apiKey, baseUrl };
2375
+ }
2376
+
2425
2377
  // src/eve/agent/cron-chat.ts
2426
2378
  function resolveCronAgentIdentifier(agentIdentifier) {
2427
2379
  return agentIdentifier?.trim() || process.env.ROBOTROCK_CRON_AGENT_IDENTIFIER?.trim() || "robotrock-agent";
@@ -2451,8 +2403,6 @@ function defineRobotRockReadyHook() {
2451
2403
  // src/eve/agent/hooks/chat-audit.ts
2452
2404
  import { defineHook as defineHook2 } from "eve/hooks";
2453
2405
  var loggedIdempotencyKeys = /* @__PURE__ */ new Set();
2454
- var loggedToolCallIds = /* @__PURE__ */ new Set();
2455
- var pendingToolCallsBySession = /* @__PURE__ */ new Map();
2456
2406
  function toEveInputRequest(request) {
2457
2407
  return {
2458
2408
  requestId: request.requestId,
@@ -2462,22 +2412,6 @@ function toEveInputRequest(request) {
2462
2412
  ...request.options ? { options: request.options } : {}
2463
2413
  };
2464
2414
  }
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
2415
  async function logPendingInputResponse(ctx, pending, response) {
2482
2416
  const caller = tryResolveTenantCaller(ctx);
2483
2417
  if (!caller) {
@@ -2514,70 +2448,11 @@ async function logPendingInputResponse(ctx, pending, response) {
2514
2448
  });
2515
2449
  loggedIdempotencyKeys.add(idempotencyKey);
2516
2450
  }
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
2451
  function resetRobotrockChatAuditIdempotencyKeys() {
2561
2452
  loggedIdempotencyKeys.clear();
2562
- loggedToolCallIds.clear();
2563
- pendingToolCallsBySession.clear();
2564
2453
  }
2565
2454
  var robotrockChatAuditHook = defineHook2({
2566
2455
  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
2456
  async "input.requested"(event, ctx) {
2582
2457
  const requests = [];
2583
2458
  for (const request of event.data.requests) {
@@ -2621,37 +2496,39 @@ var robotrockChatAuditHook = defineHook2({
2621
2496
  },
2622
2497
  async "action.result"(event, ctx) {
2623
2498
  const result = event.data.result;
2624
- if (result.kind === "tool-result") {
2625
- const staged = await fetchRobotRockStagedHitl(ctx, ctx.session.id);
2626
- const pending = staged.find((entry) => entry.toolCallId === result.callId);
2627
- if (pending) {
2628
- const idempotencyKey = `${ctx.session.id}:${pending.requestId}`;
2629
- if (!loggedIdempotencyKeys.has(idempotencyKey)) {
2630
- if (pending.toolName === "ask_question") {
2631
- const parsed = parseEveAskQuestionToolOutput(result.output);
2632
- if (parsed) {
2633
- await logPendingInputResponse(ctx, pending, {
2634
- requestId: pending.requestId,
2635
- ...parsed
2636
- });
2637
- }
2638
- } else if (isEveApprovalInputRequest(toEveInputRequest(pending))) {
2639
- if (event.data.status === "rejected") {
2640
- await logPendingInputResponse(ctx, pending, {
2641
- requestId: pending.requestId,
2642
- optionId: "deny"
2643
- });
2644
- } else if (event.data.status === "completed") {
2645
- await logPendingInputResponse(ctx, pending, {
2646
- requestId: pending.requestId,
2647
- optionId: "approve"
2648
- });
2649
- }
2650
- }
2651
- }
2499
+ if (result.kind !== "tool-result") {
2500
+ return;
2501
+ }
2502
+ const staged = await fetchRobotRockStagedHitl(ctx, ctx.session.id);
2503
+ const pending = staged.find((entry) => entry.toolCallId === result.callId);
2504
+ if (!pending) {
2505
+ return;
2506
+ }
2507
+ const idempotencyKey = `${ctx.session.id}:${pending.requestId}`;
2508
+ if (loggedIdempotencyKeys.has(idempotencyKey)) {
2509
+ return;
2510
+ }
2511
+ if (pending.toolName === "ask_question") {
2512
+ const parsed = parseEveAskQuestionToolOutput(result.output);
2513
+ if (parsed) {
2514
+ await logPendingInputResponse(ctx, pending, {
2515
+ requestId: pending.requestId,
2516
+ ...parsed
2517
+ });
2518
+ }
2519
+ } else if (isEveApprovalInputRequest(toEveInputRequest(pending))) {
2520
+ if (event.data.status === "rejected") {
2521
+ await logPendingInputResponse(ctx, pending, {
2522
+ requestId: pending.requestId,
2523
+ optionId: "deny"
2524
+ });
2525
+ } else if (event.data.status === "completed") {
2526
+ await logPendingInputResponse(ctx, pending, {
2527
+ requestId: pending.requestId,
2528
+ optionId: "approve"
2529
+ });
2652
2530
  }
2653
2531
  }
2654
- await logToolExecutionFromResult(ctx, event);
2655
2532
  }
2656
2533
  }
2657
2534
  });
@@ -2671,6 +2548,7 @@ async function agentAdminFetch(config, path, init) {
2671
2548
  headers: {
2672
2549
  "Content-Type": "application/json",
2673
2550
  ...buildRobotRockAuthHeaders(config.auth),
2551
+ ...buildChatCorrelationHeaders(config.chatCorrelation),
2674
2552
  ...init?.headers ?? {}
2675
2553
  }
2676
2554
  });
@@ -2780,13 +2658,23 @@ function createAgentAdminApi(config) {
2780
2658
  }
2781
2659
  };
2782
2660
  }
2661
+ function resolveBoundChatCorrelation2(ctx) {
2662
+ const caller = tryResolveTenantCaller(ctx);
2663
+ return {
2664
+ eveSessionId: ctx.session.id,
2665
+ ...caller?.chatId ? { chatId: caller.chatId } : {},
2666
+ ...resolveChatCorrelationFromEnv()
2667
+ };
2668
+ }
2783
2669
  function createBoundAgentAdminClient(ctx) {
2784
2670
  const caller = requireTenantCaller(ctx);
2785
2671
  const baseUrl = process.env.ROBOTROCK_BASE_URL?.trim();
2786
2672
  const serviceToken = process.env.ROBOTROCK_AGENT_SERVICE_TOKEN?.trim();
2673
+ const chatCorrelation = resolveBoundChatCorrelation2(ctx);
2787
2674
  if (caller.connectionId && serviceToken) {
2788
2675
  return createAgentAdminApi({
2789
2676
  baseUrl,
2677
+ chatCorrelation,
2790
2678
  auth: resolveRobotRockAuthConfig({
2791
2679
  agentService: {
2792
2680
  token: serviceToken,
@@ -2801,6 +2689,7 @@ function createBoundAgentAdminClient(ctx) {
2801
2689
  if (apiKey) {
2802
2690
  return createAgentAdminApi({
2803
2691
  baseUrl,
2692
+ chatCorrelation,
2804
2693
  auth: {
2805
2694
  kind: "apiKey",
2806
2695
  apiKey,