@@ -178,6 +178,8 @@ import { McpAppFrame } from "./McpAppFrame";
178178import { ChangedFilesCard } from "./ChangedFilesTree" ;
179179import { useFileContextMenuHandler } from "../../fileContextMenu" ;
180180import { useProject , useThreadShell } from "../../state/entities" ;
181+ import { useSettingsProjectGroups } from "../settings/useSettingsProjectGroups" ;
182+ import { resolveCivilizationContextSettingsLink } from "./civilizationContextInspectorLink" ;
181183import {
182184 CHAT_TIMELINE_ANCHOR_OFFSET ,
183185 readTimelinePosition ,
@@ -2619,6 +2621,8 @@ function AssistantTimelineRow({ row }: { row: Extract<TimelineRow, { kind: "mess
26192621 className = "mt-1.5"
26202622 projectedItem = { row . projectedItem }
26212623 message = { row . message }
2624+ attemptId = { row . attemptId }
2625+ providerTurnOrdinal = { row . providerTurnOrdinal }
26222626 showCopyButton = { row . showAssistantCopyButton }
26232627 copyStreaming = { row . assistantCopyStreaming }
26242628 />
@@ -2685,6 +2689,8 @@ function AssistantMetaTimelineRow({
26852689 className = "mt-0.5"
26862690 projectedItem = { row . projectedItem }
26872691 message = { row . message }
2692+ attemptId = { row . attemptId }
2693+ providerTurnOrdinal = { row . providerTurnOrdinal }
26882694 showCopyButton = { row . showAssistantCopyButton }
26892695 copyStreaming = { row . assistantCopyStreaming }
26902696 alwaysVisible
@@ -2697,13 +2703,17 @@ function AssistantMessageMeta({
26972703 className,
26982704 projectedItem,
26992705 message,
2706+ attemptId,
2707+ providerTurnOrdinal,
27002708 showCopyButton,
27012709 copyStreaming,
27022710 alwaysVisible = false ,
27032711} : {
27042712 className ?: string ;
27052713 projectedItem ?: Extract < TimelineRow , { kind : "message" } > [ "projectedItem" ] ;
27062714 message : ChatMessage ;
2715+ attemptId ?: RunAttemptId | undefined ;
2716+ providerTurnOrdinal ?: number | undefined ;
27072717 showCopyButton : boolean ;
27082718 copyStreaming : boolean ;
27092719 alwaysVisible ?: boolean ;
@@ -2733,6 +2743,12 @@ function AssistantMessageMeta({
27332743 { projectedItem ?. item . type === "assistant_message" ? (
27342744 < AssistantForkButton projectedItem = { projectedItem } />
27352745 ) : null }
2746+ < CivilizationContextInspectionLink
2747+ projectedItem = { projectedItem }
2748+ message = { message }
2749+ attemptId = { attemptId }
2750+ providerTurnOrdinal = { providerTurnOrdinal }
2751+ />
27362752 { ! message . streaming && (
27372753 < Tooltip >
27382754 < TooltipTrigger render = { < p className = "text-muted-foreground text-xs tabular-nums" /> } >
@@ -2747,6 +2763,67 @@ function AssistantMessageMeta({
27472763 ) ;
27482764}
27492765
2766+ function CivilizationContextInspectionLink ( {
2767+ projectedItem,
2768+ message,
2769+ attemptId,
2770+ providerTurnOrdinal,
2771+ } : {
2772+ readonly projectedItem ?: Extract < TimelineRow , { kind : "message" } > [ "projectedItem" ] ;
2773+ readonly message : ChatMessage ;
2774+ readonly attemptId ?: RunAttemptId | undefined ;
2775+ readonly providerTurnOrdinal ?: number | undefined ;
2776+ } ) {
2777+ const ctx = use ( TimelineRowCtx ) ;
2778+ const sourceThreadId = projectedItem ?. sourceThreadId ?? null ;
2779+ const sourceThread = useThreadShell (
2780+ sourceThreadId === null ? null : scopeThreadRef ( ctx . activeThreadEnvironmentId , sourceThreadId ) ,
2781+ ) ;
2782+ const sourceProjectId = sourceThread ?. projectId ?? null ;
2783+ const projectGroups = useSettingsProjectGroups ( ) ;
2784+ const search = ( ( ) => {
2785+ if (
2786+ sourceThreadId === null ||
2787+ sourceProjectId === null ||
2788+ message . runId === null ||
2789+ attemptId === undefined ||
2790+ providerTurnOrdinal === undefined
2791+ ) {
2792+ return null ;
2793+ }
2794+ return resolveCivilizationContextSettingsLink ( {
2795+ groups : projectGroups ,
2796+ environmentId : ctx . activeThreadEnvironmentId ,
2797+ projectId : sourceProjectId ,
2798+ threadId : sourceThreadId ,
2799+ runId : message . runId ,
2800+ attemptId,
2801+ providerTurnOrdinal,
2802+ } ) ;
2803+ } ) ( ) ;
2804+
2805+ if ( search === null ) return null ;
2806+
2807+ return (
2808+ < Tooltip >
2809+ < TooltipTrigger
2810+ render = {
2811+ < Link
2812+ to = "/settings/civilization"
2813+ search = { search }
2814+ hash = "civilization-context-inspector"
2815+ className = "inline-flex size-6 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring/70"
2816+ aria-label = "Inspect Civilization context for this turn"
2817+ >
2818+ < EyeIcon className = "size-3.5" aria-hidden = "true" />
2819+ </ Link >
2820+ }
2821+ />
2822+ < TooltipPopup > Inspect Civilization context for this provider turn</ TooltipPopup >
2823+ </ Tooltip >
2824+ ) ;
2825+ }
2826+
27502827function AssistantCopyButton ( {
27512828 message,
27522829 showCopyButton,
0 commit comments