@sentry/junior-dashboard 0.91.0 → 0.92.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.
@@ -2,7 +2,7 @@ import { useState } from "react";
2
2
  import { Link, useParams } from "react-router";
3
3
  import { Mail, UserRound } from "lucide-react";
4
4
 
5
- import { useRequesterDirectoryData, useRequesterProfileData } from "../api";
5
+ import { useActorDirectoryData, useActorProfileData } from "../api";
6
6
  import { Button } from "../components/Button";
7
7
  import { ConversationList } from "../components/ConversationList";
8
8
  import { ConversationSearchInput } from "../components/ConversationListControls";
@@ -23,37 +23,31 @@ import {
23
23
  import { cn } from "../styles";
24
24
  import type {
25
25
  ConversationStatsItem,
26
- RequesterActivityDay,
27
- RequesterDirectory,
28
- RequesterProfile,
29
- RequesterSummary,
30
- RequesterTotals,
26
+ ActorActivityDay,
27
+ ActorDirectory,
28
+ ActorProfile,
29
+ ActorSummary,
30
+ ActorTotals,
31
31
  } from "../types";
32
32
 
33
33
  type PeopleSort = "activeDays" | "conversations" | "recent" | "runtime";
34
34
 
35
- function requesterName(person: Pick<RequesterSummary, "requester">): string {
35
+ function actorName(person: Pick<ActorSummary, "actor">): string {
36
36
  return (
37
- person.requester.fullName ??
38
- person.requester.slackUserName ??
39
- person.requester.email
37
+ person.actor.fullName ?? person.actor.slackUserName ?? person.actor.email
40
38
  );
41
39
  }
42
40
 
43
- function personMeta(person: RequesterSummary): string {
41
+ function personMeta(person: ActorSummary): string {
44
42
  const pieces = [
45
- person.requester.email,
46
- person.requester.slackUserName
47
- ? `@${person.requester.slackUserName}`
48
- : undefined,
43
+ person.actor.email,
44
+ person.actor.slackUserName ? `@${person.actor.slackUserName}` : undefined,
49
45
  `last ${formatRelativeTime(person.lastSeenAt)}`,
50
46
  ];
51
47
  return pieces.filter(Boolean).join(" / ");
52
48
  }
53
49
 
54
- function sampleLabel(
55
- data: Pick<RequesterDirectory, "sampleSize" | "truncated">,
56
- ) {
50
+ function sampleLabel(data: Pick<ActorDirectory, "sampleSize" | "truncated">) {
57
51
  return `${formatCompactNumber(data.sampleSize)} sampled conversations${
58
52
  data.truncated ? " / limited sample" : ""
59
53
  }`;
@@ -64,18 +58,18 @@ function runtimeLabel(durationMs: number, conversations: number): string {
64
58
  return formatMs(durationMs);
65
59
  }
66
60
 
67
- /** Render the requester directory from dashboard reporting data. */
61
+ /** Render the actor directory from dashboard reporting data. */
68
62
  export function PeoplePage() {
69
- const query = useRequesterDirectoryData();
63
+ const query = useActorDirectoryData();
70
64
  return <PeoplePageContent data={query.data} error={query.error} />;
71
65
  }
72
66
 
73
- /** Render loaded, failed, and empty requester directory states. */
67
+ /** Render loaded, failed, and empty actor directory states. */
74
68
  export function PeoplePageContent({
75
69
  data,
76
70
  error,
77
71
  }: {
78
- data: RequesterDirectory | undefined;
72
+ data: ActorDirectory | undefined;
79
73
  error: unknown;
80
74
  }) {
81
75
  const [peopleSearch, setPeopleSearch] = useState("");
@@ -92,7 +86,7 @@ export function PeoplePageContent({
92
86
  <SectionTitle>People</SectionTitle>
93
87
  <div className="mt-1 break-words text-[0.82rem] leading-relaxed text-[#b8b8b8]">
94
88
  {data
95
- ? `${people.length} of ${data.people.length} requesters / ${sampleLabel(data)}`
89
+ ? `${people.length} of ${data.people.length} actors / ${sampleLabel(data)}`
96
90
  : "People failed to load"}
97
91
  </div>
98
92
  </div>
@@ -116,7 +110,7 @@ export function PeoplePageContent({
116
110
  ) : (
117
111
  <div className="p-3">
118
112
  <EmptyTelemetry>
119
- No requester telemetry with trusted email.
113
+ No actor telemetry with trusted email.
120
114
  </EmptyTelemetry>
121
115
  </div>
122
116
  )}
@@ -126,18 +120,18 @@ export function PeoplePageContent({
126
120
  }
127
121
 
128
122
  function filterPeople(
129
- people: RequesterSummary[],
123
+ people: ActorSummary[],
130
124
  query: string,
131
125
  sort: PeopleSort,
132
- ): RequesterSummary[] {
126
+ ): ActorSummary[] {
133
127
  const normalized = query.trim().toLowerCase();
134
128
  const filtered = normalized
135
129
  ? people.filter((person) =>
136
130
  [
137
- person.requester.email,
138
- person.requester.fullName,
139
- person.requester.slackUserId,
140
- person.requester.slackUserName,
131
+ person.actor.email,
132
+ person.actor.fullName,
133
+ person.actor.slackUserId,
134
+ person.actor.slackUserName,
141
135
  ]
142
136
  .filter(Boolean)
143
137
  .join(" ")
@@ -196,7 +190,7 @@ function PeopleToolbar(props: {
196
190
  );
197
191
  }
198
192
 
199
- function PeopleDirectory(props: { people: RequesterSummary[] }) {
193
+ function PeopleDirectory(props: { people: ActorSummary[] }) {
200
194
  if (props.people.length === 0) {
201
195
  return (
202
196
  <div className="p-3">
@@ -210,7 +204,7 @@ function PeopleDirectory(props: { people: RequesterSummary[] }) {
210
204
  className="sticky top-0 z-[1] grid grid-cols-[minmax(14rem,1fr)_repeat(3,minmax(5rem,auto))] items-center gap-3 border-b border-white/10 bg-[#050505] px-3 py-2 text-[0.76rem] font-semibold uppercase leading-none text-[#888] max-md:hidden"
211
205
  role="row"
212
206
  >
213
- <div>Requester</div>
207
+ <div>Actor</div>
214
208
  <div className="justify-self-end">Conversations</div>
215
209
  <div className="justify-self-end">Active days</div>
216
210
  <div className="justify-self-end">Runtime</div>
@@ -218,8 +212,8 @@ function PeopleDirectory(props: { people: RequesterSummary[] }) {
218
212
  {props.people.map((person) => (
219
213
  <Link
220
214
  className="grid min-w-0 grid-cols-[minmax(14rem,1fr)_repeat(3,minmax(5rem,auto))] items-center gap-3 border-b border-l-4 border-b-white/10 border-l-[#22a06b] bg-[#0b0b0b] px-3 py-3 text-inherit no-underline transition-colors hover:bg-[#151515] max-md:grid-cols-1 max-md:px-4 max-md:py-4"
221
- key={person.requester.email}
222
- to={peoplePath(person.requester.email)}
215
+ key={person.actor.email}
216
+ to={peoplePath(person.actor.email)}
223
217
  >
224
218
  <div className="min-w-0">
225
219
  <div className="flex min-w-0 items-center gap-2">
@@ -228,7 +222,7 @@ function PeopleDirectory(props: { people: RequesterSummary[] }) {
228
222
  </span>
229
223
  <div className="min-w-0">
230
224
  <div className="truncate text-[1.02rem] font-bold leading-tight text-white">
231
- {requesterName(person)}
225
+ {actorName(person)}
232
226
  </div>
233
227
  <div className="mt-1 truncate text-[0.82rem] leading-tight text-[#b8b8b8]">
234
228
  {personMeta(person)}
@@ -255,11 +249,11 @@ function DirectoryNumber(props: { value: number }) {
255
249
  );
256
250
  }
257
251
 
258
- /** Render one requester's profile and recent conversation history. */
252
+ /** Render one actor's profile and recent conversation history. */
259
253
  export function PersonProfilePage() {
260
254
  const params = useParams();
261
255
  const email = params.email ? decodeURIComponent(params.email) : undefined;
262
- const query = useRequesterProfileData(email);
256
+ const query = useActorProfileData(email);
263
257
  if (!query.data && !query.error) {
264
258
  return <LoadingView label="Loading profile" />;
265
259
  }
@@ -279,7 +273,7 @@ export function PersonProfilePage() {
279
273
  );
280
274
  }
281
275
 
282
- export function Profile(props: { profile: RequesterProfile }) {
276
+ export function Profile(props: { profile: ActorProfile }) {
283
277
  const profile = props.profile;
284
278
  const [recentSearch, setRecentSearch] = useState("");
285
279
  const conversations = buildConversations(profile.recentConversations);
@@ -297,14 +291,14 @@ export function Profile(props: { profile: RequesterProfile }) {
297
291
  </span>
298
292
  <div className="min-w-0">
299
293
  <h2 className="m-0 truncate text-2xl font-extrabold leading-tight tracking-normal text-white">
300
- {profile.requester.fullName ??
301
- profile.requester.slackUserName ??
302
- profile.requester.email}
294
+ {profile.actor.fullName ??
295
+ profile.actor.slackUserName ??
296
+ profile.actor.email}
303
297
  </h2>
304
298
  <div className="mt-1 break-words text-[0.88rem] leading-relaxed text-[#b8b8b8]">
305
- {profile.requester.email}
306
- {profile.requester.slackUserName
307
- ? ` / @${profile.requester.slackUserName}`
299
+ {profile.actor.email}
300
+ {profile.actor.slackUserName
301
+ ? ` / @${profile.actor.slackUserName}`
308
302
  : ""}
309
303
  </div>
310
304
  </div>
@@ -368,7 +362,7 @@ export function Profile(props: { profile: RequesterProfile }) {
368
362
  );
369
363
  }
370
364
 
371
- function ProfileMetrics(props: { totals: RequesterTotals }) {
365
+ function ProfileMetrics(props: { totals: ActorTotals }) {
372
366
  const totals = props.totals;
373
367
  const metrics = [
374
368
  ["conversations", formatCompactNumber(totals.conversations)],
@@ -395,22 +389,19 @@ function ProfileMetrics(props: { totals: RequesterTotals }) {
395
389
  );
396
390
  }
397
391
 
398
- function ContributionGrid(props: { days: RequesterActivityDay[] }) {
392
+ function ContributionGrid(props: { days: ActorActivityDay[] }) {
399
393
  const max = Math.max(1, ...props.days.map((day) => day.conversations));
400
- const weeks: Array<Array<RequesterActivityDay | null>> = [];
394
+ const weeks: Array<Array<ActorActivityDay | null>> = [];
401
395
  const leadingDays = props.days[0]
402
396
  ? new Date(`${props.days[0].date}T00:00:00Z`).getUTCDay()
403
397
  : 0;
404
- const cells: Array<RequesterActivityDay | null> = [
398
+ const cells: Array<ActorActivityDay | null> = [
405
399
  ...Array.from({ length: leadingDays }, () => null),
406
400
  ...props.days,
407
401
  ];
408
402
  while (cells.length > 0 && cells.length % 7 !== 0) cells.push(null);
409
403
  for (let index = 0; index < cells.length; index += 7) {
410
- const week: Array<RequesterActivityDay | null> = cells.slice(
411
- index,
412
- index + 7,
413
- );
404
+ const week: Array<ActorActivityDay | null> = cells.slice(index, index + 7);
414
405
  while (week.length < 7) week.push(null);
415
406
  weeks.push(week);
416
407
  }
@@ -16,14 +16,14 @@ import type {
16
16
  SkillReport,
17
17
  } from "@sentry/junior/reporting";
18
18
  import type {
19
- RequesterDirectoryReport,
20
- RequesterIdentity as ApiRequesterIdentity,
21
- RequesterSummaryReport,
22
- RequesterTotalsReport,
19
+ ActorDirectoryReport,
20
+ ActorIdentity as ApiActorIdentity,
21
+ ActorSummaryReport,
22
+ ActorTotalsReport,
23
23
  } from "@sentry/junior/api/people/list";
24
24
  import type {
25
- RequesterActivityDayReport,
26
- RequesterProfileReport,
25
+ ActorActivityDayReport,
26
+ ActorProfileReport,
27
27
  } from "@sentry/junior/api/people/profile";
28
28
 
29
29
  export type Health = HealthReport;
@@ -45,17 +45,17 @@ export type ConversationSubagentTranscript =
45
45
 
46
46
  export type ConversationStatsItem = ReportingConversationStatsItem;
47
47
 
48
- export type RequesterIdentity = ApiRequesterIdentity;
48
+ export type ActorIdentity = ApiActorIdentity;
49
49
 
50
- export type RequesterActivityDay = RequesterActivityDayReport;
50
+ export type ActorActivityDay = ActorActivityDayReport;
51
51
 
52
- export type RequesterDirectory = RequesterDirectoryReport;
52
+ export type ActorDirectory = ActorDirectoryReport;
53
53
 
54
- export type RequesterProfile = RequesterProfileReport;
54
+ export type ActorProfile = ActorProfileReport;
55
55
 
56
- export type RequesterSummary = RequesterSummaryReport;
56
+ export type ActorSummary = ActorSummaryReport;
57
57
 
58
- export type RequesterTotals = RequesterTotalsReport;
58
+ export type ActorTotals = ActorTotalsReport;
59
59
 
60
60
  export type TurnUsage = ConversationUsage;
61
61
 
@@ -136,7 +136,7 @@ export type Conversation = {
136
136
  id: string;
137
137
  lastProgressAt: string;
138
138
  lastSeenAt: string;
139
- requesterIdentity?: RequesterIdentity;
139
+ actorIdentity?: ActorIdentity;
140
140
  sentryTraceUrl?: string;
141
141
  startedAt: string;
142
142
  status: ConversationSummary["status"];
@@ -3,7 +3,7 @@ import type {
3
3
  ConversationStatsItem as DashboardConversationStatsItem,
4
4
  ConversationStatsReport as DashboardConversationStatsReport,
5
5
  ConversationSubagentTranscriptReport as DashboardConversationSubagentTranscriptReport,
6
- RequesterIdentity as DashboardRequesterIdentity,
6
+ ActorIdentity as DashboardActorIdentity,
7
7
  ConversationFeed as DashboardConversationFeed,
8
8
  ConversationSummaryReport as DashboardConversationSummary,
9
9
  ConversationUsage as DashboardRunUsage,
@@ -90,7 +90,7 @@ function publicIncidentConversation(
90
90
  totalTokens: 9700,
91
91
  },
92
92
  surface: "slack",
93
- requesterIdentity: {
93
+ actorIdentity: {
94
94
  email: "avery@sentry.io",
95
95
  fullName: "Avery Stone",
96
96
  slackUserId: "UQA111",
@@ -189,7 +189,7 @@ function publicIncidentConversation(
189
189
  totalTokens: 9250,
190
190
  },
191
191
  surface: "slack",
192
- requesterIdentity: {
192
+ actorIdentity: {
193
193
  email: "morgan@sentry.io",
194
194
  fullName: "Morgan Lee",
195
195
  slackUserId: "UQA222",
@@ -284,7 +284,7 @@ function activeConversation(nowMs: number): DashboardConversationReport {
284
284
  totalTokens: 8420,
285
285
  },
286
286
  surface: "slack",
287
- requesterIdentity: {
287
+ actorIdentity: {
288
288
  email: "sam@sentry.io",
289
289
  fullName: "Sam Rivera",
290
290
  slackUserId: "UQA333",
@@ -355,7 +355,7 @@ function privateConversation(nowMs: number): DashboardConversationReport {
355
355
  totalTokens: 3540,
356
356
  },
357
357
  surface: "slack",
358
- requesterIdentity: {
358
+ actorIdentity: {
359
359
  email: "private-user@sentry.io",
360
360
  slackUserId: "UQA444",
361
361
  slackUserName: "private-user",
@@ -462,7 +462,7 @@ function hungConversation(nowMs: number): DashboardConversationReport {
462
462
  totalTokens: 12_000,
463
463
  },
464
464
  surface: "slack",
465
- requesterIdentity: {
465
+ actorIdentity: {
466
466
  email: "dana@sentry.io",
467
467
  fullName: "Dana Chen",
468
468
  slackUserId: "UQA555",
@@ -540,7 +540,7 @@ function failedConversation(nowMs: number): DashboardConversationReport {
540
540
  totalTokens: 4890,
541
541
  },
542
542
  surface: "slack",
543
- requesterIdentity: {
543
+ actorIdentity: {
544
544
  email: "riley@sentry.io",
545
545
  fullName: "Riley Patel",
546
546
  slackUserId: "UQA666",
@@ -774,7 +774,7 @@ function dashboardQaConversation(nowMs: number): DashboardConversationReport {
774
774
  name: "advisor",
775
775
  input: {
776
776
  question:
777
- "Review the dashboard plan before editing. Focus on whether requester email can be trusted, what profile metrics are useful, and what UI risks to avoid.",
777
+ "Review the dashboard plan before editing. Focus on whether actor email can be trusted, what profile metrics are useful, and what UI risks to avoid.",
778
778
  },
779
779
  }),
780
780
  ],
@@ -789,7 +789,7 @@ function dashboardQaConversation(nowMs: number): DashboardConversationReport {
789
789
  output: {
790
790
  verdict: "proceed",
791
791
  summary:
792
- "Use trusted requesterIdentity.email, keep metrics to conversations/runtime/tokens, and make profile activity scannable before adding heavier analytics.",
792
+ "Use trusted actorIdentity.email, keep metrics to conversations/runtime/tokens, and make profile activity scannable before adding heavier analytics.",
793
793
  },
794
794
  }),
795
795
  ],
@@ -823,7 +823,7 @@ function dashboardQaConversation(nowMs: number): DashboardConversationReport {
823
823
  },
824
824
  ],
825
825
  summary:
826
- "Add requester activity grid, recent conversations, and email profile links.",
826
+ "Add actor activity grid, recent conversations, and email profile links.",
827
827
  },
828
828
  }),
829
829
  ],
@@ -846,7 +846,7 @@ function dashboardQaConversation(nowMs: number): DashboardConversationReport {
846
846
  risks: {
847
847
  auth: "dashboard routes remain authenticated",
848
848
  privacy:
849
- "requester emails are trusted from normalized reporting identity",
849
+ "actor emails are trusted from normalized reporting identity",
850
850
  },
851
851
  },
852
852
  }),
@@ -911,7 +911,7 @@ function dashboardQaConversation(nowMs: number): DashboardConversationReport {
911
911
  parts: [
912
912
  {
913
913
  type: "text",
914
- text: "Implemented the people profile route, linked requester emails, and tightened the dashboard widgets based on the advisor review.",
914
+ text: "Implemented the people profile route, linked actor emails, and tightened the dashboard widgets based on the advisor review.",
915
915
  },
916
916
  ],
917
917
  }),
@@ -925,7 +925,7 @@ function dashboardQaConversation(nowMs: number): DashboardConversationReport {
925
925
  status: "completed",
926
926
  args: {
927
927
  question:
928
- "Review the dashboard plan before editing. Focus on whether requester email can be trusted, what profile metrics are useful, and what UI risks to avoid.",
928
+ "Review the dashboard plan before editing. Focus on whether actor email can be trusted, what profile metrics are useful, and what UI risks to avoid.",
929
929
  },
930
930
  subagents: [
931
931
  mockSubagentActivity({
@@ -1014,7 +1014,7 @@ function dashboardQaAdvisorTranscript(
1014
1014
  parts: [
1015
1015
  {
1016
1016
  type: "text",
1017
- text: "Review the dashboard plan before editing. Focus on whether requester email can be trusted, what profile metrics are useful, and what UI risks to avoid.",
1017
+ text: "Review the dashboard plan before editing. Focus on whether actor email can be trusted, what profile metrics are useful, and what UI risks to avoid.",
1018
1018
  },
1019
1019
  ],
1020
1020
  }),
@@ -1024,7 +1024,7 @@ function dashboardQaAdvisorTranscript(
1024
1024
  parts: [
1025
1025
  {
1026
1026
  type: "text",
1027
- text: "Requester identity email is a reasonable profile key because reporting already normalizes trusted identities. Keep the first cut narrow: total conversations, runtime, token volume, recent conversations, and a contribution-style activity grid. Avoid attention widgets until there is an explicit operator workflow.",
1027
+ text: "Actor identity email is a reasonable profile key because reporting already normalizes trusted identities. Keep the first cut narrow: total conversations, runtime, token volume, recent conversations, and a contribution-style activity grid. Avoid attention widgets until there is an explicit operator workflow.",
1028
1028
  },
1029
1029
  ],
1030
1030
  }),
@@ -1137,7 +1137,7 @@ function conversationStatsReportFromSummaries(
1137
1137
  summaries: DashboardConversationSummary[],
1138
1138
  ): DashboardConversationStatsReport {
1139
1139
  const conversations = recentConversationGroups(nowMs, summaries);
1140
- const requesters = new Map<string, DashboardConversationStatsItem>();
1140
+ const actors = new Map<string, DashboardConversationStatsItem>();
1141
1141
  const locations = new Map<string, DashboardConversationStatsItem>();
1142
1142
  let durationMs = 0;
1143
1143
  let tokens: number | undefined;
@@ -1155,29 +1155,25 @@ function conversationStatsReportFromSummaries(
1155
1155
  failed += signals.failed ? 1 : 0;
1156
1156
  hung += signals.hung ? 1 : 0;
1157
1157
 
1158
- const requesterRuns = new Map<string, RunContribution[]>();
1158
+ const actorRuns = new Map<string, RunContribution[]>();
1159
1159
  for (const contribution of contributions) {
1160
- const requester =
1161
- requesterLabel(contribution.run.requesterIdentity) ?? "Unknown";
1162
- requesterRuns.set(requester, [
1163
- ...(requesterRuns.get(requester) ?? []),
1164
- contribution,
1165
- ]);
1160
+ const actor = actorLabel(contribution.run.actorIdentity) ?? "Unknown";
1161
+ actorRuns.set(actor, [...(actorRuns.get(actor) ?? []), contribution]);
1166
1162
  }
1167
1163
 
1168
- for (const [requester, requesterContributions] of requesterRuns) {
1169
- const item = requesters.get(requester) ?? emptyStatsItem(requester);
1170
- const requesterSignals = statusSignals(
1171
- requesterContributions.map((contribution) => contribution.run),
1164
+ for (const [actor, actorContributions] of actorRuns) {
1165
+ const item = actors.get(actor) ?? emptyStatsItem(actor);
1166
+ const actorSignals = statusSignals(
1167
+ actorContributions.map((contribution) => contribution.run),
1172
1168
  );
1173
1169
  item.conversations += 1;
1174
- item.runs += requesterContributions.length;
1175
- item.durationMs += contributionDurationTotal(requesterContributions);
1176
- item.active += requesterSignals.active ? 1 : 0;
1177
- item.failed += requesterSignals.failed ? 1 : 0;
1178
- item.hung += requesterSignals.hung ? 1 : 0;
1179
- addItemTokens(item, contributionTokenTotal(requesterContributions));
1180
- requesters.set(requester, item);
1170
+ item.runs += actorContributions.length;
1171
+ item.durationMs += contributionDurationTotal(actorContributions);
1172
+ item.active += actorSignals.active ? 1 : 0;
1173
+ item.failed += actorSignals.failed ? 1 : 0;
1174
+ item.hung += actorSignals.hung ? 1 : 0;
1175
+ addItemTokens(item, contributionTokenTotal(actorContributions));
1176
+ actors.set(actor, item);
1181
1177
  }
1182
1178
 
1183
1179
  const location = locationLabel(newestRun(runs));
@@ -1200,7 +1196,7 @@ function conversationStatsReportFromSummaries(
1200
1196
  generatedAt: iso(nowMs),
1201
1197
  hung,
1202
1198
  locations: statsItems(locations),
1203
- requesters: statsItems(requesters),
1199
+ actors: statsItems(actors),
1204
1200
  sampleLimit: summaries.length,
1205
1201
  sampleSize: summaries.length,
1206
1202
  source: "conversation_index",
@@ -1332,13 +1328,13 @@ function contributionTokenTotal(
1332
1328
  );
1333
1329
  }
1334
1330
 
1335
- function requesterLabel(
1336
- requester: DashboardRequesterIdentity | undefined,
1331
+ function actorLabel(
1332
+ actor: DashboardActorIdentity | undefined,
1337
1333
  ): string | undefined {
1338
- const email = requester?.email?.trim() || undefined;
1339
- const fullName = requester?.fullName?.trim() || undefined;
1340
- const slackUserName = requester?.slackUserName?.trim() || undefined;
1341
- return email ?? fullName ?? slackUserName ?? requester?.slackUserId;
1334
+ const email = actor?.email?.trim() || undefined;
1335
+ const fullName = actor?.fullName?.trim() || undefined;
1336
+ const slackUserName = actor?.slackUserName?.trim() || undefined;
1337
+ return email ?? fullName ?? slackUserName ?? actor?.slackUserId;
1342
1338
  }
1343
1339
 
1344
1340
  function locationLabel(turn: DashboardConversationSummary): string {
@@ -34,7 +34,7 @@ function mockSystemPrompt(): string {
34
34
  "",
35
35
  "- Default application repo: acme/junior-demo.",
36
36
  "- Default package namespace: @acme/junior.",
37
- "- Open pull requests as drafts unless the requester asks for ready review.",
37
+ "- Open pull requests as drafts unless the actor asks for ready review.",
38
38
  "",
39
39
  "# Slack Output",
40
40
  "",
@@ -555,7 +555,7 @@ export function longReleaseConversation(
555
555
  outputTokens: 1037,
556
556
  },
557
557
  surface: "slack",
558
- requesterIdentity: {
558
+ actorIdentity: {
559
559
  fullName: "Jordan Blake",
560
560
  slackUserId: "UQA777",
561
561
  slackUserName: "jordan",
@@ -585,7 +585,7 @@ export function longReleaseConversation(
585
585
  outputTokens: 5765,
586
586
  },
587
587
  surface: "slack",
588
- requesterIdentity: {
588
+ actorIdentity: {
589
589
  fullName: "Jordan Blake",
590
590
  slackUserId: "UQA777",
591
591
  slackUserName: "jordan",
@@ -5,7 +5,7 @@ import type {
5
5
  ConversationRunReport,
6
6
  ConversationSurface,
7
7
  ConversationUsage,
8
- RequesterIdentity,
8
+ ActorIdentity,
9
9
  TranscriptMessage,
10
10
  } from "@sentry/junior/reporting";
11
11
 
@@ -24,7 +24,7 @@ export type MockRunOptions = {
24
24
  id?: string;
25
25
  lastProgressAt?: string;
26
26
  lastSeenAt?: string;
27
- requesterIdentity?: RequesterIdentity;
27
+ actorIdentity?: ActorIdentity;
28
28
  sentryTraceUrl?: string;
29
29
  startedAt?: string;
30
30
  status?: ConversationReportStatus;
@@ -64,8 +64,8 @@ export function mockRun(options: MockRunOptions = {}): ConversationRunReport {
64
64
  ...(options.cumulativeUsage !== undefined
65
65
  ? { cumulativeUsage: options.cumulativeUsage }
66
66
  : {}),
67
- ...(options.requesterIdentity !== undefined
68
- ? { requesterIdentity: options.requesterIdentity }
67
+ ...(options.actorIdentity !== undefined
68
+ ? { actorIdentity: options.actorIdentity }
69
69
  : {}),
70
70
  ...(options.sentryTraceUrl !== undefined
71
71
  ? { sentryTraceUrl: options.sentryTraceUrl }