@agent-native/core 0.98.6 → 0.98.8

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 (88) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/docs/content/external-agents.mdx +22 -12
  4. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +8 -2
  5. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +8 -2
  6. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +8 -2
  7. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +8 -2
  8. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +8 -2
  9. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +8 -2
  10. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +8 -2
  11. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +8 -2
  12. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +8 -2
  13. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +8 -2
  14. package/corpus/core/package.json +1 -1
  15. package/corpus/core/src/a2a/handlers.ts +6 -5
  16. package/corpus/core/src/a2a/task-store.ts +63 -0
  17. package/corpus/core/src/client/session-replay.ts +90 -6
  18. package/corpus/core/src/integrations/adapters/slack.ts +110 -19
  19. package/corpus/core/src/integrations/identity.ts +103 -39
  20. package/corpus/core/src/integrations/pending-tasks-retry-job.ts +2 -1
  21. package/corpus/core/src/integrations/pending-tasks-store.ts +1 -1
  22. package/corpus/core/src/integrations/plugin.ts +215 -8
  23. package/corpus/core/src/integrations/types.ts +37 -0
  24. package/corpus/core/src/integrations/webhook-handler.ts +1 -0
  25. package/corpus/core/src/mcp/builtin-tools.ts +5 -2
  26. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +4 -1
  27. package/corpus/templates/analytics/AGENTS.md +9 -9
  28. package/corpus/templates/analytics/changelog/2026-07-12-analytics-uses-the-full-in-app-agent-for-multi-step-incident.md +6 -0
  29. package/corpus/templates/analytics/server/handlers/session-replay.ts +15 -9
  30. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +23 -5
  31. package/corpus/templates/analytics/server/lib/session-replay.ts +26 -5
  32. package/corpus/templates/analytics/server/plugins/agent-chat.ts +4 -1
  33. package/corpus/templates/analytics/server/routes/api/session-replay/agent-diagnostics.json.get.ts +8 -5
  34. package/corpus/templates/analytics/server/routes/api/session-replay/agent-events.json.get.ts +8 -3
  35. package/corpus/templates/calendar/app/components/calendar/DeleteEventDialog.tsx +12 -2
  36. package/dist/a2a/handlers.d.ts.map +1 -1
  37. package/dist/a2a/handlers.js +6 -6
  38. package/dist/a2a/handlers.js.map +1 -1
  39. package/dist/a2a/task-store.d.ts +12 -0
  40. package/dist/a2a/task-store.d.ts.map +1 -1
  41. package/dist/a2a/task-store.js +54 -0
  42. package/dist/a2a/task-store.js.map +1 -1
  43. package/dist/client/session-replay.d.ts.map +1 -1
  44. package/dist/client/session-replay.js +71 -9
  45. package/dist/client/session-replay.js.map +1 -1
  46. package/dist/collab/routes.d.ts +1 -1
  47. package/dist/collab/struct-routes.d.ts +1 -1
  48. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  49. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  50. package/dist/integrations/adapters/slack.js +94 -11
  51. package/dist/integrations/adapters/slack.js.map +1 -1
  52. package/dist/integrations/identity.d.ts +19 -2
  53. package/dist/integrations/identity.d.ts.map +1 -1
  54. package/dist/integrations/identity.js +76 -34
  55. package/dist/integrations/identity.js.map +1 -1
  56. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  57. package/dist/integrations/pending-tasks-retry-job.js +2 -1
  58. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  59. package/dist/integrations/pending-tasks-store.js +1 -1
  60. package/dist/integrations/pending-tasks-store.js.map +1 -1
  61. package/dist/integrations/plugin.d.ts.map +1 -1
  62. package/dist/integrations/plugin.js +165 -9
  63. package/dist/integrations/plugin.js.map +1 -1
  64. package/dist/integrations/types.d.ts +32 -0
  65. package/dist/integrations/types.d.ts.map +1 -1
  66. package/dist/integrations/types.js.map +1 -1
  67. package/dist/integrations/webhook-handler.js +1 -0
  68. package/dist/integrations/webhook-handler.js.map +1 -1
  69. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  70. package/dist/mcp/builtin-tools.js +5 -2
  71. package/dist/mcp/builtin-tools.js.map +1 -1
  72. package/dist/notifications/routes.d.ts +1 -1
  73. package/dist/progress/routes.d.ts +1 -1
  74. package/dist/resources/handlers.d.ts +3 -3
  75. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  76. package/dist/server/transcribe-voice.d.ts +1 -1
  77. package/docs/content/external-agents.mdx +22 -12
  78. package/docs/content/locales/ar-SA/external-agents.mdx +8 -2
  79. package/docs/content/locales/de-DE/external-agents.mdx +8 -2
  80. package/docs/content/locales/es-ES/external-agents.mdx +8 -2
  81. package/docs/content/locales/fr-FR/external-agents.mdx +8 -2
  82. package/docs/content/locales/hi-IN/external-agents.mdx +8 -2
  83. package/docs/content/locales/ja-JP/external-agents.mdx +8 -2
  84. package/docs/content/locales/ko-KR/external-agents.mdx +8 -2
  85. package/docs/content/locales/pt-BR/external-agents.mdx +8 -2
  86. package/docs/content/locales/zh-CN/external-agents.mdx +8 -2
  87. package/docs/content/locales/zh-TW/external-agents.mdx +8 -2
  88. package/package.json +1 -1
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- error: string;
30
29
  ok?: undefined;
30
+ error: string;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- error: string;
17
16
  ok?: undefined;
17
+ error: string;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -17,12 +17,12 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
+ error?: undefined;
20
21
  configured?: undefined;
21
22
  connectPath?: undefined;
22
23
  url: string;
23
24
  id: string;
24
25
  provider: string;
25
- error?: undefined;
26
26
  }>;
27
27
  export default _default;
28
28
  //# sourceMappingURL=upload-image.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/integrations/adapters/slack.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAQhB,MAAM,aAAa,CAAC;AA+BrB,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7E,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,GAAE,mBAAwB,GAChC,eAAe,CAmgBjB"}
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/integrations/adapters/slack.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAQhB,MAAM,aAAa,CAAC;AAwDrB,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7E,kEAAkE;IAClE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,GAAE,mBAAwB,GAChC,eAAe,CAgjBjB"}
@@ -25,6 +25,29 @@ const SLACK_IDENTITY_CACHE_TTL_MS = 10 * 60 * 1_000;
25
25
  const SLACK_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
26
26
  const SLACK_IDENTITY_CACHE_MAX_ENTRIES = 1_000;
27
27
  const slackIdentityCache = new Map();
28
+ // Deduped system notices send at most once per key per TTL so senders are
29
+ // informed without being spammed per message. Callers pick the window: the
30
+ // anonymous-tier heads-up uses the default day-long TTL; decline replies pass
31
+ // a short TTL so a persistent condition still reminds the sender occasionally.
32
+ const SLACK_SYSTEM_NOTICE_DEDUPE_TTL_MS = 24 * 60 * 60 * 1_000;
33
+ const SLACK_SYSTEM_NOTICE_CACHE_MAX_ENTRIES = 1_000;
34
+ const slackSystemNoticeCache = new Map();
35
+ /** Returns true when a deduped notice should send now, claiming the slot. */
36
+ function claimSlackSystemNoticeSlot(key, ttlMs = SLACK_SYSTEM_NOTICE_DEDUPE_TTL_MS) {
37
+ const now = Date.now();
38
+ const expiresAt = slackSystemNoticeCache.get(key);
39
+ if (expiresAt && expiresAt > now)
40
+ return false;
41
+ if (expiresAt)
42
+ slackSystemNoticeCache.delete(key);
43
+ if (slackSystemNoticeCache.size >= SLACK_SYSTEM_NOTICE_CACHE_MAX_ENTRIES) {
44
+ const oldestKey = slackSystemNoticeCache.keys().next().value;
45
+ if (oldestKey)
46
+ slackSystemNoticeCache.delete(oldestKey);
47
+ }
48
+ slackSystemNoticeCache.set(key, now + ttlMs);
49
+ return true;
50
+ }
28
51
  /**
29
52
  * Create a Slack platform adapter.
30
53
  *
@@ -201,7 +224,10 @@ export function slackAdapter(options = {}) {
201
224
  triggerKind: isDm ? "dm" : isMention ? "mention" : "thread_reply",
202
225
  conversationType: isDm ? "dm" : "unknown",
203
226
  tenantId: teamId,
204
- actorTrust: { memberType: "unknown", verified: true },
227
+ // The signed Slack envelope authenticates the workspace, not the
228
+ // sender's membership tier. `users.info` hydration below is the
229
+ // authority that may promote this to a verified member.
230
+ actorTrust: { memberType: "unknown", verified: false },
205
231
  platformContext: {
206
232
  channelId: e.channel,
207
233
  channelType: e.channel_type,
@@ -388,6 +414,45 @@ export function slackAdapter(options = {}) {
388
414
  throw err;
389
415
  }
390
416
  },
417
+ async sendSystemNotice(incoming, text, opts) {
418
+ if (!text.trim())
419
+ return;
420
+ const dedupeKey = opts?.dedupeKey;
421
+ if (dedupeKey &&
422
+ !claimSlackSystemNoticeSlot(dedupeKey, opts?.dedupeTtlMs)) {
423
+ return;
424
+ }
425
+ try {
426
+ const token = await resolveBotToken(incoming);
427
+ if (!token) {
428
+ if (dedupeKey)
429
+ slackSystemNoticeCache.delete(dedupeKey);
430
+ throw new Error("Slack bot token not configured for system notice");
431
+ }
432
+ const channelId = incoming.platformContext.channelId;
433
+ if (typeof channelId !== "string" || !channelId) {
434
+ if (dedupeKey)
435
+ slackSystemNoticeCache.delete(dedupeKey);
436
+ throw new Error("Slack channel id missing for system notice");
437
+ }
438
+ const threadTs = typeof incoming.platformContext.threadTs === "string"
439
+ ? incoming.platformContext.threadTs
440
+ : undefined;
441
+ await postFresh(token, channelId, threadTs, {
442
+ text,
443
+ unfurl_links: false,
444
+ unfurl_media: false,
445
+ mrkdwn: true,
446
+ });
447
+ }
448
+ catch (error) {
449
+ // A failed delivery did not inform the sender, so release the slot and
450
+ // allow the next message to retry instead of suppressing notices for a day.
451
+ if (dedupeKey)
452
+ slackSystemNoticeCache.delete(dedupeKey);
453
+ throw error;
454
+ }
455
+ },
391
456
  async sendMessageToTarget(message, target) {
392
457
  const targetContext = {
393
458
  platform: "slack",
@@ -920,7 +985,9 @@ async function resolveSlackUserIdentity(token, incoming) {
920
985
  : typeof user.user.name === "string" && user.user.name.trim()
921
986
  ? user.user.name.trim()
922
987
  : null,
923
- memberType: user.user.is_ultra_restricted
988
+ // is_stranger marks Slack Connect DM participants from another
989
+ // workspace; they must map to "external", never "member".
990
+ memberType: user.user.is_stranger || user.user.is_ultra_restricted
924
991
  ? "external"
925
992
  : user.user.is_restricted
926
993
  ? "guest"
@@ -947,8 +1014,22 @@ async function resolveSlackUserIdentity(token, incoming) {
947
1014
  }
948
1015
  async function hydrateSlackIdentity(token, incoming) {
949
1016
  const identity = await resolveSlackUserIdentity(token, incoming);
950
- if (!identity)
951
- return incoming;
1017
+ if (!identity) {
1018
+ // Context hydration can call users.info again after the webhook identity
1019
+ // pass. A transient failure on that second lookup is not evidence that a
1020
+ // previously verified sender became unverified; preserve the stronger
1021
+ // identity instead of replacing it with a negative-cache result.
1022
+ if (incoming.senderVerified === true &&
1023
+ incoming.senderEmail?.trim() &&
1024
+ incoming.actorTrust?.verified === true) {
1025
+ return incoming;
1026
+ }
1027
+ return {
1028
+ ...incoming,
1029
+ senderVerified: false,
1030
+ actorTrust: { memberType: "unknown", verified: false },
1031
+ };
1032
+ }
952
1033
  return {
953
1034
  ...incoming,
954
1035
  ...(identity.name ? { senderName: identity.name } : {}),
@@ -1057,8 +1138,6 @@ async function hydrateSlackContext(token, incoming) {
1057
1138
  })
1058
1139
  : [];
1059
1140
  const profile = identity;
1060
- const isGuest = identity?.memberType === "guest";
1061
- const isExternal = identity?.memberType === "external";
1062
1141
  const isPrivate = conversation?.channel?.is_private === true;
1063
1142
  const isExternalShared = conversation?.channel?.is_ext_shared === true;
1064
1143
  const isMpim = conversation?.channel?.is_mpim === true;
@@ -1099,11 +1178,15 @@ async function hydrateSlackContext(token, incoming) {
1099
1178
  ? { senderEmail: profile.email, senderVerified: true }
1100
1179
  : { senderVerified: false }),
1101
1180
  conversationType,
1102
- actorTrust: {
1103
- memberType: identity?.memberType ??
1104
- (isExternal ? "external" : isGuest ? "guest" : "member"),
1105
- verified: true,
1106
- },
1181
+ // Conversation hydration must not promote a caller when users.info was
1182
+ // unavailable. Preserve the result of the earlier identity-only hydration
1183
+ // unless this request independently resolved the Slack user.
1184
+ actorTrust: identity
1185
+ ? { memberType: identity.memberType, verified: true }
1186
+ : (incoming.actorTrust ?? {
1187
+ memberType: "unknown",
1188
+ verified: false,
1189
+ }),
1107
1190
  contextMessages: hydratedMessages,
1108
1191
  ...(hydratedFiles.length ? { files: hydratedFiles.slice(0, 20) } : {}),
1109
1192
  platformContext: {