@agent-native/core 0.108.0 → 0.109.0
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/package.json +1 -1
- package/corpus/core/src/a2a/client.ts +140 -17
- package/corpus/core/src/a2a/handlers.ts +60 -0
- package/corpus/core/src/a2a/index.ts +6 -1
- package/corpus/core/src/a2a/invoke.ts +68 -1
- package/corpus/core/src/a2a/server.ts +13 -1
- package/corpus/core/src/a2a/types.ts +16 -0
- package/corpus/core/src/action.ts +3 -2
- package/corpus/core/src/agent/production-agent.ts +10 -4
- package/corpus/core/src/client/AssistantChat.tsx +648 -603
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -4
- package/corpus/core/src/client/agent-chat-adapter.ts +23 -37
- package/corpus/core/src/client/agent-sidebar-state.ts +4 -0
- package/corpus/core/src/client/analytics.ts +84 -0
- package/corpus/core/src/client/chat/message-components.tsx +94 -22
- package/corpus/core/src/client/chat/tool-call-display.tsx +170 -47
- package/corpus/core/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
- package/corpus/core/src/client/chat-thread-url.ts +11 -0
- package/corpus/core/src/client/error-capture.ts +12 -0
- package/corpus/core/src/client/extensions/ExtensionSlot.tsx +37 -1
- package/corpus/core/src/client/index.ts +2 -0
- package/corpus/core/src/client/route-chunk-recovery.ts +20 -8
- package/corpus/core/src/client/session-replay.ts +31 -0
- package/corpus/core/src/extensions/actions.ts +2 -14
- package/corpus/core/src/extensions/store.ts +1 -1
- package/corpus/core/src/localization/default-messages.ts +3 -0
- package/corpus/core/src/mcp/build-server.ts +2 -2
- package/corpus/core/src/progress/actions.ts +4 -2
- package/corpus/core/src/provider-api/index.ts +205 -105
- package/corpus/core/src/scripts/call-agent.ts +137 -17
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +40 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +31 -0
- package/corpus/core/src/styles/agent-conversation.css +7 -0
- package/corpus/core/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/corpus/core/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/corpus/core/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/corpus/core/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +29 -10
- package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +54 -23
- package/corpus/templates/analytics/.builder/skills/apollo/SKILL.md +19 -41
- package/corpus/templates/analytics/.builder/skills/commonroom/SKILL.md +20 -35
- package/corpus/templates/analytics/.builder/skills/github/SKILL.md +23 -67
- package/corpus/templates/analytics/.builder/skills/pylon/SKILL.md +25 -43
- package/corpus/templates/analytics/AGENTS.md +22 -13
- package/corpus/templates/analytics/actions/account-deep-dive.ts +1 -0
- package/corpus/templates/analytics/actions/configure-gong-native-insights.ts +29 -0
- package/corpus/templates/analytics/actions/content-calendar-schema.ts +8 -4
- package/corpus/templates/analytics/actions/content-calendar.ts +12 -4
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -1
- package/corpus/templates/analytics/actions/gong-calls.ts +113 -22
- package/corpus/templates/analytics/actions/gong-native-insights.ts +166 -0
- package/corpus/templates/analytics/actions/hubspot-deals.ts +190 -46
- package/corpus/templates/analytics/actions/pylon-issues.ts +123 -0
- package/corpus/templates/analytics/actions/slack-messages.ts +179 -27
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +48 -152
- package/corpus/templates/analytics/app/components/ui/chart.tsx +1 -1
- package/corpus/templates/analytics/app/hooks/use-chart-tooltip-flip.ts +21 -6
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +13 -0
- package/corpus/templates/analytics/app/i18n-data.ts +134 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +181 -30
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +6 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +4 -3
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-editors-can-add-shared-extensions-or-opt-into-per-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-dashboard-extensions-show-a-loading-skeleton.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-errors-now-group-repeat-failures-consistently-and-keep-priva.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-gong-transcript-reviews-now-batch-bounded-call-windows-for-f.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-hubspot-deal-filters-now-run-in-hubspot-before-paging-result.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-notion-content-calendars-now-discover-the-matching-database-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-pylon-dashboard-reads-now-use-the-paginated-issue-search-api.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-17-slack-reads-no-longer-join-channels-and-report-pagination-coverage.md +6 -0
- package/corpus/templates/analytics/server/handlers/notion.ts +14 -3
- package/corpus/templates/analytics/server/handlers/slack.ts +182 -29
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +2 -6
- package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +6 -2
- package/corpus/templates/analytics/server/lib/error-capture.ts +75 -8
- package/corpus/templates/analytics/server/lib/gong-native-policy.ts +72 -0
- package/corpus/templates/analytics/server/lib/gong.ts +54 -66
- package/corpus/templates/analytics/server/lib/hubspot.ts +40 -3
- package/corpus/templates/analytics/server/lib/notion.ts +83 -8
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +4 -0
- package/corpus/templates/analytics/server/lib/slack.ts +242 -90
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +3 -3
- package/corpus/templates/analytics/server/routes/api/pylon/accounts.get.ts +42 -1
- package/corpus/templates/analytics/server/routes/api/pylon/issues.get.ts +71 -1
- package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +44 -4
- package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +19 -1
- package/corpus/templates/clips/app/components/library/create-folder-dialog.tsx +123 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +42 -4
- package/corpus/templates/clips/app/components/library/recording-card.tsx +30 -0
- package/corpus/templates/clips/app/entry.client.tsx +6 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +12 -1
- package/corpus/templates/clips/app/i18n/de-DE.ts +12 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +12 -1
- package/corpus/templates/clips/app/i18n/es-ES.ts +11 -1
- package/corpus/templates/clips/app/i18n/fr-FR.ts +11 -1
- package/corpus/templates/clips/app/i18n/hi-IN.ts +10 -1
- package/corpus/templates/clips/app/i18n/ja-JP.ts +12 -1
- package/corpus/templates/clips/app/i18n/ko-KR.ts +11 -1
- package/corpus/templates/clips/app/i18n/pt-BR.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-CN.ts +11 -1
- package/corpus/templates/clips/app/i18n/zh-TW.ts +11 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +72 -1
- package/corpus/templates/clips/changelog/2026-07-17-choose-which-workspace-receives-new-clips-recordings-and-des.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-create-folders-directly-from-the-move-menu.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-17-failed-desktop-uploads-now-offer-a-direct-way-to-reopen-clip.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +1 -1
- package/corpus/templates/content/app/entry.client.tsx +6 -1
- package/corpus/templates/dispatch/AGENTS.md +5 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-apps-page-links-to-other-available-apps.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-07-17-curated-template-remixes.md +6 -0
- package/corpus/templates/mail/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +11 -7
- package/corpus/templates/slides/.env.example +0 -1
- package/corpus/templates/slides/AGENTS.md +4 -0
- package/corpus/templates/slides/DEVELOPING.md +2 -2
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
- package/corpus/templates/slides/actions/logo-config.ts +6 -7
- package/corpus/templates/slides/actions/search-images.ts +11 -39
- package/corpus/templates/slides/actions/search-logos.ts +5 -52
- package/corpus/templates/slides/app/components/editor/ImageSearchPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/LogoSearchPanel.tsx +16 -26
- package/corpus/templates/slides/app/entry.client.tsx +6 -1
- package/corpus/templates/slides/server/lib/media-search-providers.ts +216 -0
- package/corpus/templates/slides/server/register-secrets.ts +30 -0
- package/dist/a2a/client.d.ts +38 -1
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +81 -12
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/handlers.d.ts.map +1 -1
- package/dist/a2a/handlers.js +47 -0
- package/dist/a2a/handlers.js.map +1 -1
- package/dist/a2a/index.d.ts +4 -4
- package/dist/a2a/index.d.ts.map +1 -1
- package/dist/a2a/index.js +2 -2
- package/dist/a2a/index.js.map +1 -1
- package/dist/a2a/invoke.d.ts +26 -2
- package/dist/a2a/invoke.d.ts.map +1 -1
- package/dist/a2a/invoke.js +30 -1
- package/dist/a2a/invoke.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +14 -1
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +12 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +3 -2
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +5 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +5 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +158 -136
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +27 -4
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -39
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/agent-sidebar-state.d.ts +1 -0
- package/dist/client/agent-sidebar-state.d.ts.map +1 -1
- package/dist/client/agent-sidebar-state.js +4 -0
- package/dist/client/agent-sidebar-state.js.map +1 -1
- package/dist/client/analytics.d.ts +14 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +67 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +8 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +62 -19
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +6 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +83 -14
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts +8 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.d.ts.map +1 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js +51 -0
- package/dist/client/chat/use-agent-chat-lifecycle-tracking.js.map +1 -0
- package/dist/client/chat-thread-url.d.ts +2 -0
- package/dist/client/chat-thread-url.d.ts.map +1 -0
- package/dist/client/chat-thread-url.js +12 -0
- package/dist/client/chat-thread-url.js.map +1 -0
- package/dist/client/error-capture.d.ts.map +1 -1
- package/dist/client/error-capture.js +7 -0
- package/dist/client/error-capture.js.map +1 -1
- package/dist/client/extensions/ExtensionSlot.d.ts +3 -1
- package/dist/client/extensions/ExtensionSlot.d.ts.map +1 -1
- package/dist/client/extensions/ExtensionSlot.js +28 -3
- package/dist/client/extensions/ExtensionSlot.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/route-chunk-recovery.d.ts.map +1 -1
- package/dist/client/route-chunk-recovery.js +14 -9
- package/dist/client/route-chunk-recovery.js.map +1 -1
- package/dist/client/session-replay.d.ts +15 -0
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +20 -0
- package/dist/client/session-replay.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +2 -10
- package/dist/extensions/actions.js.map +1 -1
- package/dist/extensions/store.js +1 -1
- package/dist/extensions/store.js.map +1 -1
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +3 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp/build-server.d.ts +2 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +2 -2
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +1 -1
- package/dist/progress/actions.d.ts.map +1 -1
- package/dist/progress/actions.js +3 -2
- package/dist/progress/actions.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +91 -8
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/scripts/call-agent.d.ts.map +1 -1
- package/dist/scripts/call-agent.js +107 -16
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.d.ts +6 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +27 -0
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +27 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/styles/agent-conversation.css +7 -0
- package/dist/templates/default/app/i18n/ar-SA.ts +20 -0
- package/dist/templates/default/app/i18n/de-DE.ts +20 -0
- package/dist/templates/default/app/i18n/en-US.ts +20 -0
- package/dist/templates/default/app/i18n/es-ES.ts +20 -0
- package/dist/templates/default/app/i18n/fr-FR.ts +21 -0
- package/dist/templates/default/app/i18n/hi-IN.ts +19 -0
- package/dist/templates/default/app/i18n/ja-JP.ts +20 -0
- package/dist/templates/default/app/i18n/ko-KR.ts +19 -0
- package/dist/templates/default/app/i18n/pt-BR.ts +20 -0
- package/dist/templates/default/app/i18n/zh-CN.ts +19 -0
- package/dist/templates/default/app/i18n/zh-TW.ts +19 -0
- package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/dist/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/package.json +1 -1
- package/src/templates/default/app/i18n/ar-SA.ts +20 -0
- package/src/templates/default/app/i18n/de-DE.ts +20 -0
- package/src/templates/default/app/i18n/en-US.ts +20 -0
- package/src/templates/default/app/i18n/es-ES.ts +20 -0
- package/src/templates/default/app/i18n/fr-FR.ts +21 -0
- package/src/templates/default/app/i18n/hi-IN.ts +19 -0
- package/src/templates/default/app/i18n/ja-JP.ts +20 -0
- package/src/templates/default/app/i18n/ko-KR.ts +19 -0
- package/src/templates/default/app/i18n/pt-BR.ts +20 -0
- package/src/templates/default/app/i18n/zh-CN.ts +19 -0
- package/src/templates/default/app/i18n/zh-TW.ts +19 -0
- package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +28 -0
- package/src/templates/workspace-core/.agents/skills/composable-mini-apps/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +13 -0
- package/corpus/templates/analytics/server/handlers/github.ts +0 -200
- package/corpus/templates/analytics/server/handlers/pylon.ts +0 -43
- package/corpus/templates/analytics/server/lib/apollo.ts +0 -167
- package/corpus/templates/analytics/server/lib/commonroom.ts +0 -149
- package/corpus/templates/analytics/server/lib/github.ts +0 -660
- package/corpus/templates/analytics/server/lib/mixpanel.ts +0 -156
- package/corpus/templates/analytics/server/lib/posthog.ts +0 -194
- package/corpus/templates/analytics/server/lib/pylon.ts +0 -109
- package/corpus/templates/analytics/server/routes/api/github/graphql.post.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/issue.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/org-prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/pr.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/prs.get.ts +0 -1
- package/corpus/templates/analytics/server/routes/api/github/search.get.ts +0 -1
- package/corpus/templates/slides/actions/fetch-logos.ts +0 -90
- package/corpus/templates/slides/actions/image-search.ts +0 -64
- package/corpus/templates/slides/actions/import-github.ts +0 -182
- package/corpus/templates/slides/actions/logo-lookup.ts +0 -113
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
defineEventHandler,
|
|
3
|
+
getQuery,
|
|
4
|
+
getRouterParam,
|
|
5
|
+
setResponseStatus,
|
|
6
|
+
} from "h3";
|
|
2
7
|
|
|
3
8
|
import {
|
|
4
9
|
requireCredential,
|
|
@@ -16,7 +21,10 @@ export const handleContentCalendar = defineEventHandler(async (event) => {
|
|
|
16
21
|
const missing = await requireCredential(event, "NOTION_API_KEY", "Notion");
|
|
17
22
|
if (missing) return missing;
|
|
18
23
|
try {
|
|
19
|
-
const
|
|
24
|
+
const { databaseId } = getQuery(event);
|
|
25
|
+
const entries = await getContentCalendar(
|
|
26
|
+
databaseId as string | undefined,
|
|
27
|
+
);
|
|
20
28
|
return { entries, total: entries.length };
|
|
21
29
|
} catch (err: any) {
|
|
22
30
|
console.error("Notion content-calendar error:", err.message);
|
|
@@ -32,7 +40,10 @@ export const handleContentCalendarSchema = defineEventHandler(async (event) => {
|
|
|
32
40
|
const missing = await requireCredential(event, "NOTION_API_KEY", "Notion");
|
|
33
41
|
if (missing) return missing;
|
|
34
42
|
try {
|
|
35
|
-
const
|
|
43
|
+
const { databaseId } = getQuery(event);
|
|
44
|
+
const schema = await getContentCalendarSchema(
|
|
45
|
+
databaseId as string | undefined,
|
|
46
|
+
);
|
|
36
47
|
return { schema };
|
|
37
48
|
} catch (err: any) {
|
|
38
49
|
console.error("Notion schema error:", err.message);
|
|
@@ -10,11 +10,11 @@ import {
|
|
|
10
10
|
runApiHandlerWithContext,
|
|
11
11
|
} from "../lib/credentials";
|
|
12
12
|
import {
|
|
13
|
-
listChannels,
|
|
14
13
|
getChannelHistory,
|
|
15
|
-
searchMessages,
|
|
16
|
-
resolveUsers,
|
|
17
14
|
getTeamInfo,
|
|
15
|
+
listChannelsWithCoverage,
|
|
16
|
+
resolveUsersWithCoverage,
|
|
17
|
+
searchMessages,
|
|
18
18
|
type Workspace,
|
|
19
19
|
type SlackMessage,
|
|
20
20
|
} from "../lib/slack";
|
|
@@ -49,12 +49,21 @@ export const handleSlackTeam = defineEventHandler((event) =>
|
|
|
49
49
|
export const handleSlackChannels = defineEventHandler((event) =>
|
|
50
50
|
runApiHandlerWithContext(event, async () => {
|
|
51
51
|
try {
|
|
52
|
-
const { workspace: workspaceParam } = getQuery(event);
|
|
52
|
+
const { workspace: workspaceParam, cursor } = getQuery(event);
|
|
53
53
|
const workspace = parseWorkspace(workspaceParam as string);
|
|
54
54
|
const missing = await requireSlackCredential(event, workspace);
|
|
55
55
|
if (missing) return missing;
|
|
56
|
-
const
|
|
57
|
-
|
|
56
|
+
const result = await listChannelsWithCoverage(
|
|
57
|
+
workspace,
|
|
58
|
+
cursor as string | undefined,
|
|
59
|
+
);
|
|
60
|
+
return {
|
|
61
|
+
channels: result.channels,
|
|
62
|
+
total: result.total,
|
|
63
|
+
truncated: result.truncated,
|
|
64
|
+
pagination: result.pagination,
|
|
65
|
+
coverage: result.coverage,
|
|
66
|
+
};
|
|
58
67
|
} catch (err: any) {
|
|
59
68
|
console.error("Slack channels error:", err.message);
|
|
60
69
|
setResponseStatus(event, 500);
|
|
@@ -112,15 +121,33 @@ export const handleSlackHistory = defineEventHandler((event) =>
|
|
|
112
121
|
const userIds = result.messages
|
|
113
122
|
.map((m) => m.user)
|
|
114
123
|
.filter((id): id is string => !!id);
|
|
115
|
-
const
|
|
124
|
+
const resolution = await resolveUsersWithCoverage(
|
|
125
|
+
workspace,
|
|
126
|
+
userIds,
|
|
127
|
+
result.messages,
|
|
128
|
+
);
|
|
116
129
|
|
|
117
130
|
const enrichedMessages = enrichMessages(result.messages);
|
|
118
131
|
|
|
119
132
|
return {
|
|
120
133
|
messages: enrichedMessages,
|
|
121
|
-
users,
|
|
134
|
+
users: resolution.users,
|
|
122
135
|
has_more: result.has_more,
|
|
123
136
|
next_cursor: result.next_cursor,
|
|
137
|
+
truncated: result.truncated,
|
|
138
|
+
pagination: result.pagination,
|
|
139
|
+
coverage: {
|
|
140
|
+
...result.coverage,
|
|
141
|
+
coverage_complete:
|
|
142
|
+
result.coverage.coverage_complete &&
|
|
143
|
+
resolution.coverage.coverage_complete,
|
|
144
|
+
truncated: result.coverage.truncated || resolution.coverage.truncated,
|
|
145
|
+
truncation_reasons: [
|
|
146
|
+
...result.coverage.truncation_reasons,
|
|
147
|
+
...resolution.coverage.truncation_reasons,
|
|
148
|
+
],
|
|
149
|
+
authors: resolution.coverage,
|
|
150
|
+
},
|
|
124
151
|
};
|
|
125
152
|
} catch (err: any) {
|
|
126
153
|
console.error("Slack history error:", err.message);
|
|
@@ -165,29 +192,45 @@ export const handleSlackMultiHistory = defineEventHandler((event) =>
|
|
|
165
192
|
? JSON.parse(cursorsParam as string)
|
|
166
193
|
: {};
|
|
167
194
|
|
|
168
|
-
// Fetch pageSize messages from each channel in parallel
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
195
|
+
// Fetch pageSize messages from each channel in parallel while preserving
|
|
196
|
+
// partial results when the bot is not invited to one of the channels.
|
|
197
|
+
const channelResults = await Promise.allSettled(
|
|
198
|
+
channelIds.map((channelId) =>
|
|
199
|
+
getChannelHistory(workspace, channelId, pageSize, cursors[channelId]),
|
|
172
200
|
),
|
|
173
201
|
);
|
|
202
|
+
const successfulResults = channelResults.flatMap((entry, index) =>
|
|
203
|
+
entry.status === "fulfilled"
|
|
204
|
+
? [{ channelId: channelIds[index], result: entry.value }]
|
|
205
|
+
: [],
|
|
206
|
+
);
|
|
207
|
+
const failedChannelIds = channelResults.flatMap((entry, index) =>
|
|
208
|
+
entry.status === "rejected" ? [channelIds[index]] : [],
|
|
209
|
+
);
|
|
174
210
|
|
|
175
211
|
// Tag messages with channel name and merge
|
|
176
|
-
const allMessages: (SlackMessage & {
|
|
212
|
+
const allMessages: (SlackMessage & {
|
|
213
|
+
channel_id: string;
|
|
214
|
+
channel_name: string;
|
|
215
|
+
})[] = [];
|
|
177
216
|
const perChannelHasMore: Record<string, boolean> = {};
|
|
178
217
|
const nextCursors: Record<string, string> = {};
|
|
179
218
|
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
perChannelHasMore[
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
219
|
+
successfulResults.forEach(({ channelId, result }) => {
|
|
220
|
+
const chName =
|
|
221
|
+
channelNamesList[channelIds.indexOf(channelId)] || channelId;
|
|
222
|
+
perChannelHasMore[channelId] = result.has_more;
|
|
223
|
+
for (const message of result.messages) {
|
|
224
|
+
allMessages.push({
|
|
225
|
+
...message,
|
|
226
|
+
channel_id: channelId,
|
|
227
|
+
channel_name: chName,
|
|
228
|
+
});
|
|
189
229
|
}
|
|
190
230
|
});
|
|
231
|
+
failedChannelIds.forEach((channelId) => {
|
|
232
|
+
perChannelHasMore[channelId] = true;
|
|
233
|
+
});
|
|
191
234
|
|
|
192
235
|
// Sort merged by timestamp (newest first)
|
|
193
236
|
allMessages.sort((a, b) => parseFloat(b.ts) - parseFloat(a.ts));
|
|
@@ -195,26 +238,112 @@ export const handleSlackMultiHistory = defineEventHandler((event) =>
|
|
|
195
238
|
// Take top pageSize
|
|
196
239
|
const pageMessages = allMessages.slice(0, pageSize);
|
|
197
240
|
|
|
241
|
+
const emittedByChannel = new Map<string, SlackMessage[]>();
|
|
242
|
+
for (const message of pageMessages) {
|
|
243
|
+
const emitted = emittedByChannel.get(message.channel_id) ?? [];
|
|
244
|
+
emitted.push(message);
|
|
245
|
+
emittedByChannel.set(message.channel_id, emitted);
|
|
246
|
+
}
|
|
247
|
+
for (const channelId of channelIds) {
|
|
248
|
+
const emitted = emittedByChannel.get(channelId);
|
|
249
|
+
const nextCursor = emitted?.[emitted.length - 1]?.ts;
|
|
250
|
+
if (nextCursor) nextCursors[channelId] = nextCursor;
|
|
251
|
+
else if (cursors[channelId])
|
|
252
|
+
nextCursors[channelId] = cursors[channelId];
|
|
253
|
+
}
|
|
254
|
+
|
|
198
255
|
// Enrich text from blocks
|
|
199
|
-
const enrichedMessages =
|
|
256
|
+
const enrichedMessages = pageMessages.map((message) => {
|
|
257
|
+
const enriched = enrichMessages([message])[0] ?? message;
|
|
258
|
+
const { channel_id: _channelId, ...rest } = enriched as typeof message;
|
|
259
|
+
return rest;
|
|
260
|
+
});
|
|
200
261
|
|
|
201
262
|
// Resolve users
|
|
202
263
|
const userIds = enrichedMessages
|
|
203
264
|
.map((m) => m.user)
|
|
204
265
|
.filter((id): id is string => !!id);
|
|
205
|
-
const
|
|
266
|
+
const resolution = await resolveUsersWithCoverage(
|
|
267
|
+
workspace,
|
|
268
|
+
userIds,
|
|
269
|
+
enrichedMessages,
|
|
270
|
+
);
|
|
206
271
|
|
|
207
272
|
// has_more is true if any channel has more messages
|
|
273
|
+
const providerTruncated = successfulResults.some(
|
|
274
|
+
({ result }) => result.truncated,
|
|
275
|
+
);
|
|
276
|
+
const mergedResultTruncated = allMessages.length > pageSize;
|
|
208
277
|
const hasMore =
|
|
209
|
-
|
|
210
|
-
|
|
278
|
+
providerTruncated ||
|
|
279
|
+
mergedResultTruncated ||
|
|
280
|
+
failedChannelIds.length > 0;
|
|
281
|
+
const truncationReasons = [
|
|
282
|
+
...(providerTruncated ? ["provider_has_more"] : []),
|
|
283
|
+
...(mergedResultTruncated ? ["merged_result_limit"] : []),
|
|
284
|
+
...failedChannelIds.map(
|
|
285
|
+
(channelId) => `channel_fetch_failed:${channelId}`,
|
|
286
|
+
),
|
|
287
|
+
];
|
|
288
|
+
const channelPagination = Object.fromEntries(
|
|
289
|
+
channelResults.map((entry, index) => [
|
|
290
|
+
channelIds[index],
|
|
291
|
+
entry.status === "fulfilled"
|
|
292
|
+
? entry.value.pagination
|
|
293
|
+
: {
|
|
294
|
+
cursor_type: "latest_ts" as const,
|
|
295
|
+
...(cursors[channelIds[index]]
|
|
296
|
+
? { request_cursor: cursors[channelIds[index]] }
|
|
297
|
+
: {}),
|
|
298
|
+
},
|
|
299
|
+
]),
|
|
300
|
+
);
|
|
301
|
+
const channelCoverage = Object.fromEntries(
|
|
302
|
+
channelResults.map((entry, index) => [
|
|
303
|
+
channelIds[index],
|
|
304
|
+
entry.status === "fulfilled"
|
|
305
|
+
? entry.value.coverage
|
|
306
|
+
: {
|
|
307
|
+
requested: pageSize,
|
|
308
|
+
fetched: 0,
|
|
309
|
+
returned: 0,
|
|
310
|
+
pages_fetched: 0,
|
|
311
|
+
coverage_complete: false,
|
|
312
|
+
truncated: true,
|
|
313
|
+
truncation_reasons: [
|
|
314
|
+
`channel_fetch_failed:${channelIds[index]}`,
|
|
315
|
+
],
|
|
316
|
+
},
|
|
317
|
+
]),
|
|
318
|
+
);
|
|
211
319
|
|
|
212
320
|
return {
|
|
213
321
|
messages: enrichedMessages,
|
|
214
|
-
users,
|
|
322
|
+
users: resolution.users,
|
|
215
323
|
has_more: hasMore,
|
|
216
324
|
next_cursors: nextCursors,
|
|
217
325
|
total: allMessages.length,
|
|
326
|
+
truncated: hasMore,
|
|
327
|
+
pagination: {
|
|
328
|
+
cursor_type: "per_channel_latest_ts",
|
|
329
|
+
request_cursors: cursors,
|
|
330
|
+
next_cursors: nextCursors,
|
|
331
|
+
channels: channelPagination,
|
|
332
|
+
},
|
|
333
|
+
coverage: {
|
|
334
|
+
requested: channelIds.length * pageSize,
|
|
335
|
+
fetched: allMessages.length,
|
|
336
|
+
returned: enrichedMessages.length,
|
|
337
|
+
pages_fetched: successfulResults.length,
|
|
338
|
+
coverage_complete: !hasMore && resolution.coverage.coverage_complete,
|
|
339
|
+
truncated: hasMore || resolution.coverage.truncated,
|
|
340
|
+
truncation_reasons: [
|
|
341
|
+
...truncationReasons,
|
|
342
|
+
...resolution.coverage.truncation_reasons,
|
|
343
|
+
],
|
|
344
|
+
channels: channelCoverage,
|
|
345
|
+
authors: resolution.coverage,
|
|
346
|
+
},
|
|
218
347
|
};
|
|
219
348
|
} catch (err: any) {
|
|
220
349
|
console.error("Slack multi-history error:", err.message);
|
|
@@ -242,9 +371,33 @@ export const handleSlackSearch = defineEventHandler((event) =>
|
|
|
242
371
|
const userIds = result.messages
|
|
243
372
|
.map((m) => m.user)
|
|
244
373
|
.filter((id): id is string => !!id);
|
|
245
|
-
const
|
|
374
|
+
const resolution = await resolveUsersWithCoverage(
|
|
375
|
+
workspace,
|
|
376
|
+
userIds,
|
|
377
|
+
result.messages,
|
|
378
|
+
);
|
|
246
379
|
|
|
247
|
-
return {
|
|
380
|
+
return {
|
|
381
|
+
messages: result.messages,
|
|
382
|
+
users: resolution.users,
|
|
383
|
+
total: result.total,
|
|
384
|
+
unsupported: result.unsupported,
|
|
385
|
+
guidance: result.guidance,
|
|
386
|
+
truncated: result.truncated,
|
|
387
|
+
pagination: result.pagination,
|
|
388
|
+
coverage: {
|
|
389
|
+
...result.coverage,
|
|
390
|
+
coverage_complete:
|
|
391
|
+
result.coverage.coverage_complete &&
|
|
392
|
+
resolution.coverage.coverage_complete,
|
|
393
|
+
truncated: result.coverage.truncated || resolution.coverage.truncated,
|
|
394
|
+
truncation_reasons: [
|
|
395
|
+
...result.coverage.truncation_reasons,
|
|
396
|
+
...resolution.coverage.truncation_reasons,
|
|
397
|
+
],
|
|
398
|
+
authors: resolution.coverage,
|
|
399
|
+
},
|
|
400
|
+
};
|
|
248
401
|
} catch (err: any) {
|
|
249
402
|
console.error("Slack search error:", err.message);
|
|
250
403
|
setResponseStatus(event, 500);
|
|
@@ -43,14 +43,9 @@ export const INITIAL_TOOL_NAMES = [
|
|
|
43
43
|
"query-staged-dataset",
|
|
44
44
|
"list-staged-datasets",
|
|
45
45
|
"account-deep-dive",
|
|
46
|
-
"hubspot-deals",
|
|
47
|
-
"hubspot-records",
|
|
48
|
-
"hubspot-pipelines",
|
|
49
46
|
"gong-calls",
|
|
47
|
+
"gong-native-insights",
|
|
50
48
|
"github-repo-files",
|
|
51
|
-
"jira-search",
|
|
52
|
-
"slack-messages",
|
|
53
|
-
"sentry",
|
|
54
49
|
"list-data-dictionary",
|
|
55
50
|
"navigate",
|
|
56
51
|
];
|
|
@@ -66,6 +61,7 @@ export const PLAN_MODE_ACT_ONLY_TOOLS = new Set([
|
|
|
66
61
|
"hubspot-records",
|
|
67
62
|
"hubspot-pipelines",
|
|
68
63
|
"gong-calls",
|
|
64
|
+
"gong-native-insights",
|
|
69
65
|
"github-repo-files",
|
|
70
66
|
"jira-search",
|
|
71
67
|
"slack-messages",
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The deliberately small authenticated MCP surface for Analytics.
|
|
3
3
|
*
|
|
4
|
-
* Keep this list read-only and
|
|
5
|
-
*
|
|
4
|
+
* Keep this list read-only and bounded. It includes incident evidence plus
|
|
5
|
+
* the narrow Gong deep-dive/synthesis/evidence operations used by sibling
|
|
6
|
+
* apps. Do not add raw replay blobs or dashboard/data mutation actions here.
|
|
6
7
|
*/
|
|
7
8
|
export const ANALYTICS_CONNECTOR_CATALOG = [
|
|
9
|
+
"account-deep-dive",
|
|
10
|
+
"gong-calls",
|
|
11
|
+
"gong-native-insights",
|
|
8
12
|
"list-session-recordings",
|
|
9
13
|
"get-session-replay-summary",
|
|
10
14
|
"get-session-replay-timeline",
|
|
@@ -373,6 +373,11 @@ export function normalizeFrameFile(file: string | null): string {
|
|
|
373
373
|
// Strip bundler content hashes in the basename: main.4f3a2b1c.js -> main.js
|
|
374
374
|
out = out.replace(/([._-])[0-9a-fA-F]{8,}(?=\.[a-z0-9]+$)/i, "");
|
|
375
375
|
out = out.replace(/([._-])[0-9a-fA-F]{8,}$/i, "");
|
|
376
|
+
// Vite also emits eight-character base64url hashes, e.g. entry-CVi_y2nS.js.
|
|
377
|
+
out = out.replace(
|
|
378
|
+
/([._-])(?=[A-Za-z0-9_-]{8}\.[a-z0-9]+$)(?=[A-Za-z0-9_-]*[A-Z0-9_])[A-Za-z0-9_-]{8}(?=\.[a-z0-9]+$)/,
|
|
379
|
+
"",
|
|
380
|
+
);
|
|
376
381
|
return out;
|
|
377
382
|
}
|
|
378
383
|
|
|
@@ -412,11 +417,15 @@ export function fingerprint(
|
|
|
412
417
|
frames: ParsedStackFrame[],
|
|
413
418
|
message: string,
|
|
414
419
|
): string {
|
|
420
|
+
// The client uses this synthetic type for bare Error rejections. Keep it
|
|
421
|
+
// in the same group as window errors while retaining the original event
|
|
422
|
+
// type in the stored occurrence.
|
|
423
|
+
const groupingType = type === "UnhandledRejection" ? "Error" : type;
|
|
415
424
|
const frame = topFrame(frames);
|
|
416
425
|
const key =
|
|
417
426
|
frame && (frame.file || frame.function)
|
|
418
|
-
? `${
|
|
419
|
-
: `${
|
|
427
|
+
? `${groupingType}|${normalizeFrameFile(frame.file)}|${frame.function ?? ""}`
|
|
428
|
+
: `${groupingType}|${normalizeMessageForFingerprint(message)}`;
|
|
420
429
|
return hashHex(key);
|
|
421
430
|
}
|
|
422
431
|
|
|
@@ -1123,6 +1132,28 @@ function recordingPath(recordingId: string | null): string | null {
|
|
|
1123
1132
|
return recordingId ? `/sessions/${recordingId}` : null;
|
|
1124
1133
|
}
|
|
1125
1134
|
|
|
1135
|
+
async function accessibleClientRecordingId(
|
|
1136
|
+
scope: ErrorReadScope,
|
|
1137
|
+
recordingId: string,
|
|
1138
|
+
): Promise<string | null> {
|
|
1139
|
+
const db = getDb() as any;
|
|
1140
|
+
const [row] = await db
|
|
1141
|
+
.select({ clientRecordingId: schema.sessionRecordings.clientRecordingId })
|
|
1142
|
+
.from(schema.sessionRecordings)
|
|
1143
|
+
.where(
|
|
1144
|
+
and(
|
|
1145
|
+
eq(schema.sessionRecordings.id, recordingId),
|
|
1146
|
+
accessFilter(
|
|
1147
|
+
schema.sessionRecordings,
|
|
1148
|
+
schema.sessionRecordingShares,
|
|
1149
|
+
accessCtx(scope),
|
|
1150
|
+
),
|
|
1151
|
+
),
|
|
1152
|
+
)
|
|
1153
|
+
.limit(1);
|
|
1154
|
+
return row?.clientRecordingId ?? null;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1126
1157
|
async function sparklinesForIssues(
|
|
1127
1158
|
issueIds: string[],
|
|
1128
1159
|
): Promise<Map<string, number[]>> {
|
|
@@ -1194,9 +1225,19 @@ export async function listErrorIssues(
|
|
|
1194
1225
|
),
|
|
1195
1226
|
];
|
|
1196
1227
|
if (sessionRecordingId) {
|
|
1197
|
-
|
|
1198
|
-
|
|
1228
|
+
const clientRecordingId = await accessibleClientRecordingId(
|
|
1229
|
+
scope,
|
|
1230
|
+
sessionRecordingId,
|
|
1199
1231
|
);
|
|
1232
|
+
const recordingConditions: any[] = [
|
|
1233
|
+
eq(schema.errorEvents.sessionRecordingId, sessionRecordingId),
|
|
1234
|
+
];
|
|
1235
|
+
if (clientRecordingId) {
|
|
1236
|
+
recordingConditions.push(
|
|
1237
|
+
eq(schema.errorEvents.clientRecordingId, clientRecordingId),
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
occurrenceConditions.push(or(...recordingConditions));
|
|
1200
1241
|
}
|
|
1201
1242
|
if (userId) {
|
|
1202
1243
|
occurrenceConditions.push(
|
|
@@ -1241,6 +1282,13 @@ export async function listErrorIssues(
|
|
|
1241
1282
|
.limit(limit);
|
|
1242
1283
|
|
|
1243
1284
|
const sparklines = await sparklinesForIssues(rows.map((row: any) => row.id));
|
|
1285
|
+
const { byId: accessibleLastRecordings } = await resolveAccessibleRecordings(
|
|
1286
|
+
scope,
|
|
1287
|
+
rows
|
|
1288
|
+
.map((row: any) => row.lastSessionRecordingId)
|
|
1289
|
+
.filter((value: unknown): value is string => Boolean(value)),
|
|
1290
|
+
[],
|
|
1291
|
+
);
|
|
1244
1292
|
const issues = rows.map((row: any) => ({
|
|
1245
1293
|
id: row.id,
|
|
1246
1294
|
fingerprint: row.fingerprint,
|
|
@@ -1253,8 +1301,17 @@ export async function listErrorIssues(
|
|
|
1253
1301
|
lastSeenAt: row.lastSeenAt,
|
|
1254
1302
|
eventCount: Number(row.eventCount ?? 0),
|
|
1255
1303
|
usersAffected: Number(row.usersAffected ?? 0),
|
|
1256
|
-
lastSessionRecordingId:
|
|
1257
|
-
|
|
1304
|
+
lastSessionRecordingId:
|
|
1305
|
+
row.lastSessionRecordingId &&
|
|
1306
|
+
accessibleLastRecordings.has(row.lastSessionRecordingId)
|
|
1307
|
+
? row.lastSessionRecordingId
|
|
1308
|
+
: null,
|
|
1309
|
+
lastSessionRecordingPath: recordingPath(
|
|
1310
|
+
row.lastSessionRecordingId &&
|
|
1311
|
+
accessibleLastRecordings.has(row.lastSessionRecordingId)
|
|
1312
|
+
? row.lastSessionRecordingId
|
|
1313
|
+
: null,
|
|
1314
|
+
),
|
|
1258
1315
|
assignee: row.assignee ?? null,
|
|
1259
1316
|
app: row.app ?? null,
|
|
1260
1317
|
template: row.template ?? null,
|
|
@@ -1390,6 +1447,9 @@ export async function getErrorIssue(
|
|
|
1390
1447
|
.filter((value: unknown): value is string => Boolean(value)),
|
|
1391
1448
|
),
|
|
1392
1449
|
) as string[];
|
|
1450
|
+
if (issueRow.lastSessionRecordingId) {
|
|
1451
|
+
srIds.push(issueRow.lastSessionRecordingId);
|
|
1452
|
+
}
|
|
1393
1453
|
const clientIds = Array.from(
|
|
1394
1454
|
new Set(
|
|
1395
1455
|
eventRows
|
|
@@ -1467,9 +1527,16 @@ export async function getErrorIssue(
|
|
|
1467
1527
|
lastSeenAt: issueRow.lastSeenAt,
|
|
1468
1528
|
eventCount: Number(issueRow.eventCount ?? 0),
|
|
1469
1529
|
usersAffected: Number(issueRow.usersAffected ?? 0),
|
|
1470
|
-
lastSessionRecordingId:
|
|
1530
|
+
lastSessionRecordingId:
|
|
1531
|
+
issueRow.lastSessionRecordingId &&
|
|
1532
|
+
byId.has(issueRow.lastSessionRecordingId)
|
|
1533
|
+
? issueRow.lastSessionRecordingId
|
|
1534
|
+
: null,
|
|
1471
1535
|
lastSessionRecordingPath: recordingPath(
|
|
1472
|
-
issueRow.lastSessionRecordingId
|
|
1536
|
+
issueRow.lastSessionRecordingId &&
|
|
1537
|
+
byId.has(issueRow.lastSessionRecordingId)
|
|
1538
|
+
? issueRow.lastSessionRecordingId
|
|
1539
|
+
: null,
|
|
1473
1540
|
),
|
|
1474
1541
|
assignee: issueRow.assignee ?? null,
|
|
1475
1542
|
app: issueRow.app ?? null,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRequestOrgId,
|
|
3
|
+
getRequestUserEmail,
|
|
4
|
+
} from "@agent-native/core/server";
|
|
5
|
+
import {
|
|
6
|
+
getOrgSetting,
|
|
7
|
+
getUserSetting,
|
|
8
|
+
putOrgSetting,
|
|
9
|
+
putUserSetting,
|
|
10
|
+
} from "@agent-native/core/settings";
|
|
11
|
+
|
|
12
|
+
export const GONG_NATIVE_INSIGHTS_SETTING_KEY = "gong-native-insights-policy";
|
|
13
|
+
|
|
14
|
+
export interface GongNativeInsightsPolicy {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
configured: boolean;
|
|
17
|
+
scope: "workspace" | "user" | "none";
|
|
18
|
+
updatedAt: string | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function parsePolicy(
|
|
22
|
+
value: Record<string, unknown> | null,
|
|
23
|
+
scope: GongNativeInsightsPolicy["scope"],
|
|
24
|
+
): GongNativeInsightsPolicy {
|
|
25
|
+
return {
|
|
26
|
+
enabled: value?.enabled === true,
|
|
27
|
+
configured: value != null,
|
|
28
|
+
scope,
|
|
29
|
+
updatedAt: typeof value?.updatedAt === "string" ? value.updatedAt : null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function readGongNativeInsightsPolicy(): Promise<GongNativeInsightsPolicy> {
|
|
34
|
+
const orgId = getRequestOrgId() || null;
|
|
35
|
+
if (orgId) {
|
|
36
|
+
return parsePolicy(
|
|
37
|
+
await getOrgSetting(orgId, GONG_NATIVE_INSIGHTS_SETTING_KEY),
|
|
38
|
+
"workspace",
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const email = getRequestUserEmail();
|
|
43
|
+
if (email) {
|
|
44
|
+
return parsePolicy(
|
|
45
|
+
await getUserSetting(email, GONG_NATIVE_INSIGHTS_SETTING_KEY),
|
|
46
|
+
"user",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return parsePolicy(null, "none");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function writeGongNativeInsightsPolicy(
|
|
54
|
+
enabled: boolean,
|
|
55
|
+
): Promise<GongNativeInsightsPolicy> {
|
|
56
|
+
const orgId = getRequestOrgId() || null;
|
|
57
|
+
const email = getRequestUserEmail();
|
|
58
|
+
const value = {
|
|
59
|
+
enabled,
|
|
60
|
+
updatedAt: new Date().toISOString(),
|
|
61
|
+
updatedBy: email ?? "authenticated-agent",
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (orgId) {
|
|
65
|
+
await putOrgSetting(orgId, GONG_NATIVE_INSIGHTS_SETTING_KEY, value);
|
|
66
|
+
return parsePolicy(value, "workspace");
|
|
67
|
+
}
|
|
68
|
+
if (!email) throw new Error("no authenticated user");
|
|
69
|
+
|
|
70
|
+
await putUserSetting(email, GONG_NATIVE_INSIGHTS_SETTING_KEY, value);
|
|
71
|
+
return parsePolicy(value, "user");
|
|
72
|
+
}
|