@@ -2117,14 +2117,7 @@ export function formatIssueOutput({
21172117 // Event type union is: ErrorEvent | DefaultEvent | TransactionEvent | GenericEvent | CspEvent
21182118 // But in practice we may have other types returned as UnknownEvent
21192119 const eventType = event . type ;
2120- const isUnsupportedType =
2121- eventType !== "error" &&
2122- eventType !== "default" &&
2123- eventType !== "transaction" &&
2124- eventType !== "generic" &&
2125- eventType !== "csp" ;
2126-
2127- if ( isUnsupportedType ) {
2120+ if ( ! isSupportedEventType ( event ) ) {
21282121 // Log to Sentry for tracking new/unknown event types
21292122 const sentryEventId = logIssue (
21302123 `Unsupported event type encountered: ${ String ( eventType ) } ` ,
@@ -2216,27 +2209,67 @@ export function formatIssueOutput({
22162209 output += "\n" ;
22172210 }
22182211
2212+ output += "## Response Notes\n\n" ;
2213+ for ( const note of buildIssueResponseNotes ( {
2214+ organizationSlug,
2215+ issue,
2216+ event,
2217+ apiService,
2218+ aiConversations,
2219+ experimentalMode,
2220+ availableToolNames,
2221+ directToolNames,
2222+ } ) ) {
2223+ output += `- ${ note } \n` ;
2224+ }
2225+ return output ;
2226+ }
2227+
2228+ export function buildIssueResponseNotes ( {
2229+ organizationSlug,
2230+ issue,
2231+ event,
2232+ apiService,
2233+ aiConversations,
2234+ experimentalMode,
2235+ availableToolNames,
2236+ directToolNames,
2237+ } : {
2238+ organizationSlug : string ;
2239+ issue : Issue ;
2240+ event : Event ;
2241+ apiService : SentryApiService ;
2242+ aiConversations ?: AIConversationReference [ ] ;
2243+ experimentalMode ?: boolean ;
2244+ availableToolNames ?: ReadonlySet < string > ;
2245+ directToolNames ?: ReadonlySet < string > ;
2246+ } ) : string [ ] {
2247+ const notes : string [ ] = [ ] ;
22192248 const traceId =
22202249 typeof event . contexts ?. trace ?. trace_id === "string" &&
22212250 event . contexts . trace . trace_id . length > 0
22222251 ? event . contexts . trace . trace_id
22232252 : undefined ;
22242253
2225- output += "## Response Notes\n\n" ;
22262254 const commitIssueReference = / ^ \d + $ / . test ( issue . shortId )
22272255 ? apiService . getIssueUrl ( organizationSlug , issue . shortId )
22282256 : issue . shortId ;
2229- output += `- Commit message issue reference: \`Fixes ${ commitIssueReference } \` automatically closes the issue when the commit is merged.\n` ;
2230- output +=
2231- "- The stacktrace includes first-party application code and third-party code. First-party frames are usually the best starting point for triage.\n" ;
2257+ notes . push (
2258+ `Commit message issue reference: \`Fixes ${ commitIssueReference } \` automatically closes the issue when the commit is merged.` ,
2259+ ) ;
2260+ notes . push (
2261+ "The stacktrace includes first-party application code and third-party code. First-party frames are usually the best starting point for triage." ,
2262+ ) ;
22322263 if ( aiConversations && aiConversations . length > 0 ) {
2233- output += formatAIConversationResponseNote ( {
2234- aiConversations,
2235- organizationSlug,
2236- experimentalMode : experimentalMode ?? false ,
2237- availableToolNames,
2238- directToolNames,
2239- } ) ;
2264+ notes . push (
2265+ ...buildAIConversationResponseNotes ( {
2266+ aiConversations,
2267+ organizationSlug,
2268+ experimentalMode : experimentalMode ?? false ,
2269+ availableToolNames,
2270+ directToolNames,
2271+ } ) ,
2272+ ) ;
22402273 }
22412274 const issueEventSearchInstruction = formatToolCallInstruction ( {
22422275 toolName : "search_issue_events" ,
@@ -2250,7 +2283,7 @@ export function formatIssueOutput({
22502283 directToolNames,
22512284 fallbackInstruction : "Issue event search is not available in this session" ,
22522285 } ) ;
2253- output += `- Issue event search: ${ issueEventSearchInstruction } \n` ;
2286+ notes . push ( ` Issue event search: ${ issueEventSearchInstruction } ` ) ;
22542287 const hasMultipleThreads = event . entries ?. some ( ( entry ) => {
22552288 if ( entry . type !== "threads" ) {
22562289 return false ;
@@ -2275,7 +2308,7 @@ export function formatIssueOutput({
22752308 "to fetch a full thread stacktrace by numeric Thread ID or exact thread Name. Omit `thread` to use Sentry's default selected thread" ,
22762309 } ) ;
22772310 if ( stacktraceInstruction ) {
2278- output += `- Thread stacktrace lookup: ${ stacktraceInstruction } \n` ;
2311+ notes . push ( ` Thread stacktrace lookup: ${ stacktraceInstruction } ` ) ;
22792312 }
22802313 }
22812314 if ( traceId ) {
@@ -2316,9 +2349,11 @@ export function formatIssueOutput({
23162349 fallbackInstruction :
23172350 "Related log search is not available in this session" ,
23182351 } ) ;
2319- output += `- Full distributed trace and span tree: ${ traceDetailsInstruction } \n` ;
2320- output += `- Related span search: ${ spanSearchInstruction } \n` ;
2321- output += `- Related log search: ${ logSearchInstruction } \n` ;
2352+ notes . push (
2353+ `Full distributed trace and span tree: ${ traceDetailsInstruction } ` ,
2354+ ) ;
2355+ notes . push ( `Related span search: ${ spanSearchInstruction } ` ) ;
2356+ notes . push ( `Related log search: ${ logSearchInstruction } ` ) ;
23222357 }
23232358 if ( experimentalMode ) {
23242359 const breadcrumbsInstruction = formatToolCallInstruction ( {
@@ -2332,12 +2367,14 @@ export function formatIssueOutput({
23322367 fallbackInstruction :
23332368 "Issue breadcrumbs are not available in this session" ,
23342369 } ) ;
2335- output += `- Breadcrumb trail leading up to this error: ${ breadcrumbsInstruction } \n` ;
2370+ notes . push (
2371+ `Breadcrumb trail leading up to this error: ${ breadcrumbsInstruction } ` ,
2372+ ) ;
23362373 }
2337- return output ;
2374+ return notes ;
23382375}
23392376
2340- function formatAIConversationResponseNote ( {
2377+ function buildAIConversationResponseNotes ( {
23412378 aiConversations,
23422379 organizationSlug,
23432380 experimentalMode,
@@ -2349,7 +2386,7 @@ function formatAIConversationResponseNote({
23492386 experimentalMode : boolean ;
23502387 availableToolNames ?: ReadonlySet < string > ;
23512388 directToolNames ?: ReadonlySet < string > ;
2352- } ) : string {
2389+ } ) : string [ ] {
23532390 const instructions = formatAIConversationActionInstructions ( {
23542391 organizationSlug,
23552392 aiConversations,
@@ -2363,13 +2400,27 @@ function formatAIConversationResponseNote({
23632400 const spanSuffix = conversation . spanId
23642401 ? ` Matching span: \`${ conversation . spanId } \`.`
23652402 : "" ;
2366- return `- Agent conversation found in this trace: \`${ conversation . conversationId } \`.${ spanSuffix } \n${ instructions . map ( ( instruction ) => `- ${ instruction } ` ) . join ( "\n" ) } \n` ;
2403+ return [
2404+ `Agent conversation found in this trace: \`${ conversation . conversationId } \`.${ spanSuffix } ` ,
2405+ ...instructions ,
2406+ ] ;
23672407 }
23682408
23692409 const conversationIds = aiConversations
23702410 . map ( ( conversation ) => `\`${ conversation . conversationId } \`` )
23712411 . join ( ", " ) ;
2372- return `- Multiple agent conversations were found in this trace: ${ conversationIds } .\n${ instructions . map ( ( instruction ) => `- ${ instruction } ` ) . join ( "\n" ) } \n` ;
2412+ return [
2413+ `Multiple agent conversations were found in this trace: ${ conversationIds } .` ,
2414+ ...instructions ,
2415+ ] ;
2416+ }
2417+
2418+ function formatAIConversationResponseNote (
2419+ args : Parameters < typeof buildAIConversationResponseNotes > [ 0 ] ,
2420+ ) : string {
2421+ return `${ buildAIConversationResponseNotes ( args )
2422+ . map ( ( note ) => `- ${ note } ` )
2423+ . join ( "\n" ) } \n`;
23732424}
23742425
23752426const MAX_DISPLAY_REPLAYS = 5 ;
0 commit comments