Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/ai-ide/src/browser/architect-prompt-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
GET_WORKSPACE_FILE_LIST_FUNCTION_ID, FILE_CONTENT_FUNCTION_ID, SEARCH_IN_WORKSPACE_FUNCTION_ID, FIND_FILES_BY_PATTERN_FUNCTION_ID
} from '../common/workspace-functions';
import { CONTEXT_FILES_VARIABLE_ID, TASK_CONTEXT_SUMMARY_VARIABLE_ID } from '../common/context-variables';
import { OPEN_EDITORS_HINT_FRAGMENT_ID } from '../common/open-editors-hint-fragment-id';
import {
CREATE_TASK_CONTEXT_FUNCTION_ID,
GET_TASK_CONTEXT_FUNCTION_ID,
Expand Down Expand Up @@ -194,6 +195,8 @@ When a diagram clarifies an architectural concept or how something is implemente

{{prompt:project-info}}

{{prompt:${OPEN_EDITORS_HINT_FRAGMENT_ID}}}

{{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}
`
},
Expand Down Expand Up @@ -231,6 +234,8 @@ Always look at the relevant files to understand your task using the function ~{$
{{${CONTEXT_FILES_VARIABLE_ID}}}

{{prompt:project-info}}

{{prompt:${OPEN_EDITORS_HINT_FRAGMENT_ID}}}
`
},
{
Expand Down Expand Up @@ -464,6 +469,8 @@ When a diagram clarifies an architectural concept or how something is implemente

{{prompt:project-info}}

{{prompt:${OPEN_EDITORS_HINT_FRAGMENT_ID}}}

{{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}
`
}]
Expand Down
4 changes: 4 additions & 0 deletions packages/ai-ide/src/browser/frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ import { AddressGhReviewCommandContribution } from './address-pr-review-command-
import { AppTesterCapabilityContribution } from './apptester-capability-contribution';
import { GitHubCapabilityContribution } from './github-capability-contribution';
import { ShellExecutionCapabilityContribution } from './shell-execution-capability-contribution';
import { OpenEditorsHintContribution } from './open-editors-prompt-fragment';
import { OpenEditorsContextContribution } from './open-editors-context-contribution';
import { AgentModeConfirmationService, AgentModeConfirmationServiceImpl } from './agent-mode-confirmation-service';
import { ExploreAgent } from './explore-agent';
import { CodeReviewerAgent } from './code-reviewer-agent';
Expand Down Expand Up @@ -347,6 +349,8 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
bind(FrontendApplicationContribution).to(AppTesterCapabilityContribution);
bind(FrontendApplicationContribution).to(GitHubCapabilityContribution);
bind(FrontendApplicationContribution).to(ShellExecutionCapabilityContribution);
bind(FrontendApplicationContribution).to(OpenEditorsHintContribution);
bind(FrontendApplicationContribution).to(OpenEditorsContextContribution);

bind(FrontendApplicationContribution).to(CodeReviewCapabilityContribution);
bind(FrontendApplicationContribution).to(PRReviewCapabilityContribution);
Expand Down
96 changes: 96 additions & 0 deletions packages/ai-ide/src/browser/open-editors-context-contribution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// *****************************************************************************
// Copyright (C) 2026 EclipseSource GmbH and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { PreferenceService } from '@theia/core';
import { inject, injectable } from '@theia/core/shared/inversify';
import { PREFERENCE_NAME_AUTO_ADD_OPEN_EDITORS } from '../common/ai-ide-preferences';
import URI from '@theia/core/lib/common/uri';
import { FILE_VARIABLE } from '@theia/ai-core/lib/browser/file-variable-contribution';
import { ChatContextManager, ChatService, isSessionCreatedEvent } from '@theia/ai-chat/lib/common';
import { EditorManager } from '@theia/editor/lib/browser';
import { WorkspaceService } from '@theia/workspace/lib/browser';

/**
* Automatically populates the active chat session's context with open editor files.
*
* When a new chat session is created, all currently open workspace editors are added
* as file context variables. When a new editor is opened while an active session exists,
* that file is added to the session's context as well. Files outside the workspace are
* ignored, and duplicates are prevented by the existing deduplication in {@link ChatContextManager.addVariables}.
*
* The added files appear as removable context pills in the chat input UI, allowing
* users to discard irrelevant files before sending a message.
*/
@injectable()
export class OpenEditorsContextContribution implements FrontendApplicationContribution {
@inject(ChatService)
protected readonly chatService: ChatService;

@inject(EditorManager)
protected readonly editorManager: EditorManager;

@inject(WorkspaceService)
protected readonly workspaceService: WorkspaceService;

@inject(PreferenceService)
protected readonly preferenceService: PreferenceService;

protected get isEnabled(): boolean {
return this.preferenceService.get<boolean>(PREFERENCE_NAME_AUTO_ADD_OPEN_EDITORS, true);
}

onStart(): void {
this.chatService.onSessionEvent(event => {
if (isSessionCreatedEvent(event)) {
if (!this.isEnabled) {
return;
}
const activeSession = this.chatService.getActiveSession();
if (activeSession && activeSession.id === event.sessionId) {
for (const editor of this.editorManager.all) {
const uri = editor.getResourceUri();
if (uri) {
this.addFileToContext(uri, activeSession.model.context);
}
}
}
}
});

this.editorManager.onCreated(widget => {
if (!this.isEnabled) {
return;
}
const uri = widget.getResourceUri();
if (uri) {
const activeSession = this.chatService.getActiveSession();
if (activeSession) {
this.addFileToContext(uri, activeSession.model.context);
}
}
});
}

protected addFileToContext(uri: URI, context: ChatContextManager): void {
const rootUri = this.workspaceService.getWorkspaceRootUri(uri);
if (!rootUri) {
return;
}
const relativePath = this.workspaceService.getRootPrefixedPath(uri);
context.addVariables({ variable: FILE_VARIABLE, arg: relativePath });
}
}
40 changes: 40 additions & 0 deletions packages/ai-ide/src/browser/open-editors-prompt-fragment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// *****************************************************************************
// Copyright (C) 2026 EclipseSource GmbH.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { inject, injectable } from '@theia/core/shared/inversify';
import { PromptService } from '@theia/ai-core/lib/common';
import { OPEN_EDITORS_HINT_FRAGMENT_ID } from '../common/open-editors-hint-fragment-id';

export { OPEN_EDITORS_HINT_FRAGMENT_ID };

@injectable()
export class OpenEditorsHintContribution implements FrontendApplicationContribution {

@inject(PromptService)
protected readonly promptService: PromptService;

onStart(): void {
this.promptService.addBuiltInPromptFragment({
id: OPEN_EDITORS_HINT_FRAGMENT_ID,
template: `## Open Editors
The following files are currently open in the user's editor. This is provided as contextual information only \
— these files may or may not be relevant to the current request. Do not assume they are related unless the user explicitly refers to them.

{{openEditors}}`
});
}
}
10 changes: 10 additions & 0 deletions packages/ai-ide/src/common/ai-ide-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { nls, PreferenceSchema, PreferenceScope } from '@theia/core';
export const PREFERENCE_NAME_ENABLE_AI = 'ai-features.AiEnable.enableAI';
export const PREFERENCE_NAME_ORCHESTRATOR_EXCLUSION_LIST = 'ai-features.orchestrator.excludedAgents';
export const PREFERENCE_NAME_AGENT_MODE_ENABLED = 'ai-features.agentMode.enabled';
export const PREFERENCE_NAME_AUTO_ADD_OPEN_EDITORS = 'ai-features.chat.autoAddOpenEditors';
export const aiIdePreferenceSchema: PreferenceSchema = {
properties: {
[PREFERENCE_NAME_ENABLE_AI]: {
Expand Down Expand Up @@ -57,6 +58,15 @@ export const aiIdePreferenceSchema: PreferenceSchema = {
type: 'boolean',
default: false,
scope: PreferenceScope.User
},
[PREFERENCE_NAME_AUTO_ADD_OPEN_EDITORS]: {
title: AI_CORE_PREFERENCES_TITLE,
description: nls.localize('theia/ai/ide/autoAddOpenEditors/description',
'Automatically add open editor files to the chat context. '
+ 'When enabled, all open editors are added to new chat sessions, '
+ 'and newly opened files are added to the active session.'),
type: 'boolean',
default: true,
}
}
};
7 changes: 7 additions & 0 deletions packages/ai-ide/src/common/coder-replace-prompt-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
} from './file-changeset-function-ids';
import { GET_TASK_CONTEXT_FUNCTION_ID } from './task-context-function-ids';
import { ArchitectAgentId, ExploreAgentId } from './agent-ids';
import { OPEN_EDITORS_HINT_FRAGMENT_ID } from './open-editors-hint-fragment-id';

export const CODER_SYSTEM_PROMPT_ID = 'coder-system';

Expand Down Expand Up @@ -259,6 +260,8 @@ Always retrieve relevant files using ~{${FILE_CONTENT_FUNCTION_ID}} to understan
## Project Info
{{prompt:project-info}}

{{prompt:${OPEN_EDITORS_HINT_FRAGMENT_ID}}}

{{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}

# Final Instruction
Expand Down Expand Up @@ -549,6 +552,8 @@ Always retrieve relevant files using ~{${FILE_CONTENT_FUNCTION_ID}} to understan
## Project Info
{{prompt:project-info}}

{{prompt:${OPEN_EDITORS_HINT_FRAGMENT_ID}}}

{{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}

# Final Instruction
Expand Down Expand Up @@ -639,6 +644,8 @@ You have previously proposed changes for the following files. Some suggestions m

{{prompt:project-info}}

{{prompt:${OPEN_EDITORS_HINT_FRAGMENT_ID}}}

{{${TASK_CONTEXT_SUMMARY_VARIABLE_ID}}}

## Final Instruction
Expand Down
17 changes: 17 additions & 0 deletions packages/ai-ide/src/common/open-editors-hint-fragment-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// *****************************************************************************
// Copyright (C) 2026 EclipseSource GmbH.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************

export const OPEN_EDITORS_HINT_FRAGMENT_ID = 'open-editors-hint';
3 changes: 3 additions & 0 deletions packages/ai-ide/src/common/universal-prompt-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import { BasePromptFragment } from '@theia/ai-core/lib/common';
import { CHAT_CONTEXT_DETAILS_VARIABLE_ID } from '@theia/ai-chat';
import { OPEN_EDITORS_HINT_FRAGMENT_ID } from './open-editors-hint-fragment-id';

export const universalTemplate: BasePromptFragment = {
id: 'universal-system-default',
Expand All @@ -23,6 +24,8 @@ You are an assistant integrated into {{productName}}, designed to assist softwar
## Current Context
Some files and other pieces of data may have been added by the user to the context of the chat. If any have, the details can be found below.
{{${CHAT_CONTEXT_DETAILS_VARIABLE_ID}}}

{{prompt:${OPEN_EDITORS_HINT_FRAGMENT_ID}}}
`
};

Expand Down
Loading