@sentry/junior 0.87.0 → 0.89.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/README.md +16 -5
- package/dist/{agent-hooks-NWOUB3UR.js → agent-hooks-RIJ5TSWP.js} +8 -8
- package/dist/api/people/list.d.ts +4 -0
- package/dist/api/people/list.js +83 -0
- package/dist/api/people/list.query.d.ts +4 -0
- package/dist/api/people/profile.d.ts +4 -0
- package/dist/api/people/profile.js +131 -0
- package/dist/api/people/profile.query.d.ts +4 -0
- package/dist/api/people/shared.d.ts +76 -0
- package/dist/api/people/types.d.ts +85 -0
- package/dist/app.js +43 -40
- package/dist/{catalog-runtime-XOD7YPRS.js → catalog-runtime-MW7XERSU.js} +3 -3
- package/dist/chat/conversations/sql/migrations.d.ts +1 -1
- package/dist/chat/conversations/sql/schema/identities.d.ts +54 -3
- package/dist/chat/conversations/sql/schema/users.d.ts +109 -0
- package/dist/chat/conversations/sql/schema.d.ts +164 -3
- package/dist/chat/conversations/sql/store.d.ts +0 -1
- package/dist/chat/identities/identity.d.ts +18 -0
- package/dist/chat/identities/sql.d.ts +4 -0
- package/dist/chat/runtime/processing-reaction.d.ts +2 -1
- package/dist/chat/runtime/slack-resume.d.ts +3 -2
- package/dist/chat/runtime/thread-context.d.ts +3 -1
- package/dist/chat/runtime/turn-user-message.d.ts +2 -1
- package/dist/chat/services/conversation-memory.d.ts +3 -1
- package/dist/chat/slack/message.d.ts +2 -1
- package/dist/chat/slack/outbound.d.ts +5 -4
- package/dist/chat/slack/timestamp.d.ts +6 -0
- package/dist/chat/sql/schema.d.ts +163 -3
- package/dist/chat/tools/slack/context.d.ts +2 -1
- package/dist/{chunk-ENPSU7L7.js → chunk-2DPZRS3B.js} +4 -4
- package/dist/{chunk-6I6HBOQM.js → chunk-4IXHIV37.js} +413 -157
- package/dist/{chunk-JRXCSSSU.js → chunk-6UPQ5GTJ.js} +3 -3
- package/dist/{chunk-64ACM6AP.js → chunk-7ES37H6U.js} +2 -2
- package/dist/{chunk-GGD6WK6V.js → chunk-AHLSXMOU.js} +2 -2
- package/dist/{chunk-2TAIGJPQ.js → chunk-C5NCV3OB.js} +1 -1
- package/dist/{chunk-6O5UI3RG.js → chunk-F22AM3OW.js} +1 -1
- package/dist/{chunk-BRSQQRG6.js → chunk-IATAYWFU.js} +2 -2
- package/dist/{chunk-BQ3ITJA6.js → chunk-KBFQXJL4.js} +2 -2
- package/dist/{chunk-ACJJJEGG.js → chunk-KBSLCOGE.js} +8 -8
- package/dist/{chunk-IXTBFABZ.js → chunk-KQKIA4CU.js} +1 -1
- package/dist/{chunk-B6FQPS7A.js → chunk-NYJLQI42.js} +22 -20
- package/dist/chunk-PBV4ZIVM.js +261 -0
- package/dist/{chunk-ZU2ALUVQ.js → chunk-S35CPNPT.js} +1 -1
- package/dist/{chunk-RIB3M6YA.js → chunk-V6XDCS3X.js} +4 -4
- package/dist/{chunk-KF7522P3.js → chunk-VMBZFPZM.js} +11 -1
- package/dist/{chunk-2NFV5FMB.js → chunk-XS6NLQPA.js} +21 -12
- package/dist/{chunk-GB5DFM4D.js → chunk-YPAE5RH3.js} +1 -1
- package/dist/cli/chat.js +6 -6
- package/dist/cli/check.js +4 -4
- package/dist/cli/init.js +30 -36
- package/dist/cli/plugins.js +11 -11
- package/dist/cli/snapshot-warmup.js +6 -6
- package/dist/cli/upgrade.js +12 -12
- package/dist/{db-SZVUU7RB.js → db-37HOGLI7.js} +5 -5
- package/dist/nitro.js +4 -4
- package/dist/reporting/conversations.d.ts +0 -56
- package/dist/reporting.d.ts +2 -8
- package/dist/reporting.js +14 -290
- package/dist/{runner-DMP3IQNM.js → runner-BCRF2FCI.js} +13 -13
- package/dist/{validation-MBNJKWPQ.js → validation-FMJO3L5P.js} +4 -4
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -10,6 +10,14 @@ pnpm add @sentry/junior hono @sentry/node
|
|
|
10
10
|
|
|
11
11
|
## Quick usage
|
|
12
12
|
|
|
13
|
+
`plugins.ts`:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { defineJuniorPlugins } from "@sentry/junior";
|
|
17
|
+
|
|
18
|
+
export const plugins = defineJuniorPlugins([]);
|
|
19
|
+
```
|
|
20
|
+
|
|
13
21
|
`server.ts`:
|
|
14
22
|
|
|
15
23
|
```ts
|
|
@@ -17,8 +25,11 @@ import { initSentry } from "@sentry/junior/instrumentation";
|
|
|
17
25
|
initSentry();
|
|
18
26
|
|
|
19
27
|
import { createApp } from "@sentry/junior";
|
|
28
|
+
import { plugins } from "./plugins.ts";
|
|
20
29
|
|
|
21
|
-
const app = await createApp(
|
|
30
|
+
const app = await createApp({
|
|
31
|
+
plugins,
|
|
32
|
+
});
|
|
22
33
|
|
|
23
34
|
export default app;
|
|
24
35
|
```
|
|
@@ -26,10 +37,10 @@ export default app;
|
|
|
26
37
|
Run `junior init my-bot` to scaffold a complete project including `vercel.json` for Vercel deployment.
|
|
27
38
|
|
|
28
39
|
Use `defineJuniorPlugins([...])` in a runtime-safe plugin module, then point
|
|
29
|
-
`juniorNitro({ plugins: "./plugins" })` at that module
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
`juniorNitro({ plugins: "./plugins" })` at that module and pass the same set to
|
|
41
|
+
`createApp({ plugins })`. Manifest-only packages use package-name strings;
|
|
42
|
+
factories such as `githubPlugin()` register their manifest and in-process hooks
|
|
43
|
+
together.
|
|
33
44
|
|
|
34
45
|
## Full docs
|
|
35
46
|
|
|
@@ -11,16 +11,16 @@ import {
|
|
|
11
11
|
getPlugins,
|
|
12
12
|
setPlugins,
|
|
13
13
|
validatePlugins
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-6I6HBOQM.js";
|
|
14
|
+
} from "./chunk-XS6NLQPA.js";
|
|
15
|
+
import "./chunk-IATAYWFU.js";
|
|
17
16
|
import "./chunk-G3E7SCME.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-YPAE5RH3.js";
|
|
18
|
+
import "./chunk-4IXHIV37.js";
|
|
19
|
+
import "./chunk-AHLSXMOU.js";
|
|
20
|
+
import "./chunk-S35CPNPT.js";
|
|
21
21
|
import "./chunk-L7OHKDOX.js";
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-KQKIA4CU.js";
|
|
23
|
+
import "./chunk-VMBZFPZM.js";
|
|
24
24
|
import "./chunk-FTMXFBDC.js";
|
|
25
25
|
import "./chunk-3DA7X2U3.js";
|
|
26
26
|
import "./chunk-MLKGABMK.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RequesterDirectoryReport } from "./types";
|
|
2
|
+
/** Load the people list from verified user identities in SQL. */
|
|
3
|
+
export declare function readPeopleList(): Promise<RequesterDirectoryReport>;
|
|
4
|
+
export type { RequesterDirectoryReport, RequesterIdentity, RequesterSummaryReport, RequesterTotalsReport, } from "./types";
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SAMPLE_LIMIT,
|
|
3
|
+
addSignals,
|
|
4
|
+
emptyTotals,
|
|
5
|
+
identityWithEmail,
|
|
6
|
+
mergeIdentity,
|
|
7
|
+
reportDate,
|
|
8
|
+
reportTime,
|
|
9
|
+
requesterRows,
|
|
10
|
+
signals,
|
|
11
|
+
summaryFromRow
|
|
12
|
+
} from "../../chunk-PBV4ZIVM.js";
|
|
13
|
+
import "../../chunk-4IXHIV37.js";
|
|
14
|
+
import "../../chunk-AHLSXMOU.js";
|
|
15
|
+
import "../../chunk-S35CPNPT.js";
|
|
16
|
+
import "../../chunk-L7OHKDOX.js";
|
|
17
|
+
import "../../chunk-KQKIA4CU.js";
|
|
18
|
+
import "../../chunk-VMBZFPZM.js";
|
|
19
|
+
import "../../chunk-FTMXFBDC.js";
|
|
20
|
+
import "../../chunk-3DA7X2U3.js";
|
|
21
|
+
import "../../chunk-MLKGABMK.js";
|
|
22
|
+
|
|
23
|
+
// src/api/people/list.query.ts
|
|
24
|
+
function directoryItem(accumulator) {
|
|
25
|
+
return {
|
|
26
|
+
active: accumulator.active,
|
|
27
|
+
activeDays: accumulator.activeDates.size,
|
|
28
|
+
conversations: accumulator.conversations,
|
|
29
|
+
durationMs: accumulator.durationMs,
|
|
30
|
+
failed: accumulator.failed,
|
|
31
|
+
firstSeenAt: new Date(accumulator.firstSeenMs).toISOString(),
|
|
32
|
+
hung: accumulator.hung,
|
|
33
|
+
lastSeenAt: new Date(accumulator.lastSeenMs).toISOString(),
|
|
34
|
+
requester: accumulator.requester,
|
|
35
|
+
runs: accumulator.runs
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async function readPeopleListFromSql(options = {}) {
|
|
39
|
+
const nowMs = Date.now();
|
|
40
|
+
const { rows, truncated } = await requesterRows(options);
|
|
41
|
+
const people = /* @__PURE__ */ new Map();
|
|
42
|
+
for (const row of rows) {
|
|
43
|
+
const summary = summaryFromRow(row, nowMs);
|
|
44
|
+
const requester = identityWithEmail(summary.requesterIdentity);
|
|
45
|
+
if (!requester) continue;
|
|
46
|
+
const firstSeenMs = reportTime(summary.startedAt) ?? row.createdAt.getTime();
|
|
47
|
+
const lastSeenMs = reportTime(summary.lastSeenAt) ?? row.lastActivityAt.getTime();
|
|
48
|
+
const date = reportDate(summary.lastSeenAt);
|
|
49
|
+
const accumulator = people.get(requester.email) ?? {
|
|
50
|
+
...emptyTotals(),
|
|
51
|
+
activeDates: /* @__PURE__ */ new Set(),
|
|
52
|
+
firstSeenMs,
|
|
53
|
+
lastSeenMs,
|
|
54
|
+
requester
|
|
55
|
+
};
|
|
56
|
+
accumulator.requester = mergeIdentity(accumulator.requester, requester);
|
|
57
|
+
accumulator.conversations += 1;
|
|
58
|
+
accumulator.runs += 1;
|
|
59
|
+
addSignals(accumulator, signals(summary));
|
|
60
|
+
accumulator.firstSeenMs = Math.min(accumulator.firstSeenMs, firstSeenMs);
|
|
61
|
+
accumulator.lastSeenMs = Math.max(accumulator.lastSeenMs, lastSeenMs);
|
|
62
|
+
if (date) accumulator.activeDates.add(date);
|
|
63
|
+
people.set(requester.email, accumulator);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
generatedAt: new Date(nowMs).toISOString(),
|
|
67
|
+
people: [...people.values()].map(directoryItem).sort(
|
|
68
|
+
(left, right) => (reportTime(right.lastSeenAt) ?? 0) - (reportTime(left.lastSeenAt) ?? 0) || right.conversations - left.conversations || left.requester.email.localeCompare(right.requester.email)
|
|
69
|
+
),
|
|
70
|
+
sampleLimit: SAMPLE_LIMIT,
|
|
71
|
+
sampleSize: rows.length,
|
|
72
|
+
source: "conversation_index",
|
|
73
|
+
truncated
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/api/people/list.ts
|
|
78
|
+
async function readPeopleList() {
|
|
79
|
+
return readPeopleListFromSql();
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
readPeopleList
|
|
83
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RequesterDirectoryReport } from "./types";
|
|
2
|
+
import { type PeopleApiQueryOptions } from "./shared";
|
|
3
|
+
/** Load the people list from the configured or injected SQL database. */
|
|
4
|
+
export declare function readPeopleListFromSql(options?: PeopleApiQueryOptions): Promise<RequesterDirectoryReport>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RequesterProfileReport } from "./types";
|
|
2
|
+
/** Load one person profile from verified user identities in SQL. */
|
|
3
|
+
export declare function readPeopleProfile(email: string): Promise<RequesterProfileReport>;
|
|
4
|
+
export type { ConversationStatsItem, ConversationSummaryReport, PeopleConversationStatus, PeopleConversationSurface, RequesterActivityDayReport, RequesterIdentity, RequesterProfileReport, RequesterTotalsReport, } from "./types";
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACTIVITY_DAYS,
|
|
3
|
+
RECENT_LIMIT,
|
|
4
|
+
SAMPLE_LIMIT,
|
|
5
|
+
activityDays,
|
|
6
|
+
addSignals,
|
|
7
|
+
emptyActivityDay,
|
|
8
|
+
emptyStatsItem,
|
|
9
|
+
emptyTotals,
|
|
10
|
+
identityWithEmail,
|
|
11
|
+
mergeIdentity,
|
|
12
|
+
normalizeEmail,
|
|
13
|
+
reportDate,
|
|
14
|
+
reportTime,
|
|
15
|
+
requesterRows,
|
|
16
|
+
signals,
|
|
17
|
+
slackLocationLabel,
|
|
18
|
+
statsItems,
|
|
19
|
+
summaryFromRow,
|
|
20
|
+
surfaceLabel
|
|
21
|
+
} from "../../chunk-PBV4ZIVM.js";
|
|
22
|
+
import "../../chunk-4IXHIV37.js";
|
|
23
|
+
import "../../chunk-AHLSXMOU.js";
|
|
24
|
+
import "../../chunk-S35CPNPT.js";
|
|
25
|
+
import "../../chunk-L7OHKDOX.js";
|
|
26
|
+
import "../../chunk-KQKIA4CU.js";
|
|
27
|
+
import "../../chunk-VMBZFPZM.js";
|
|
28
|
+
import "../../chunk-FTMXFBDC.js";
|
|
29
|
+
import "../../chunk-3DA7X2U3.js";
|
|
30
|
+
import "../../chunk-MLKGABMK.js";
|
|
31
|
+
|
|
32
|
+
// src/api/people/profile.query.ts
|
|
33
|
+
function emptyProfile(email, nowMs) {
|
|
34
|
+
const end = new Date(nowMs);
|
|
35
|
+
end.setUTCHours(0, 0, 0, 0);
|
|
36
|
+
const start = new Date(end);
|
|
37
|
+
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
38
|
+
return {
|
|
39
|
+
activityDays: activityDays(/* @__PURE__ */ new Map(), nowMs),
|
|
40
|
+
generatedAt: new Date(nowMs).toISOString(),
|
|
41
|
+
locations: [],
|
|
42
|
+
recentConversations: [],
|
|
43
|
+
requester: { email },
|
|
44
|
+
sampleLimit: SAMPLE_LIMIT,
|
|
45
|
+
sampleSize: 0,
|
|
46
|
+
source: "conversation_index",
|
|
47
|
+
surfaces: [],
|
|
48
|
+
totals: emptyTotals(),
|
|
49
|
+
truncated: false,
|
|
50
|
+
windowEnd: end.toISOString(),
|
|
51
|
+
windowStart: start.toISOString()
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function readPeopleProfileFromSql(email, options = {}) {
|
|
55
|
+
const nowMs = Date.now();
|
|
56
|
+
const normalizedEmail = normalizeEmail(email);
|
|
57
|
+
if (!normalizedEmail) {
|
|
58
|
+
return emptyProfile("", nowMs);
|
|
59
|
+
}
|
|
60
|
+
const { rows, truncated } = await requesterRows(options, normalizedEmail);
|
|
61
|
+
let requester;
|
|
62
|
+
const totals = emptyTotals();
|
|
63
|
+
const activeDates = /* @__PURE__ */ new Set();
|
|
64
|
+
const days = /* @__PURE__ */ new Map();
|
|
65
|
+
const locations = /* @__PURE__ */ new Map();
|
|
66
|
+
const surfaces = /* @__PURE__ */ new Map();
|
|
67
|
+
const recentConversations = [];
|
|
68
|
+
for (const row of rows) {
|
|
69
|
+
const summary = summaryFromRow(row, nowMs);
|
|
70
|
+
const identity = identityWithEmail(summary.requesterIdentity);
|
|
71
|
+
if (identity) {
|
|
72
|
+
requester = requester ? mergeIdentity(requester, identity) : identity;
|
|
73
|
+
}
|
|
74
|
+
recentConversations.push(summary);
|
|
75
|
+
const value = signals(summary);
|
|
76
|
+
const date = reportDate(summary.lastSeenAt);
|
|
77
|
+
totals.conversations += 1;
|
|
78
|
+
totals.runs += 1;
|
|
79
|
+
addSignals(totals, value);
|
|
80
|
+
if (date) {
|
|
81
|
+
activeDates.add(date);
|
|
82
|
+
const day = days.get(date) ?? emptyActivityDay(date);
|
|
83
|
+
day.conversations += 1;
|
|
84
|
+
day.runs += 1;
|
|
85
|
+
addSignals(day, value);
|
|
86
|
+
days.set(date, day);
|
|
87
|
+
}
|
|
88
|
+
const location = slackLocationLabel(summary) ?? surfaceLabel(summary.surface);
|
|
89
|
+
const locationItem = locations.get(location) ?? emptyStatsItem(location);
|
|
90
|
+
locationItem.conversations += 1;
|
|
91
|
+
locationItem.runs += 1;
|
|
92
|
+
addSignals(locationItem, value);
|
|
93
|
+
locations.set(location, locationItem);
|
|
94
|
+
const surface = surfaceLabel(summary.surface);
|
|
95
|
+
const surfaceItem = surfaces.get(surface) ?? emptyStatsItem(surface);
|
|
96
|
+
surfaceItem.conversations += 1;
|
|
97
|
+
surfaceItem.runs += 1;
|
|
98
|
+
addSignals(surfaceItem, value);
|
|
99
|
+
surfaces.set(surface, surfaceItem);
|
|
100
|
+
}
|
|
101
|
+
totals.activeDays = activeDates.size;
|
|
102
|
+
const end = new Date(nowMs);
|
|
103
|
+
end.setUTCHours(0, 0, 0, 0);
|
|
104
|
+
const start = new Date(end);
|
|
105
|
+
start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
|
|
106
|
+
return {
|
|
107
|
+
activityDays: activityDays(days, nowMs),
|
|
108
|
+
generatedAt: new Date(nowMs).toISOString(),
|
|
109
|
+
locations: statsItems(locations),
|
|
110
|
+
recentConversations: recentConversations.sort(
|
|
111
|
+
(left, right) => (reportTime(right.lastSeenAt) ?? 0) - (reportTime(left.lastSeenAt) ?? 0) || right.conversationId.localeCompare(left.conversationId)
|
|
112
|
+
).slice(0, RECENT_LIMIT),
|
|
113
|
+
requester: requester ?? { email: normalizedEmail },
|
|
114
|
+
sampleLimit: SAMPLE_LIMIT,
|
|
115
|
+
sampleSize: rows.length,
|
|
116
|
+
source: "conversation_index",
|
|
117
|
+
surfaces: statsItems(surfaces),
|
|
118
|
+
totals,
|
|
119
|
+
truncated,
|
|
120
|
+
windowEnd: end.toISOString(),
|
|
121
|
+
windowStart: start.toISOString()
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/api/people/profile.ts
|
|
126
|
+
async function readPeopleProfile(email) {
|
|
127
|
+
return readPeopleProfileFromSql(email);
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
readPeopleProfile
|
|
131
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RequesterProfileReport } from "./types";
|
|
2
|
+
import { type PeopleApiQueryOptions } from "./shared";
|
|
3
|
+
/** Load one person profile from the configured or injected SQL database. */
|
|
4
|
+
export declare function readPeopleProfileFromSql(email: string, options?: PeopleApiQueryOptions): Promise<RequesterProfileReport>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { JuniorDatabase } from "@/chat/sql/db";
|
|
2
|
+
import type { ConversationStatsItem, ConversationSummaryReport, PeopleConversationSurface, RequesterActivityDayReport, RequesterIdentity, RequesterTotalsReport } from "./types";
|
|
3
|
+
export declare const SAMPLE_LIMIT = 5000;
|
|
4
|
+
export declare const RECENT_LIMIT = 25;
|
|
5
|
+
export declare const ACTIVITY_DAYS = 366;
|
|
6
|
+
export interface PeopleApiQueryOptions {
|
|
7
|
+
db?: JuniorDatabase;
|
|
8
|
+
}
|
|
9
|
+
/** Normalize emails before matching people API rows. */
|
|
10
|
+
export declare function normalizeEmail(email: string | undefined): string | undefined;
|
|
11
|
+
/** Parse report timestamps without throwing on malformed legacy values. */
|
|
12
|
+
export declare function reportTime(value: string): number | undefined;
|
|
13
|
+
/** Convert a report timestamp into the UTC day used for people activity. */
|
|
14
|
+
export declare function reportDate(value: string): string | undefined;
|
|
15
|
+
/** Return the dashboard label for a conversation surface. */
|
|
16
|
+
export declare function surfaceLabel(surface: PeopleConversationSurface): string;
|
|
17
|
+
/** Return the dashboard-safe Slack location label for a conversation. */
|
|
18
|
+
export declare function slackLocationLabel(args: {
|
|
19
|
+
channel?: string;
|
|
20
|
+
channelName?: string;
|
|
21
|
+
channelNameRedacted?: boolean;
|
|
22
|
+
}): string | undefined;
|
|
23
|
+
/** Project one SQL conversation row into the people API conversation summary. */
|
|
24
|
+
export declare function summaryFromRow(row: PeopleConversationRow, nowMs: number): ConversationSummaryReport;
|
|
25
|
+
/** Build a zeroed totals object for people API aggregations. */
|
|
26
|
+
export declare function emptyTotals(): RequesterTotalsReport;
|
|
27
|
+
/** Build a zeroed labeled stats row for people API aggregations. */
|
|
28
|
+
export declare function emptyStatsItem(label: string): ConversationStatsItem;
|
|
29
|
+
/** Build a zeroed activity day for the people profile window. */
|
|
30
|
+
export declare function emptyActivityDay(date: string): RequesterActivityDayReport;
|
|
31
|
+
/** Collapse a conversation summary status into aggregate counters. */
|
|
32
|
+
export declare function signals(summary: ConversationSummaryReport): {
|
|
33
|
+
active: boolean;
|
|
34
|
+
failed: boolean;
|
|
35
|
+
hung: boolean;
|
|
36
|
+
};
|
|
37
|
+
/** Add status counters into a people API aggregate row. */
|
|
38
|
+
export declare function addSignals(target: Pick<RequesterTotalsReport, "active" | "failed" | "hung">, value: ReturnType<typeof signals>): void;
|
|
39
|
+
/** Return only requester identities that can be grouped by normalized email. */
|
|
40
|
+
export declare function identityWithEmail(requester: RequesterIdentity | undefined): (RequesterIdentity & {
|
|
41
|
+
email: string;
|
|
42
|
+
}) | undefined;
|
|
43
|
+
/** Preserve the first observed person fields while filling missing details. */
|
|
44
|
+
export declare function mergeIdentity(current: RequesterIdentity & {
|
|
45
|
+
email: string;
|
|
46
|
+
}, next: RequesterIdentity & {
|
|
47
|
+
email: string;
|
|
48
|
+
}): RequesterIdentity & {
|
|
49
|
+
email: string;
|
|
50
|
+
};
|
|
51
|
+
/** Fill the fixed people profile activity window from sparse day totals. */
|
|
52
|
+
export declare function activityDays(days: Map<string, RequesterActivityDayReport>, nowMs: number): RequesterActivityDayReport[];
|
|
53
|
+
/** Return deterministic stats rows for people API responses. */
|
|
54
|
+
export declare function statsItems(map: Map<string, ConversationStatsItem>): ConversationStatsItem[];
|
|
55
|
+
/** Read verified requester conversation rows directly from the SQL identity model. */
|
|
56
|
+
export declare function requesterRows(options?: PeopleApiQueryOptions, email?: string): Promise<{
|
|
57
|
+
rows: {
|
|
58
|
+
channelName: string | null;
|
|
59
|
+
conversationId: string;
|
|
60
|
+
createdAt: Date;
|
|
61
|
+
destinationVisibility: import("../../chat/conversations/sql/schema/destinations").JuniorDestinationVisibility | null;
|
|
62
|
+
email: string;
|
|
63
|
+
executionStatus: import("../../chat/conversations/store").ConversationStatus;
|
|
64
|
+
executionUpdatedAt: Date | null;
|
|
65
|
+
fullName: string | null;
|
|
66
|
+
handle: string | null;
|
|
67
|
+
lastActivityAt: Date;
|
|
68
|
+
providerSubjectId: string;
|
|
69
|
+
runId: string | null;
|
|
70
|
+
source: import("../../chat/conversations/store").ConversationSource | null;
|
|
71
|
+
title: string | null;
|
|
72
|
+
updatedAt: Date;
|
|
73
|
+
}[];
|
|
74
|
+
truncated: boolean;
|
|
75
|
+
}>;
|
|
76
|
+
export type PeopleConversationRow = Awaited<ReturnType<typeof requesterRows>>["rows"][number];
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type PeopleConversationStatus = "active" | "completed" | "failed" | "hung";
|
|
2
|
+
export type PeopleConversationSurface = "api" | "internal" | "scheduler" | "slack";
|
|
3
|
+
export interface RequesterIdentity {
|
|
4
|
+
email?: string;
|
|
5
|
+
fullName?: string;
|
|
6
|
+
slackUserId?: string;
|
|
7
|
+
slackUserName?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ConversationSummaryReport {
|
|
10
|
+
cumulativeDurationMs: number;
|
|
11
|
+
conversationId: string;
|
|
12
|
+
displayTitle: string;
|
|
13
|
+
id: string;
|
|
14
|
+
lastProgressAt: string;
|
|
15
|
+
lastSeenAt: string;
|
|
16
|
+
startedAt: string;
|
|
17
|
+
status: PeopleConversationStatus;
|
|
18
|
+
surface: PeopleConversationSurface;
|
|
19
|
+
channel?: string;
|
|
20
|
+
channelName?: string;
|
|
21
|
+
channelNameRedacted?: boolean;
|
|
22
|
+
requesterIdentity?: RequesterIdentity;
|
|
23
|
+
}
|
|
24
|
+
export interface ConversationStatsItem {
|
|
25
|
+
active: number;
|
|
26
|
+
conversations: number;
|
|
27
|
+
durationMs: number;
|
|
28
|
+
failed: number;
|
|
29
|
+
hung: number;
|
|
30
|
+
label: string;
|
|
31
|
+
runs: number;
|
|
32
|
+
tokens?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface RequesterActivityDayReport {
|
|
35
|
+
active: number;
|
|
36
|
+
conversations: number;
|
|
37
|
+
date: string;
|
|
38
|
+
durationMs: number;
|
|
39
|
+
failed: number;
|
|
40
|
+
hung: number;
|
|
41
|
+
runs: number;
|
|
42
|
+
tokens?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface RequesterTotalsReport {
|
|
45
|
+
active: number;
|
|
46
|
+
activeDays: number;
|
|
47
|
+
conversations: number;
|
|
48
|
+
durationMs: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
hung: number;
|
|
51
|
+
runs: number;
|
|
52
|
+
tokens?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface RequesterSummaryReport extends RequesterTotalsReport {
|
|
55
|
+
firstSeenAt: string;
|
|
56
|
+
lastSeenAt: string;
|
|
57
|
+
requester: RequesterIdentity & {
|
|
58
|
+
email: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export interface RequesterDirectoryReport {
|
|
62
|
+
generatedAt: string;
|
|
63
|
+
people: RequesterSummaryReport[];
|
|
64
|
+
sampleLimit: number;
|
|
65
|
+
sampleSize: number;
|
|
66
|
+
source: "conversation_index";
|
|
67
|
+
truncated: boolean;
|
|
68
|
+
}
|
|
69
|
+
export interface RequesterProfileReport {
|
|
70
|
+
activityDays: RequesterActivityDayReport[];
|
|
71
|
+
generatedAt: string;
|
|
72
|
+
locations: ConversationStatsItem[];
|
|
73
|
+
recentConversations: ConversationSummaryReport[];
|
|
74
|
+
requester: RequesterIdentity & {
|
|
75
|
+
email: string;
|
|
76
|
+
};
|
|
77
|
+
sampleLimit: number;
|
|
78
|
+
sampleSize: number;
|
|
79
|
+
source: "conversation_index";
|
|
80
|
+
surfaces: ConversationStatsItem[];
|
|
81
|
+
totals: RequesterTotalsReport;
|
|
82
|
+
truncated: boolean;
|
|
83
|
+
windowEnd: string;
|
|
84
|
+
windowStart: string;
|
|
85
|
+
}
|