From 9b64d3b8aeba845e38595076949b7515fc48f880 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 11 Feb 2026 10:38:21 -0800 Subject: [PATCH 1/3] Use sequence as default terminal tab title This aligns us with how most terminals use this information. It is a pretty big change though and I expect some users to not be happy with the new behavior. The user can always go back to the old way, but this way is technically more correct and there's really good reason to make the change now since agentic CLIs use the title to signal progress or required user confirmations. Fixes #291275 --- .../workbench/contrib/terminal/common/terminalConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 87c3d392b20a..046f3dcc7121 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -342,7 +342,7 @@ const terminalConfiguration: IStringDictionary = { }, [TerminalSettingId.TerminalTitle]: { 'type': 'string', - 'default': '${process}', + 'default': '${sequence}', 'markdownDescription': terminalTitle }, [TerminalSettingId.TerminalDescription]: { From 70658519dc8b1cc5b312ca0c3b7f232b7aea8140 Mon Sep 17 00:00:00 2001 From: Matt Bierner <12821956+mjbvz@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:17:47 -0800 Subject: [PATCH 2/3] Enable tsgo by default in the workspace Tsgo language tooling should be feature complete at this point. There still may be bugs or more minor gaps, but we want more dogfooding to find these Enabling tsgo to help with this. It's still easy to switch back to tsc if you run into any blockers --- .vscode/settings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index da775f21244f..3e903f646758 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -94,6 +94,7 @@ "**/*.snap": true, }, // --- TypeScript --- + "typescript.experimental.useTsgo": true, "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifier": "relative", "typescript.preferences.quoteStyle": "single", From f103973f700e95b1906802b117d23f5f691c4772 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 11 Feb 2026 15:30:01 -0600 Subject: [PATCH 3/3] add `requiresAnyToolSetRegistered` condition for `tips` (#294680) fix #294675 --- .../browser/ui/codicons/codicon/codicon.ttf | Bin 125648 -> 125696 bytes .../contrib/chat/browser/chatTipService.ts | 17 +++++++- .../chat/test/browser/chatTipService.test.ts | 41 ++++++++++++++++++ .../tools/mockLanguageModelToolsService.ts | 17 ++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf index ff46f210b8ab96e49e12c17db2d6794ed6b5eecd..a3098e1715c529ea8fa52ad57586c686ca2fd629 100644 GIT binary patch delta 559 zcmXAlO=uHQ5Xawa-tK1K?!LF1x0|>LiIPZ)(L_n&D)>n$9*T#Gp2UL%58f<(Ts#<| z;vp4jK)i^hpm>m61fhYX+cviOXq(WBJ@)9ygGdg=le^6vW`_U#X8tgHKjoME^5S*v zcD}iQP<|P~$5!oT8Rw?G<=U%^c@H5toO|@->B5IBK`^*eYn;PhXXayI~1Zai<3_UOm^O}croHMQ02WINT) z-)^ou*FEfA?!D+o`w#m2+jP6Jb8KgCH@Ev`aAHs&y2E$FgZZWW%2FOaJ*$L}9}tH) za?yQMMTi%pu@u;rB&Q$=mc)R>Z>ilS483)nFP zjmt9E1jE4scc`u?aV|IpiAYj}Oc5qxSu>bMuq0uXSzMPwI7CTEHCZq=HGwbzha}yy znHoT(qA^30vB(HGwgCyQ`VMi1t)w8b2nmNtgo#4Z!YuAPt2_aQt;n*%DZyAYVx|-p z!8S1EqOPc>RwtB_x@M}1E^>+u8^o|=#tac-LJ=B&TSgd~rO>SLkEA6Z8gZKN}cef8ebauR*w;i>!*!k8q zx);0Od->kA-rxRQKkOfVT-!yv8+*pyqk%YhGRzF`3_JH%i|eaJcyVhPqexH$4~a-e zNmN4%2vsfOxaAtK|3~06T6P^`F+ZqUDole4j$0r(X9gc0T|B diff --git a/src/vs/workbench/contrib/chat/browser/chatTipService.ts b/src/vs/workbench/contrib/chat/browser/chatTipService.ts index bcc4e30c205e..726d06a3df5a 100644 --- a/src/vs/workbench/contrib/chat/browser/chatTipService.ts +++ b/src/vs/workbench/contrib/chat/browser/chatTipService.ts @@ -105,6 +105,11 @@ export interface ITipDefinition { * The tip won't be shown if the tool it describes has already been used. */ readonly excludeWhenToolsInvoked?: string[]; + /** + * Tool set reference names where at least one must be registered for the tip to be eligible. + * If none of the listed tool sets are registered, the tip is not shown. + */ + readonly requiresAnyToolSetRegistered?: string[]; /** * If set, exclude this tip when prompt files of the specified type exist in the workspace. */ @@ -205,6 +210,7 @@ const TIP_CATALOG: ITipDefinition[] = [ ContextKeyExpr.notEquals('gitOpenRepositoryCount', '0'), ), excludeWhenToolsInvoked: ['github-pull-request_doSearch', 'github-pull-request_issue_fetch', 'github-pull-request_formSearchQuery'], + requiresAnyToolSetRegistered: ['github', 'github-pull-request'], }, { id: 'tip.subagents', @@ -271,7 +277,7 @@ export class TipEligibilityTracker extends Disposable { @ICommandService commandService: ICommandService, @IStorageService private readonly _storageService: IStorageService, @IPromptsService private readonly _promptsService: IPromptsService, - @ILanguageModelToolsService languageModelToolsService: ILanguageModelToolsService, + @ILanguageModelToolsService private readonly _languageModelToolsService: ILanguageModelToolsService, @ILogService private readonly _logService: ILogService, ) { super(); @@ -335,7 +341,7 @@ export class TipEligibilityTracker extends Disposable { // --- Set up tool listener (auto-disposes when all seen) ----------------- if (this._pendingTools.size > 0) { - this._toolListener.value = languageModelToolsService.onDidInvokeTool(e => { + this._toolListener.value = this._languageModelToolsService.onDidInvokeTool(e => { if (this._pendingTools.has(e.toolId)) { this._invokedTools.add(e.toolId); this._persistSet(TipEligibilityTracker._TOOLS_STORAGE_KEY, this._invokedTools); @@ -428,6 +434,13 @@ export class TipEligibilityTracker extends Disposable { this._logService.debug('#ChatTips: tip excluded because prompt files exist', tip.id); return true; } + if (tip.requiresAnyToolSetRegistered) { + const hasAny = tip.requiresAnyToolSetRegistered.some(name => this._languageModelToolsService.getToolSetByName(name)); + if (!hasAny) { + this._logService.debug('#ChatTips: tip excluded because no required tool sets are registered', tip.id); + return true; + } + } return false; } diff --git a/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts b/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts index 442293c19986..a1f7741a4b70 100644 --- a/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts +++ b/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts @@ -613,6 +613,47 @@ suite('ChatTipService', () => { assert.strictEqual(tracker.isExcluded(tip), false, 'Should not be excluded when no skill files exist'); }); + test('excludes tip when requiresAnyToolSetRegistered tool sets are not registered', () => { + const tip: ITipDefinition = { + id: 'tip.githubRepo', + message: 'test', + requiresAnyToolSetRegistered: ['github', 'github-pull-request'], + }; + + const tracker = testDisposables.add(new TipEligibilityTracker( + [tip], + { onDidExecuteCommand: Event.None, onWillExecuteCommand: Event.None } as Partial as ICommandService, + storageService, + createMockPromptsService() as IPromptsService, + createMockToolsService(), + new NullLogService(), + )); + + assert.strictEqual(tracker.isExcluded(tip), true, 'Should be excluded when no required tool sets are registered'); + }); + + test('does not exclude tip when at least one requiresAnyToolSetRegistered tool set is registered', () => { + const mockToolsService = createMockToolsService(); + mockToolsService.addRegisteredToolSetName('github'); + + const tip: ITipDefinition = { + id: 'tip.githubRepo', + message: 'test', + requiresAnyToolSetRegistered: ['github', 'github-pull-request'], + }; + + const tracker = testDisposables.add(new TipEligibilityTracker( + [tip], + { onDidExecuteCommand: Event.None, onWillExecuteCommand: Event.None } as Partial as ICommandService, + storageService, + createMockPromptsService() as IPromptsService, + mockToolsService, + new NullLogService(), + )); + + assert.strictEqual(tracker.isExcluded(tip), false, 'Should not be excluded when at least one required tool set is registered'); + }); + test('re-checks agent file exclusion when onDidChangeCustomAgents fires', async () => { const agentChangeEmitter = testDisposables.add(new Emitter()); let agentFiles: IPromptPath[] = []; diff --git a/src/vs/workbench/contrib/chat/test/common/tools/mockLanguageModelToolsService.ts b/src/vs/workbench/contrib/chat/test/common/tools/mockLanguageModelToolsService.ts index ea248c48bd24..665bd2a4618b 100644 --- a/src/vs/workbench/contrib/chat/test/common/tools/mockLanguageModelToolsService.ts +++ b/src/vs/workbench/contrib/chat/test/common/tools/mockLanguageModelToolsService.ts @@ -27,6 +27,9 @@ export class MockLanguageModelToolsService extends Disposable implements ILangua private readonly _onDidInvokeTool = this._register(new Emitter()); + private readonly _registeredToolIds = new Set(); + private readonly _registeredToolSetNames = new Set(); + constructor() { super(); } @@ -88,7 +91,14 @@ export class MockLanguageModelToolsService extends Disposable implements ILangua return []; } + addRegisteredToolId(id: string): void { + this._registeredToolIds.add(id); + } + getTool(id: string): IToolData | undefined { + if (this._registeredToolIds.has(id)) { + return { id, source: ToolDataSource.Internal, displayName: id, modelDescription: id }; + } return undefined; } @@ -125,7 +135,14 @@ export class MockLanguageModelToolsService extends Disposable implements ILangua return []; } + addRegisteredToolSetName(name: string): void { + this._registeredToolSetNames.add(name); + } + getToolSetByName(name: string): IToolSet | undefined { + if (this._registeredToolSetNames.has(name)) { + return { id: name, referenceName: name, icon: ThemeIcon.fromId(Codicon.tools.id), source: ToolDataSource.Internal, getTools: () => [] }; + } return undefined; }