@agent-native/core 0.98.5 → 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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +18 -0
- package/corpus/core/docs/content/external-agents.mdx +66 -7
- package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +40 -7
- package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +41 -7
- package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +41 -7
- package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +41 -7
- package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +40 -7
- package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +40 -7
- package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +40 -7
- package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +41 -7
- package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +39 -7
- package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +39 -7
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/handlers.ts +101 -26
- package/corpus/core/src/a2a/task-store.ts +128 -3
- package/corpus/core/src/client/session-replay.ts +67 -5
- package/corpus/core/src/integrations/adapters/slack.ts +207 -17
- package/corpus/core/src/integrations/identity-links-store.ts +210 -0
- package/corpus/core/src/integrations/identity.ts +196 -0
- package/corpus/core/src/integrations/index.ts +6 -0
- package/corpus/core/src/integrations/plugin.ts +130 -1
- package/corpus/core/src/integrations/types.ts +37 -0
- package/corpus/core/src/integrations/webhook-handler.ts +1 -0
- package/corpus/core/src/mcp/build-server.ts +127 -22
- package/corpus/core/src/mcp/builtin-tools.ts +5 -2
- package/corpus/core/src/mcp/external-agent-policy.ts +18 -0
- package/corpus/core/src/mcp/index.ts +1 -0
- package/corpus/core/src/server/agent-chat/plugin-options.ts +12 -1
- package/corpus/core/src/server/agent-chat/script-entries.ts +20 -3
- package/corpus/core/src/server/agent-chat-plugin.ts +3 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +34 -5
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +4 -1
- package/corpus/templates/analytics/AGENTS.md +20 -5
- package/corpus/templates/analytics/actions/create-session-replay-agent-link.ts +0 -1
- package/corpus/templates/analytics/actions/get-session-replay-events.ts +0 -1
- package/corpus/templates/analytics/actions/get-session-replay-timeline.ts +40 -0
- package/corpus/templates/analytics/actions/list-error-issues.ts +12 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +4 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +48 -17
- package/corpus/templates/analytics/changelog/2026-07-12-analytics-uses-the-full-in-app-agent-for-multi-step-incident.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-connected-external-agents-can-now-look-up-sessions-error-iss.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-12-session-identities-stay-visible-when-demo-mode-is-off.md +6 -0
- package/corpus/templates/analytics/server/handlers/session-replay.ts +15 -9
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +2 -2
- package/corpus/templates/analytics/server/lib/error-capture.ts +47 -5
- package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +72 -22
- package/corpus/templates/analytics/server/lib/session-replay.ts +41 -11
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -0
- package/corpus/templates/analytics/server/plugins/db.ts +15 -0
- package/corpus/templates/analytics/server/routes/api/session-replay/agent-diagnostics.json.get.ts +8 -5
- package/corpus/templates/analytics/server/routes/api/session-replay/agent-events.json.get.ts +8 -3
- package/corpus/templates/calendar/app/components/calendar/DeleteEventDialog.tsx +12 -2
- package/corpus/templates/forms/app/global.css +54 -8
- package/corpus/templates/forms/app/pages/AskPage.tsx +35 -13
- package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +11 -17
- package/corpus/templates/forms/app/pages/ResponsesPage.tsx +8 -5
- package/corpus/templates/forms/changelog/2026-07-12-ask-forms-suggestions-now-sit-beneath-the-composer-for-a-tig.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-12-builder-response-tables-now-fill-the-view-without-a-redundan.md +6 -0
- package/corpus/templates/forms/changelog/2026-07-12-response-tables-now-fill-the-available-pane-with-a-flexible-.md +6 -0
- package/corpus/templates/mail/AGENTS.md +3 -1
- package/corpus/templates/mail/server/lib/mail-integrations.ts +3 -0
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +89 -20
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/task-store.d.ts +32 -1
- package/dist/a2a/task-store.d.ts.map +1 -1
- package/dist/a2a/task-store.js +111 -4
- package/dist/a2a/task-store.js.map +1 -1
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +53 -8
- package/dist/client/session-replay.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +176 -17
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/identity-links-store.d.ts +23 -0
- package/dist/integrations/identity-links-store.d.ts.map +1 -0
- package/dist/integrations/identity-links-store.js +158 -0
- package/dist/integrations/identity-links-store.js.map +1 -0
- package/dist/integrations/identity.d.ts +28 -0
- package/dist/integrations/identity.d.ts.map +1 -0
- package/dist/integrations/identity.js +142 -0
- package/dist/integrations/identity.js.map +1 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +2 -0
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/plugin.d.ts.map +1 -1
- package/dist/integrations/plugin.js +93 -1
- package/dist/integrations/plugin.js.map +1 -1
- package/dist/integrations/types.d.ts +31 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/webhook-handler.js +1 -0
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/mcp/build-server.d.ts +9 -2
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +97 -20
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/builtin-tools.d.ts.map +1 -1
- package/dist/mcp/builtin-tools.js +5 -2
- package/dist/mcp/builtin-tools.js.map +1 -1
- package/dist/mcp/external-agent-policy.d.ts +19 -0
- package/dist/mcp/external-agent-policy.d.ts.map +1 -0
- package/dist/mcp/external-agent-policy.js +2 -0
- package/dist/mcp/external-agent-policy.js.map +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/server/agent-chat/plugin-options.d.ts +11 -1
- package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
- package/dist/server/agent-chat/plugin-options.js.map +1 -1
- package/dist/server/agent-chat/script-entries.d.ts.map +1 -1
- package/dist/server/agent-chat/script-entries.js +16 -2
- package/dist/server/agent-chat/script-entries.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +3 -0
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +34 -5
- package/docs/content/external-agents.mdx +66 -7
- package/docs/content/locales/ar-SA/external-agents.mdx +40 -7
- package/docs/content/locales/de-DE/external-agents.mdx +41 -7
- package/docs/content/locales/es-ES/external-agents.mdx +41 -7
- package/docs/content/locales/fr-FR/external-agents.mdx +41 -7
- package/docs/content/locales/hi-IN/external-agents.mdx +40 -7
- package/docs/content/locales/ja-JP/external-agents.mdx +40 -7
- package/docs/content/locales/ko-KR/external-agents.mdx +40 -7
- package/docs/content/locales/pt-BR/external-agents.mdx +41 -7
- package/docs/content/locales/zh-CN/external-agents.mdx +39 -7
- package/docs/content/locales/zh-TW/external-agents.mdx +39 -7
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +34 -5
package/dist/collab/routes.d.ts
CHANGED
|
@@ -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;
|
|
@@ -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;
|
|
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"}
|
|
@@ -18,6 +18,36 @@ const SLACK_PERMALINK_TIMEOUT_MS = 1_000;
|
|
|
18
18
|
const SLACK_CONTEXT_MESSAGE_LIMIT = 15;
|
|
19
19
|
const SLACK_CONTEXT_TEXT_LIMIT = 2_000;
|
|
20
20
|
const SLACK_CALM_PROGRESS_THRESHOLD_SECONDS = 30;
|
|
21
|
+
const SLACK_IDENTITY_TIMEOUT_MS = 1_000;
|
|
22
|
+
const SLACK_IDENTITY_CACHE_TTL_MS = 10 * 60 * 1_000;
|
|
23
|
+
// Failed users.info lookups only get a short negative TTL: a transient Slack
|
|
24
|
+
// API blip must not fail-close a sender's identity (and DMs) for 10 minutes.
|
|
25
|
+
const SLACK_IDENTITY_NEGATIVE_CACHE_TTL_MS = 30 * 1_000;
|
|
26
|
+
const SLACK_IDENTITY_CACHE_MAX_ENTRIES = 1_000;
|
|
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
|
+
}
|
|
21
51
|
/**
|
|
22
52
|
* Create a Slack platform adapter.
|
|
23
53
|
*
|
|
@@ -194,7 +224,10 @@ export function slackAdapter(options = {}) {
|
|
|
194
224
|
triggerKind: isDm ? "dm" : isMention ? "mention" : "thread_reply",
|
|
195
225
|
conversationType: isDm ? "dm" : "unknown",
|
|
196
226
|
tenantId: teamId,
|
|
197
|
-
|
|
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 },
|
|
198
231
|
platformContext: {
|
|
199
232
|
channelId: e.channel,
|
|
200
233
|
channelType: e.channel_type,
|
|
@@ -283,6 +316,12 @@ export function slackAdapter(options = {}) {
|
|
|
283
316
|
return incoming;
|
|
284
317
|
return hydrateSlackContext(token, incoming);
|
|
285
318
|
},
|
|
319
|
+
async hydrateIncomingIdentity(incoming) {
|
|
320
|
+
const token = await resolveBotToken(incoming);
|
|
321
|
+
if (!token)
|
|
322
|
+
return incoming;
|
|
323
|
+
return hydrateSlackIdentity(token, incoming);
|
|
324
|
+
},
|
|
286
325
|
async startRunProgress(incoming) {
|
|
287
326
|
const token = await resolveBotToken(incoming);
|
|
288
327
|
if (!token)
|
|
@@ -375,6 +414,45 @@ export function slackAdapter(options = {}) {
|
|
|
375
414
|
throw err;
|
|
376
415
|
}
|
|
377
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
|
+
},
|
|
378
456
|
async sendMessageToTarget(message, target) {
|
|
379
457
|
const targetContext = {
|
|
380
458
|
platform: "slack",
|
|
@@ -873,6 +951,88 @@ async function slackJson(token, method, params, timeoutMs = 2_000) {
|
|
|
873
951
|
return null;
|
|
874
952
|
}
|
|
875
953
|
}
|
|
954
|
+
function slackIdentityCacheKey(incoming) {
|
|
955
|
+
const teamId = incoming.platformContext.teamId;
|
|
956
|
+
const senderId = incoming.senderId;
|
|
957
|
+
if (typeof senderId !== "string" || !senderId.trim())
|
|
958
|
+
return null;
|
|
959
|
+
return `${typeof teamId === "string" && teamId ? teamId : "unknown"}:${senderId}`;
|
|
960
|
+
}
|
|
961
|
+
async function resolveSlackUserIdentity(token, incoming) {
|
|
962
|
+
const cacheKey = slackIdentityCacheKey(incoming);
|
|
963
|
+
if (!cacheKey)
|
|
964
|
+
return null;
|
|
965
|
+
const cached = slackIdentityCache.get(cacheKey);
|
|
966
|
+
if (cached && cached.expiresAt > Date.now())
|
|
967
|
+
return cached.identity;
|
|
968
|
+
if (cached)
|
|
969
|
+
slackIdentityCache.delete(cacheKey);
|
|
970
|
+
const user = await slackJson(token, "users.info", { user: incoming.senderId }, SLACK_IDENTITY_TIMEOUT_MS);
|
|
971
|
+
const profile = user?.user?.profile;
|
|
972
|
+
const identity = user?.user
|
|
973
|
+
? {
|
|
974
|
+
email: typeof profile?.email === "string" && profile.email.trim()
|
|
975
|
+
? profile.email.trim().toLowerCase()
|
|
976
|
+
: null,
|
|
977
|
+
name: typeof profile?.real_name === "string" && profile.real_name.trim()
|
|
978
|
+
? profile.real_name.trim()
|
|
979
|
+
: typeof profile?.display_name === "string" &&
|
|
980
|
+
profile.display_name.trim()
|
|
981
|
+
? profile.display_name.trim()
|
|
982
|
+
: typeof user.user.real_name === "string" &&
|
|
983
|
+
user.user.real_name.trim()
|
|
984
|
+
? user.user.real_name.trim()
|
|
985
|
+
: typeof user.user.name === "string" && user.user.name.trim()
|
|
986
|
+
? user.user.name.trim()
|
|
987
|
+
: null,
|
|
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
|
|
991
|
+
? "external"
|
|
992
|
+
: user.user.is_restricted
|
|
993
|
+
? "guest"
|
|
994
|
+
: user.user.is_owner
|
|
995
|
+
? "owner"
|
|
996
|
+
: user.user.is_admin
|
|
997
|
+
? "admin"
|
|
998
|
+
: "member",
|
|
999
|
+
}
|
|
1000
|
+
: null;
|
|
1001
|
+
if (slackIdentityCache.size >= SLACK_IDENTITY_CACHE_MAX_ENTRIES) {
|
|
1002
|
+
const oldestKey = slackIdentityCache.keys().next().value;
|
|
1003
|
+
if (oldestKey)
|
|
1004
|
+
slackIdentityCache.delete(oldestKey);
|
|
1005
|
+
}
|
|
1006
|
+
slackIdentityCache.set(cacheKey, {
|
|
1007
|
+
identity,
|
|
1008
|
+
expiresAt: Date.now() +
|
|
1009
|
+
(identity
|
|
1010
|
+
? SLACK_IDENTITY_CACHE_TTL_MS
|
|
1011
|
+
: SLACK_IDENTITY_NEGATIVE_CACHE_TTL_MS),
|
|
1012
|
+
});
|
|
1013
|
+
return identity;
|
|
1014
|
+
}
|
|
1015
|
+
async function hydrateSlackIdentity(token, incoming) {
|
|
1016
|
+
const identity = await resolveSlackUserIdentity(token, incoming);
|
|
1017
|
+
if (!identity) {
|
|
1018
|
+
return {
|
|
1019
|
+
...incoming,
|
|
1020
|
+
senderVerified: false,
|
|
1021
|
+
actorTrust: { memberType: "unknown", verified: false },
|
|
1022
|
+
};
|
|
1023
|
+
}
|
|
1024
|
+
return {
|
|
1025
|
+
...incoming,
|
|
1026
|
+
...(identity.name ? { senderName: identity.name } : {}),
|
|
1027
|
+
...(identity.email
|
|
1028
|
+
? { senderEmail: identity.email, senderVerified: true }
|
|
1029
|
+
: { senderVerified: false }),
|
|
1030
|
+
actorTrust: {
|
|
1031
|
+
memberType: identity.memberType,
|
|
1032
|
+
verified: true,
|
|
1033
|
+
},
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
876
1036
|
async function hydrateSlackContext(token, incoming) {
|
|
877
1037
|
const channelId = incoming.platformContext.channelId;
|
|
878
1038
|
const threadTs = incoming.platformContext.threadTs;
|
|
@@ -880,7 +1040,7 @@ async function hydrateSlackContext(token, incoming) {
|
|
|
880
1040
|
if (typeof channelId !== "string" || typeof threadTs !== "string") {
|
|
881
1041
|
return incoming;
|
|
882
1042
|
}
|
|
883
|
-
const [thread, history, pins, conversation,
|
|
1043
|
+
const [thread, history, pins, conversation, identity] = await Promise.all([
|
|
884
1044
|
slackJson(token, "conversations.replies", {
|
|
885
1045
|
channel: channelId,
|
|
886
1046
|
ts: threadTs,
|
|
@@ -894,7 +1054,7 @@ async function hydrateSlackContext(token, incoming) {
|
|
|
894
1054
|
}),
|
|
895
1055
|
slackJson(token, "pins.list", { channel: channelId }),
|
|
896
1056
|
slackJson(token, "conversations.info", { channel: channelId }),
|
|
897
|
-
senderId ?
|
|
1057
|
+
senderId ? resolveSlackUserIdentity(token, incoming) : null,
|
|
898
1058
|
]);
|
|
899
1059
|
// Agent View can attach the Slack surface the user is currently viewing to
|
|
900
1060
|
// a DM. Treat it only as a context hint: Slack requires us to prove the bot
|
|
@@ -968,9 +1128,7 @@ async function hydrateSlackContext(token, incoming) {
|
|
|
968
1128
|
};
|
|
969
1129
|
})
|
|
970
1130
|
: [];
|
|
971
|
-
const profile =
|
|
972
|
-
const isGuest = user?.user?.is_restricted === true;
|
|
973
|
-
const isExternal = user?.user?.is_ultra_restricted === true;
|
|
1131
|
+
const profile = identity;
|
|
974
1132
|
const isPrivate = conversation?.channel?.is_private === true;
|
|
975
1133
|
const isExternalShared = conversation?.channel?.is_ext_shared === true;
|
|
976
1134
|
const isMpim = conversation?.channel?.is_mpim === true;
|
|
@@ -1006,19 +1164,20 @@ async function hydrateSlackContext(token, incoming) {
|
|
|
1006
1164
|
const hydratedFiles = hydratedMessages.flatMap((message) => message.files ?? []);
|
|
1007
1165
|
return {
|
|
1008
1166
|
...incoming,
|
|
1009
|
-
...(
|
|
1010
|
-
|
|
1011
|
-
: typeof profile?.real_name === "string" && profile.real_name
|
|
1012
|
-
? { senderName: profile.real_name }
|
|
1013
|
-
: {}),
|
|
1014
|
-
...(typeof profile?.email === "string"
|
|
1167
|
+
...(profile?.name ? { senderName: profile.name } : {}),
|
|
1168
|
+
...(profile?.email
|
|
1015
1169
|
? { senderEmail: profile.email, senderVerified: true }
|
|
1016
|
-
: {}),
|
|
1170
|
+
: { senderVerified: false }),
|
|
1017
1171
|
conversationType,
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
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
|
+
}),
|
|
1022
1181
|
contextMessages: hydratedMessages,
|
|
1023
1182
|
...(hydratedFiles.length ? { files: hydratedFiles.slice(0, 20) } : {}),
|
|
1024
1183
|
platformContext: {
|