@@ -7,9 +7,10 @@ import { CancellationToken } from '../../../../../base/common/cancellation.js';
77import { Codicon } from '../../../../../base/common/codicons.js' ;
88import { MarkdownString } from '../../../../../base/common/htmlContent.js' ;
99import { KeyCode , KeyMod } from '../../../../../base/common/keyCodes.js' ;
10- import { basename } from '../../../../../base/common/resources.js' ;
10+ import { basename , relativePath } from '../../../../../base/common/resources.js' ;
1111import { ThemeIcon } from '../../../../../base/common/themables.js' ;
1212import { assertType } from '../../../../../base/common/types.js' ;
13+ import { URI } from '../../../../../base/common/uri.js' ;
1314import { ServicesAccessor } from '../../../../../editor/browser/editorExtensions.js' ;
1415import { EditorContextKeys } from '../../../../../editor/common/editorContextKeys.js' ;
1516import { localize , localize2 } from '../../../../../nls.js' ;
@@ -22,6 +23,7 @@ import { IInstantiationService } from '../../../../../platform/instantiation/com
2223import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js' ;
2324import { IQuickInputService } from '../../../../../platform/quickinput/common/quickInput.js' ;
2425import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js' ;
26+ import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js' ;
2527import { IEditorService } from '../../../../services/editor/common/editorService.js' ;
2628import { IRemoteCodingAgent , IRemoteCodingAgentsService } from '../../../remoteCodingAgents/common/remoteCodingAgentsService.js' ;
2729import { IChatAgentHistoryEntry , IChatAgentService } from '../../common/chatAgents.js' ;
@@ -33,6 +35,7 @@ import { ChatRequestParser } from '../../common/chatRequestParser.js';
3335import { IChatPullRequestContent , IChatService } from '../../common/chatService.js' ;
3436import { IChatSessionsExtensionPoint , IChatSessionsService } from '../../common/chatSessionsService.js' ;
3537import { ChatSessionUri } from '../../common/chatUri.js' ;
38+ import { ChatRequestVariableSet , isChatRequestFileEntry } from '../../common/chatVariableEntries.js' ;
3639import { ChatAgentLocation , ChatConfiguration , ChatModeKind , } from '../../common/constants.js' ;
3740import { ILanguageModelChatMetadata } from '../../common/languageModels.js' ;
3841import { ILanguageModelToolsService } from '../../common/languageModelToolsService.js' ;
@@ -662,6 +665,47 @@ export class CreateRemoteAgentJobAction extends Action2 {
662665 }
663666 }
664667
668+ /**
669+ * Converts full URIs from the user's systems into workspace-relative paths for coding agent.
670+ */
671+ private extractRelativeFromAttachedContext ( attachedContext : ChatRequestVariableSet , workspaceContextService : IWorkspaceContextService ) : string [ ] {
672+ const workspaceFolder = workspaceContextService . getWorkspace ( ) . folders [ 0 ] ;
673+ if ( ! workspaceFolder ) {
674+ return [ ] ;
675+ }
676+ const relativePaths : string [ ] = [ ] ;
677+ for ( const contextEntry of attachedContext . asArray ( ) ) {
678+ if ( isChatRequestFileEntry ( contextEntry ) ) { // TODO: Extend for more variable types as needed
679+ if ( ! ( contextEntry . value instanceof URI ) ) {
680+ continue ;
681+ }
682+ const fileUri = contextEntry . value ;
683+ const relativePathResult = relativePath ( workspaceFolder . uri , fileUri ) ;
684+ if ( relativePathResult ) {
685+ relativePaths . push ( relativePathResult ) ;
686+ }
687+ }
688+ }
689+ return relativePaths ;
690+ }
691+
692+ private extractChatTurns ( historyEntries : IChatAgentHistoryEntry [ ] ) : string {
693+ let result = '\n' ;
694+ for ( const entry of historyEntries ) {
695+ if ( entry . request . message ) {
696+ result += `User: ${ entry . request . message } \n` ;
697+ }
698+ if ( entry . response ) {
699+ for ( const content of entry . response ) {
700+ if ( content . kind === 'markdownContent' ) {
701+ result += `AI: ${ content . content . value } \n` ;
702+ }
703+ }
704+ }
705+ }
706+ return `${ result } \n` ;
707+ }
708+
665709 async run ( accessor : ServicesAccessor , ...args : any [ ] ) {
666710 const contextKeyService = accessor . get ( IContextKeyService ) ;
667711 const remoteJobCreatingKey = ChatContextKeys . remoteJobCreating . bindTo ( contextKeyService ) ;
@@ -702,26 +746,31 @@ export class CreateRemoteAgentJobAction extends Action2 {
702746 userPrompt = 'implement this.' ;
703747 }
704748
749+ const attachedContext = widget . input . getAttachedAndImplicitContext ( session ) ;
705750 widget . input . acceptInput ( true ) ;
706751
707752 const defaultAgent = chatAgentService . getDefaultAgent ( ChatAgentLocation . Panel ) ;
708-
709- // Parse the request text to create a structured request
710753 const instantiationService = accessor . get ( IInstantiationService ) ;
711754 const requestParser = instantiationService . createInstance ( ChatRequestParser ) ;
712755 const parsedRequest = requestParser . parseChatRequest ( session , userPrompt , ChatAgentLocation . Panel ) ;
713756
757+
714758 // Add the request to the model first
715759 const addedRequest = chatModel . addRequest (
716760 parsedRequest ,
717- { variables : [ ] } ,
761+ { variables : attachedContext . asArray ( ) } ,
718762 0 ,
719763 undefined ,
720764 defaultAgent ,
721765 ) ;
722766
723- let summary : string | undefined ;
724- if ( defaultAgent && chatRequests . length > 0 ) {
767+ let summary : string = '' ;
768+ const relativeAttachedContext = this . extractRelativeFromAttachedContext ( attachedContext , accessor . get ( IWorkspaceContextService ) ) ;
769+ if ( relativeAttachedContext . length ) {
770+ summary += `\n\n${ localize ( 'attachedFiles' , "The user has attached the following files from their workspace:" ) } \n${ relativeAttachedContext . map ( file => `- ${ file } ` ) . join ( '\n' ) } \n\n` ;
771+ }
772+
773+ if ( defaultAgent && chatRequests . length > 1 ) {
725774 chatModel . acceptResponseProgress ( addedRequest , {
726775 kind : 'progressMessage' ,
727776 content : new MarkdownString (
@@ -745,7 +794,13 @@ export class CreateRemoteAgentJobAction extends Action2 {
745794 result : req . response ?. result ?? { }
746795 } ) ) ;
747796
748- summary = await chatAgentService . getChatSummary ( defaultAgent . id , historyEntries , CancellationToken . None ) ;
797+ // TODO: Determine a cutoff point where we stop including earlier history
798+ // For example, if the user has already delegated to a coding agent once,
799+ // prefer the conversation afterwards.
800+
801+ summary += 'The following is a snapshot of a chat conversation between a user and an AI coding assistant. Prioritize later messages in the conversation.' ;
802+ summary += this . extractChatTurns ( historyEntries ) ;
803+ summary += await chatAgentService . getChatSummary ( defaultAgent . id , historyEntries , CancellationToken . None ) ;
749804 }
750805
751806 chatModel . acceptResponseProgress ( addedRequest , {
0 commit comments