55
66import { CancellationToken , CancellationTokenSource } from '../../../../base/common/cancellation.js' ;
77import { Disposable } from '../../../../base/common/lifecycle.js' ;
8+ import { OS } from '../../../../base/common/platform.js' ;
89import { generateUuid } from '../../../../base/common/uuid.js' ;
910import { localize } from '../../../../nls.js' ;
1011import { ILogService } from '../../../../platform/log/common/log.js' ;
1112import { IWorkbenchContribution } from '../../../common/contributions.js' ;
1213import { IChatDebugCustomizationLogEntry , IChatDebugEventFileListContent , IChatDebugResolvedEventContent , IChatDebugService } from '../common/chatDebugService.js' ;
1314import { IChatAgentService } from '../common/participants/chatAgents.js' ;
1415import { IChatService } from '../common/chatService/chatService.js' ;
15- import { ChatRequestHooks } from '../common/promptSyntax/hookSchema.js' ;
16+ import { ChatRequestHooks , formatHookCommandLabel } from '../common/promptSyntax/hookSchema.js' ;
1617import { HookType } from '../common/promptSyntax/hookTypes.js' ;
1718import { PromptsType } from '../common/promptSyntax/promptTypes.js' ;
18- import { IHookDiscoveryInfo , type InstructionsCollectionEvent , IPromptDiscoveryInfo , IPromptsService } from '../common/promptSyntax/service/promptsService.js' ;
19+ import { IHookDiscoveryInfo , type InstructionsCollectionDebugInfo , IPromptDiscoveryInfo , IPromptsService } from '../common/promptSyntax/service/promptsService.js' ;
20+ import { lastInstructionsCollectionResult } from '../common/promptSyntax/computeAutomaticInstructions.js' ;
1921
2022interface ICustomizationEventData {
21- readonly collectionEvent : InstructionsCollectionEvent ;
23+ readonly debugInfo : InstructionsCollectionDebugInfo ;
2224 readonly hooks : ChatRequestHooks | undefined ;
2325}
2426
@@ -123,35 +125,36 @@ export class PromptsDebugContribution extends Disposable implements IWorkbenchCo
123125 }
124126
125127 // Log resolved customizations from the last instructions collection.
126- const collectionEvent = this . promptsService . lastInstructionsCollectionEvent ;
127- if ( ! isFirstInvocation && collectionEvent ) {
128- // Also fetch the resolved hooks so they appear in the customization summary.
128+ const lastResult = lastInstructionsCollectionResult ;
129+ if ( ! isFirstInvocation && lastResult ) {
130+ const { telemetryEvent : collectionEvent , debugInfo } = lastResult ;
131+ // Fetch the cached hook discovery info.
129132 let resolvedHooks : ChatRequestHooks | undefined ;
130133 try {
131- const hooksInfo = await this . promptsService . getHooks ( CancellationToken . None ) ;
132- resolvedHooks = hooksInfo ?. hooks ;
134+ const hookDiscoveryInfo = await this . promptsService . getDiscoveryInfo ( PromptsType . hook , CancellationToken . None ) as IHookDiscoveryInfo ;
135+ resolvedHooks = hookDiscoveryInfo . hooksInfo ?. hooks ;
133136 } catch ( error ) {
134137 logService . warn ( 'Error while fetching hooks for customization debug event' , error ) ;
135138 }
136139
137140 const parts : string [ ] = [ ] ;
138141 if ( collectionEvent . applyingInstructionsCount > 0 ) {
139- parts . push ( ` ${ collectionEvent . applyingInstructionsCount } applying` ) ;
142+ parts . push ( localize ( 'customizations.applying' , '{0 } applying' , collectionEvent . applyingInstructionsCount ) ) ;
140143 }
141144 if ( collectionEvent . referencedInstructionsCount > 0 ) {
142- parts . push ( ` ${ collectionEvent . referencedInstructionsCount } referenced` ) ;
145+ parts . push ( localize ( 'customizations.referenced' , '{0 } referenced' , collectionEvent . referencedInstructionsCount ) ) ;
143146 }
144147 if ( collectionEvent . agentInstructionsCount > 0 ) {
145- parts . push ( ` ${ collectionEvent . agentInstructionsCount } agent` ) ;
148+ parts . push ( localize ( 'customizations.agent' , '{0 } agent' , collectionEvent . agentInstructionsCount ) ) ;
146149 }
147150 if ( collectionEvent . listedInstructionsCount > 0 ) {
148- parts . push ( ` ${ collectionEvent . listedInstructionsCount } listed` ) ;
151+ parts . push ( localize ( 'customizations.listed' , '{0 } listed' , collectionEvent . listedInstructionsCount ) ) ;
149152 }
150- const durationStr = collectionEvent . durationInMillis . toFixed ( 1 ) ;
153+ const durationStr = debugInfo . durationInMillis . toFixed ( 1 ) ;
151154 const summary = parts . length > 0
152155 ? localize ( 'customizationsResolved.details' , 'Resolved {0} customizations ({1}) in {2}ms' , collectionEvent . totalInstructionsCount , parts . join ( ', ' ) , durationStr )
153156 : localize ( 'customizationsResolved.none' , 'No customizations resolved' ) ;
154- const detailSummaries = collectionEvent . debugDetails . map ( e => {
157+ const detailSummaries = debugInfo . debugDetails . map ( e => {
155158 const detail = e . reason ? `${ e . name } — ${ e . reason } ` : e . name ;
156159 return `[${ e . category } ] ${ detail } ` ;
157160 } ) ;
@@ -160,7 +163,7 @@ export class PromptsDebugContribution extends Disposable implements IWorkbenchCo
160163 : summary ;
161164
162165 const customizationEventId = generateUuid ( ) ;
163- this . _customizationEventDetails . set ( customizationEventId , { collectionEvent , hooks : resolvedHooks } ) ;
166+ this . _customizationEventDetails . set ( customizationEventId , { debugInfo , hooks : resolvedHooks } ) ;
164167
165168 // Evict oldest entries when the map exceeds the cap.
166169 if ( this . _customizationEventDetails . size > PromptsDebugContribution . MAX_DISCOVERY_DETAILS ) {
@@ -198,28 +201,28 @@ export class PromptsDebugContribution extends Disposable implements IWorkbenchCo
198201 switch ( discoveryInfo . type ) {
199202 case PromptsType . prompt :
200203 return {
201- name : localize ( 'promptsService.loadSlashCommands' , 'Load Slash Commands' ) ,
204+ name : localize ( 'promptsService.loadSlashCommands' , 'Slash Commands Discovery ' ) ,
202205 details : loadedCount === 1
203206 ? localize ( 'promptsDebugContribution.resolvedSlashCommand' , 'Resolved {0} slash command in {1}ms' , loadedCount , durationInMillis )
204207 : localize ( 'promptsDebugContribution.resolvedSlashCommands' , 'Resolved {0} slash commands in {1}ms' , loadedCount , durationInMillis )
205208 } ;
206209 case PromptsType . agent :
207210 return {
208- name : localize ( 'promptsService.loadAgents' , 'Load Agents ' ) ,
211+ name : localize ( 'promptsService.loadAgents' , 'Agent Discovery ' ) ,
209212 details : loadedCount === 1
210213 ? localize ( 'promptsDebugContribution.resolvedAgent' , 'Resolved {0} agent in {1}ms' , loadedCount , durationInMillis )
211214 : localize ( 'promptsDebugContribution.resolvedAgents' , 'Resolved {0} agents in {1}ms' , loadedCount , durationInMillis )
212215 } ;
213216 case PromptsType . skill :
214217 return {
215- name : localize ( 'promptsService.loadSkills' , 'Load Skills ' ) ,
218+ name : localize ( 'promptsService.loadSkills' , 'Skill Discovery ' ) ,
216219 details : loadedCount === 1
217220 ? localize ( 'promptsDebugContribution.resolvedSkill' , 'Resolved {0} skill in {1}ms' , loadedCount , durationInMillis )
218221 : localize ( 'promptsDebugContribution.resolvedSkills' , 'Resolved {0} skills in {1}ms' , loadedCount , durationInMillis )
219222 } ;
220223 case PromptsType . instructions :
221224 return {
222- name : localize ( 'promptsService.loadInstructions' , 'Load Instructions' ) ,
225+ name : localize ( 'promptsService.loadInstructions' , 'Instructions Discovery ' ) ,
223226 details : loadedCount === 1
224227 ? localize ( 'promptsDebugContribution.resolvedInstruction' , 'Resolved {0} instruction in {1}ms' , loadedCount , durationInMillis )
225228 : localize ( 'promptsDebugContribution.resolvedInstructions' , 'Resolved {0} instructions in {1}ms' , loadedCount , durationInMillis )
@@ -235,7 +238,7 @@ export class PromptsDebugContribution extends Disposable implements IWorkbenchCo
235238 ? localize ( 'promptsDebugContribution.resolvedHook' , 'Resolved {0} hook in {1}ms' , hookCount , durationInMillis )
236239 : localize ( 'promptsDebugContribution.resolvedHooks' , 'Resolved {0} hooks in {1}ms' , hookCount , durationInMillis ) ;
237240 return {
238- name : localize ( 'promptsService.loadHooks' , 'Load Hooks ' ) ,
241+ name : localize ( 'promptsService.loadHooks' , 'Hook Discovery ' ) ,
239242 details
240243 } ;
241244 }
@@ -257,20 +260,21 @@ export class PromptsDebugContribution extends Disposable implements IWorkbenchCo
257260 return undefined ;
258261 }
259262
260- const { collectionEvent , hooks } = data ;
261- const logs : IChatDebugCustomizationLogEntry [ ] = [ ...collectionEvent . debugDetails ] ;
263+ const { debugInfo , hooks } = data ;
264+ const logs : IChatDebugCustomizationLogEntry [ ] = [ ...debugInfo . debugDetails ] ;
262265
263- // Add hook entries from the resolved hooks.
266+ // Add hook entries from the resolved hooks — each command carries its sourceUri .
264267 if ( hooks ) {
265268 for ( const hookType of Object . values ( HookType ) ) {
266269 const commands = hooks [ hookType ] ;
267270 if ( commands && commands . length > 0 ) {
268271 for ( const cmd of commands ) {
269- const commandStr = cmd . command ?? cmd . osx ?? cmd . linux ?? cmd . windows ?? ' unknown' ;
272+ const commandLabel = formatHookCommandLabel ( cmd , OS ) || localize ( 'hook.unknownCommand' , '( unknown command)' ) ;
270273 logs . push ( {
271274 category : 'hook' ,
272- name : hookType ,
273- reason : commandStr ,
275+ name : commandLabel ,
276+ reason : hookType ,
277+ uri : cmd . sourceUri ,
274278 } ) ;
275279 }
276280 }
@@ -280,7 +284,7 @@ export class PromptsDebugContribution extends Disposable implements IWorkbenchCo
280284 return {
281285 kind : 'customizationSummary' ,
282286 resolutionLogs : logs ,
283- durationInMillis : collectionEvent . durationInMillis ,
287+ durationInMillis : debugInfo . durationInMillis ,
284288 counts : {
285289 instructions : logs . filter ( e => e . category === 'applying' || e . category === 'referenced' ) . length ,
286290 skills : logs . filter ( e => e . category === 'skill' ) . length ,
0 commit comments