@@ -20,7 +20,6 @@ import type { IManagedHoverContent } from '../../../../base/browser/ui/hover/hov
2020import { IMenuEntryActionViewItemOptions , MenuEntryActionViewItem } from '../../../../platform/actions/browser/menuEntryActionViewItem.js' ;
2121import { CodeEditorWidget , ICodeEditorWidgetOptions } from '../../../../editor/browser/widget/codeEditor/codeEditorWidget.js' ;
2222import { EditorExtensionsRegistry } from '../../../../editor/browser/editorExtensions.js' ;
23- import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js' ;
2423import { IEditorConstructionOptions } from '../../../../editor/browser/config/editorConfiguration.js' ;
2524import { ITextModel } from '../../../../editor/common/model.js' ;
2625import { IModelService } from '../../../../editor/common/services/model.js' ;
@@ -30,7 +29,6 @@ import { EditorOptions } from '../../../../editor/common/config/editorOptions.js
3029import { SuggestController } from '../../../../editor/contrib/suggest/browser/suggestController.js' ;
3130import { SnippetController2 } from '../../../../editor/contrib/snippet/browser/snippetController2.js' ;
3231import { CopyPasteController } from '../../../../editor/contrib/dropOrPasteInto/browser/copyPasteController.js' ;
33- import { LinkDetector } from '../../../../editor/contrib/links/browser/links.js' ;
3432import { PlaceholderTextContribution } from '../../../../editor/contrib/placeholderText/browser/placeholderTextContribution.js' ;
3533import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js' ;
3634import { ContextKeyExpr , IContextKeyService , RawContextKey } from '../../../../platform/contextkey/common/contextkey.js' ;
@@ -109,9 +107,8 @@ import { IChatStatusItemService } from '../../../../workbench/contrib/chat/brows
109107import { handleTerminalCommandPaste , isTerminalCommandInput } from '../../../../workbench/contrib/chat/browser/chatTerminalCommandPaste.js' ;
110108import { compactCodiconsIn } from '../../../../workbench/contrib/chat/browser/chatIcons.js' ;
111109import { IChatPasteTargetService } from '../../../../workbench/contrib/chat/browser/chat.js' ;
112- import { ChatDynamicVariableModel } from '../../../../workbench/contrib/chat/browser/attachments/chatDynamicVariables .js' ;
110+ import { getGitHubIssueOrPullRequestAttachments } from '../../../../workbench/contrib/chat/browser/widget/input/editor/chatPasteProviders .js' ;
113111import { NewChatInputPasteTarget } from './newChatInputPasteTarget.js' ;
114- import { registerChatInputReferenceDecorationType } from '../../../../workbench/contrib/chat/browser/widget/input/editor/chatInputReferenceDecorations.js' ;
115112import { getChatSessionType } from '../../../../workbench/contrib/chat/common/model/chatUri.js' ;
116113import { ChatSpeechToTextState , DictationSettingId , IChatSpeechToTextService } from '../../../../workbench/contrib/chat/browser/speechToText/chatSpeechToTextService.js' ;
117114import { setupDictationMicGlow } from '../../../../workbench/contrib/chat/browser/speechToText/dictationMicGlow.js' ;
@@ -134,6 +131,7 @@ import { animatePromptTyping, IPromptTypingAnimation } from './promptTypingAnima
134131import { PromptTemplatePlaceholderController } from './promptTemplatePlaceholder.js' ;
135132import { INewSessionComposer , INewSessionPromptOptionsController , NEW_SESSION_PROMPT_TYPING_DURATION_MS , NewSessionPromptOptionsState , NewSessionWorkspacePreselectionSource } from './newSessionComposerService.js' ;
136133import { NewSessionPromptOptionsWidget } from './newSessionPromptOptions.js' ;
134+ import { isInputGitHubContext , toInputGitHubContextMetadata } from '../common/newChatContextIds.js' ;
137135
138136
139137const OPEN_OTEL_SETTINGS_COMMAND = 'github.copilot.chat.otel.openSettings' ;
@@ -213,13 +211,16 @@ KeybindingsRegistry.registerKeybindingRule({
213211interface IDraftState {
214212 inputText : string ;
215213 attachments : readonly IChatRequestVariableEntry [ ] ;
216- contrib ?: Record < string , unknown > ;
217214}
218215
219216export function hasSendableNewChatContent ( query : string , attachments : readonly IChatRequestVariableEntry [ ] , hasAdditionalSendContent = false ) : boolean {
220217 return ! ! query . trim ( ) || attachments . some ( isExplicitFileOrImageVariableEntry ) || hasAdditionalSendContent ;
221218}
222219
220+ function getInputGitHubContextAttachments ( input : string ) : readonly IChatRequestVariableEntry [ ] {
221+ return getGitHubIssueOrPullRequestAttachments ( input , toInputGitHubContextMetadata ( ) ) ;
222+ }
223+
223224class NewChatInputStatusActionViewItem extends MenuEntryActionViewItem {
224225 private readonly hoverContentDisposables = this . _register ( new MutableDisposable < DisposableStore > ( ) ) ;
225226 private _container : HTMLElement | undefined ;
@@ -448,7 +449,6 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
448449 // Input
449450 private _editor ! : CodeEditorWidget ;
450451 private _editorContainer ! : HTMLElement ;
451- private _dynamicVariableModel ! : ChatDynamicVariableModel ;
452452 private _sessionControlsContainer : HTMLElement | undefined ;
453453 private readonly _promptTemplatePlaceholder = this . _register ( new MutableDisposable < PromptTemplatePlaceholderController > ( ) ) ;
454454 private readonly _promptOptionsWidget = this . _register ( new MutableDisposable < NewSessionPromptOptionsWidget > ( ) ) ;
@@ -524,7 +524,6 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
524524 @IModelService private readonly modelService : IModelService ,
525525 @ITextModelService private readonly textModelService : ITextModelService ,
526526 @IChatPasteTargetService private readonly chatPasteTargetService : IChatPasteTargetService ,
527- @ICodeEditorService private readonly codeEditorService : ICodeEditorService ,
528527 @IConfigurationService private readonly configurationService : IConfigurationService ,
529528 @IContextKeyService private readonly contextKeyService : IContextKeyService ,
530529 @ILogService private readonly logService : ILogService ,
@@ -551,7 +550,6 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
551550 @ILanguageModelsService private readonly languageModelsService : ILanguageModelsService ,
552551 ) {
553552 super ( ) ;
554- this . _register ( registerChatInputReferenceDecorationType ( this . codeEditorService ) ) ;
555553 this . _modelSelection = this . _register ( this . instantiationService . createInstance ( SessionModelSelection , this . options . session ) ) ;
556554 this . _canSendRequest = derived ( this , reader => {
557555 if ( this . options . canSubmitWithoutSession ?. read ( reader ) ) {
@@ -896,6 +894,7 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
896894 const editorOptions : IEditorConstructionOptions = {
897895 ...getSimpleEditorOptions ( this . configurationService ) ,
898896 readOnly : false ,
897+ // Match the workbench chat input so the post-paste selector is offered.
899898 pasteAs : EditorOptions . pasteAs . defaultValue ,
900899 ariaLabel : this . _getAriaLabel ( ) ,
901900 placeholder : this . options . placeholder ?? getRandomChatInputPlaceholder ( ) ,
@@ -932,7 +931,6 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
932931 SnippetController2 . ID ,
933932 PlaceholderTextContribution . ID ,
934933 CopyPasteController . ID ,
935- LinkDetector . ID ,
936934 ] ) ,
937935 } ;
938936
@@ -1068,26 +1066,17 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
10681066 AgentHostInputCompletionHandler , this . _editor , this . _contextAttachments ,
10691067 ) ) ;
10701068
1071- const contextAttachments = this . _contextAttachments ;
1072- this . _dynamicVariableModel = this . _register ( this . _scopedInstantiationService . createInstance ( ChatDynamicVariableModel , {
1073- inputEditor : this . _editor ,
1074- get attachments ( ) { return contextAttachments . attachments ; } ,
1075- onDidChangeActiveInputEditor : Event . None ,
1076- onDidChangeAttachments : contextAttachments . onDidChangeContext ,
1077- refreshParsedInput : ( ) => { } ,
1078- } ) ) ;
1079- this . _register ( this . _dynamicVariableModel . onDidChangeReferences ( ( ) => this . _updateDraftState ( ) ) ) ;
10801069 this . _register ( this . chatPasteTargetService . registerTarget ( textModel . uri , new NewChatInputPasteTarget (
10811070 this . _editor ,
10821071 this . _contextAttachments ,
10831072 this . _agentHostInputCompletionHandler ,
1084- this . _dynamicVariableModel ,
10851073 ( ) => this . _getTerminalCommandPrefix ( ) ,
10861074 ( ) => this . options . session . get ( ) ?. resource ,
10871075 textModel . uri ,
10881076 ) ) ) ;
10891077
10901078 this . _register ( this . _editor . onDidChangeModelContent ( ( ) => {
1079+ this . _syncInputGitHubContext ( ) ;
10911080 this . _updateDraftState ( ) ;
10921081 this . _updateSendButtonState ( ) ;
10931082 this . _updateEditorFontFamily ( ) ;
@@ -1480,14 +1469,9 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
14801469 }
14811470
14821471 private _updateDraftState ( ) : void {
1483- const contrib : Record < string , unknown > = { } ;
1484- if ( this . _dynamicVariableModel ?. variables . length ) {
1485- this . _dynamicVariableModel . getInputState ( contrib ) ;
1486- }
14871472 this . _draftState = {
14881473 inputText : this . _editor ?. getModel ( ) ?. getValue ( ) ?? '' ,
14891474 attachments : [ ...this . _contextAttachments . attachments ] ,
1490- ...( Object . keys ( contrib ) . length ? { contrib } : { } ) ,
14911475 } ;
14921476 }
14931477
@@ -1499,13 +1483,32 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
14991483 this . saveState ( ) ;
15001484 }
15011485
1486+ private _syncInputGitHubContext ( ) : void {
1487+ const inputAttachments = getInputGitHubContextAttachments ( this . _editor ?. getValue ( ) ?? '' ) ;
1488+ const inputAttachmentIds = new Set ( inputAttachments . map ( attachment => attachment . id ) ) ;
1489+ const attachments = this . _contextAttachments . attachments . filter ( attachment =>
1490+ ! isInputGitHubContext ( attachment ) || inputAttachmentIds . has ( attachment . id )
1491+ ) ;
1492+ const attachmentIds = new Set ( attachments . map ( attachment => attachment . id ) ) ;
1493+ for ( const attachment of inputAttachments ) {
1494+ if ( ! attachmentIds . has ( attachment . id ) ) {
1495+ attachments . push ( attachment ) ;
1496+ attachmentIds . add ( attachment . id ) ;
1497+ }
1498+ }
1499+ if ( attachments . length !== this . _contextAttachments . attachments . length
1500+ || attachments . some ( ( attachment , index ) => attachment !== this . _contextAttachments . attachments [ index ] ) ) {
1501+ this . _contextAttachments . setAttachments ( attachments ) ;
1502+ }
1503+ }
1504+
15021505 private _toHistoryEntry ( draft : IDraftState ) : IChatModelInputState {
15031506 return {
15041507 ...draft ,
15051508 mode : { id : ChatModeKind . Agent , kind : ChatModeKind . Agent } ,
15061509 selectedModel : undefined ,
15071510 selections : [ ] ,
1508- contrib : draft . contrib ?? { } ,
1511+ contrib : { } ,
15091512 } ;
15101513 }
15111514
@@ -1515,7 +1518,6 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
15151518 if ( entry ) {
15161519 this . _editor ?. getModel ( ) ?. setValue ( inputText ) ;
15171520 this . _contextAttachments . setAttachments ( entry . attachments ) ;
1518- this . _dynamicVariableModel . setInputState ( entry . contrib ) ;
15191521 }
15201522 aria . status ( inputText ) ;
15211523 if ( previous ) {
@@ -1538,11 +1540,10 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
15381540
15391541 private async _send ( background = false ) : Promise < boolean > {
15401542 const rawQuery = this . _editor . getModel ( ) ?. getValue ( ) ?? '' ;
1541- const displayQuery = rawQuery . trim ( ) ;
1543+ const query = rawQuery . trim ( ) ;
15421544 const queryOffset = rawQuery . length - rawQuery . trimStart ( ) . length ;
1543- const query = this . _dynamicVariableModel ?. getPromptText ( displayQuery , queryOffset ) ?? displayQuery ;
15441545 const hasAdditionalSendContent = this . options . hasAdditionalSendContent ?. get ( ) ?? false ;
1545- if ( ! hasSendableNewChatContent ( displayQuery , this . _contextAttachments . attachments , hasAdditionalSendContent ) || this . _sending ) {
1546+ if ( ! hasSendableNewChatContent ( query , this . _contextAttachments . attachments , hasAdditionalSendContent ) || this . _sending ) {
15461547 return false ;
15471548 }
15481549
@@ -1568,7 +1569,7 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
15681569 return true ;
15691570 }
15701571
1571- const attachments = this . _agentHostInputCompletionHandler ?. getAttachmentsForSend ( displayQuery , queryOffset ) ?? [ ...this . _contextAttachments . attachments ] ;
1572+ const attachments = this . _agentHostInputCompletionHandler ?. getAttachmentsForSend ( query , queryOffset ) ?? [ ...this . _contextAttachments . attachments ] ;
15721573 const attachedContext = attachments . length > 0
15731574 ? attachments
15741575 : undefined ;
@@ -1638,7 +1639,7 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation
16381639 if ( draft . attachments ?. length ) {
16391640 this . _contextAttachments . setAttachments ( draft . attachments . map ( IChatRequestVariableEntry . fromExport ) ) ;
16401641 }
1641- this . _dynamicVariableModel . setInputState ( draft . contrib ?? { } ) ;
1642+ this . _syncInputGitHubContext ( ) ;
16421643 }
16431644 this . _updateSendButtonState ( ) ;
16441645 }
0 commit comments