@agent-native/core 0.98.6 → 0.98.7

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 (80) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +6 -0
  3. package/corpus/core/docs/content/external-agents.mdx +15 -11
  4. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +3 -1
  5. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +3 -1
  6. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +3 -1
  7. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +3 -1
  8. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +3 -1
  9. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +3 -1
  10. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +3 -1
  11. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +3 -1
  12. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +3 -1
  13. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +3 -1
  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 +67 -5
  18. package/corpus/core/src/integrations/adapters/slack.ts +99 -19
  19. package/corpus/core/src/integrations/identity.ts +103 -39
  20. package/corpus/core/src/integrations/plugin.ts +81 -9
  21. package/corpus/core/src/integrations/types.ts +30 -0
  22. package/corpus/core/src/integrations/webhook-handler.ts +1 -0
  23. package/corpus/core/src/mcp/builtin-tools.ts +5 -2
  24. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +4 -1
  25. package/corpus/templates/analytics/AGENTS.md +9 -9
  26. package/corpus/templates/analytics/changelog/2026-07-12-analytics-uses-the-full-in-app-agent-for-multi-step-incident.md +6 -0
  27. package/corpus/templates/analytics/server/handlers/session-replay.ts +15 -9
  28. package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +23 -5
  29. package/corpus/templates/analytics/server/lib/session-replay.ts +26 -5
  30. package/corpus/templates/analytics/server/plugins/agent-chat.ts +4 -1
  31. package/corpus/templates/analytics/server/routes/api/session-replay/agent-diagnostics.json.get.ts +8 -5
  32. package/corpus/templates/analytics/server/routes/api/session-replay/agent-events.json.get.ts +8 -3
  33. package/corpus/templates/calendar/app/components/calendar/DeleteEventDialog.tsx +12 -2
  34. package/dist/a2a/handlers.d.ts.map +1 -1
  35. package/dist/a2a/handlers.js +6 -6
  36. package/dist/a2a/handlers.js.map +1 -1
  37. package/dist/a2a/task-store.d.ts +12 -0
  38. package/dist/a2a/task-store.d.ts.map +1 -1
  39. package/dist/a2a/task-store.js +54 -0
  40. package/dist/a2a/task-store.js.map +1 -1
  41. package/dist/client/session-replay.d.ts.map +1 -1
  42. package/dist/client/session-replay.js +53 -8
  43. package/dist/client/session-replay.js.map +1 -1
  44. package/dist/collab/routes.d.ts +1 -1
  45. package/dist/collab/struct-routes.d.ts +1 -1
  46. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  47. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  48. package/dist/integrations/adapters/slack.js +85 -11
  49. package/dist/integrations/adapters/slack.js.map +1 -1
  50. package/dist/integrations/identity.d.ts +19 -2
  51. package/dist/integrations/identity.d.ts.map +1 -1
  52. package/dist/integrations/identity.js +76 -34
  53. package/dist/integrations/identity.js.map +1 -1
  54. package/dist/integrations/plugin.d.ts.map +1 -1
  55. package/dist/integrations/plugin.js +56 -6
  56. package/dist/integrations/plugin.js.map +1 -1
  57. package/dist/integrations/types.d.ts +25 -0
  58. package/dist/integrations/types.d.ts.map +1 -1
  59. package/dist/integrations/types.js.map +1 -1
  60. package/dist/integrations/webhook-handler.js +1 -0
  61. package/dist/integrations/webhook-handler.js.map +1 -1
  62. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  63. package/dist/mcp/builtin-tools.js +5 -2
  64. package/dist/mcp/builtin-tools.js.map +1 -1
  65. package/dist/progress/routes.d.ts +1 -1
  66. package/dist/resources/handlers.d.ts +3 -3
  67. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  68. package/dist/server/transcribe-voice.d.ts +1 -1
  69. package/docs/content/external-agents.mdx +15 -11
  70. package/docs/content/locales/ar-SA/external-agents.mdx +3 -1
  71. package/docs/content/locales/de-DE/external-agents.mdx +3 -1
  72. package/docs/content/locales/es-ES/external-agents.mdx +3 -1
  73. package/docs/content/locales/fr-FR/external-agents.mdx +3 -1
  74. package/docs/content/locales/hi-IN/external-agents.mdx +3 -1
  75. package/docs/content/locales/ja-JP/external-agents.mdx +3 -1
  76. package/docs/content/locales/ko-KR/external-agents.mdx +3 -1
  77. package/docs/content/locales/pt-BR/external-agents.mdx +3 -1
  78. package/docs/content/locales/zh-CN/external-agents.mdx +3 -1
  79. package/docs/content/locales/zh-TW/external-agents.mdx +3 -1
  80. package/package.json +1 -1
@@ -41,9 +41,9 @@ export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import
41
41
  * Body: { text: string, fieldName?: string, requestSource?: string }
42
42
  */
43
43
  export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
44
+ text?: undefined;
44
45
  ok?: undefined;
45
46
  error: string;
46
- text?: undefined;
47
47
  } | {
48
48
  error?: undefined;
49
49
  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
+ return;
431
+ }
432
+ const channelId = incoming.platformContext.channelId;
433
+ if (typeof channelId !== "string" || !channelId) {
434
+ if (dedupeKey)
435
+ slackSystemNoticeCache.delete(dedupeKey);
436
+ return;
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,13 @@ 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
+ return {
1019
+ ...incoming,
1020
+ senderVerified: false,
1021
+ actorTrust: { memberType: "unknown", verified: false },
1022
+ };
1023
+ }
952
1024
  return {
953
1025
  ...incoming,
954
1026
  ...(identity.name ? { senderName: identity.name } : {}),
@@ -1057,8 +1129,6 @@ async function hydrateSlackContext(token, incoming) {
1057
1129
  })
1058
1130
  : [];
1059
1131
  const profile = identity;
1060
- const isGuest = identity?.memberType === "guest";
1061
- const isExternal = identity?.memberType === "external";
1062
1132
  const isPrivate = conversation?.channel?.is_private === true;
1063
1133
  const isExternalShared = conversation?.channel?.is_ext_shared === true;
1064
1134
  const isMpim = conversation?.channel?.is_mpim === true;
@@ -1099,11 +1169,15 @@ async function hydrateSlackContext(token, incoming) {
1099
1169
  ? { senderEmail: profile.email, senderVerified: true }
1100
1170
  : { senderVerified: false }),
1101
1171
  conversationType,
1102
- actorTrust: {
1103
- memberType: identity?.memberType ??
1104
- (isExternal ? "external" : isGuest ? "guest" : "member"),
1105
- verified: true,
1106
- },
1172
+ // Conversation hydration must not promote a caller when users.info was
1173
+ // unavailable. Preserve the result of the earlier identity-only hydration
1174
+ // unless this request independently resolved the Slack user.
1175
+ actorTrust: identity
1176
+ ? { memberType: identity.memberType, verified: true }
1177
+ : (incoming.actorTrust ?? {
1178
+ memberType: "unknown",
1179
+ verified: false,
1180
+ }),
1107
1181
  contextMessages: hydratedMessages,
1108
1182
  ...(hydratedFiles.length ? { files: hydratedFiles.slice(0, 20) } : {}),
1109
1183
  platformContext: {