Skip to content

Commit cb9728b

Browse files
SD comments
1 parent 486242b commit cb9728b

File tree

7 files changed

+63
-21
lines changed

7 files changed

+63
-21
lines changed

packages/ai-chat-ui/src/browser/ai-chat-ui-contribution.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@
1717
import { inject, injectable } from '@theia/core/shared/inversify';
1818
import { CommandRegistry, Emitter, isOSX, nls, QuickInputButton, QuickInputService, QuickPickItem } from '@theia/core';
1919
import { Widget } from '@theia/core/lib/browser';
20-
import { AI_CHAT_NEW_CHAT_WINDOW_COMMAND, AI_CHAT_NEW_WITH_TASK_CONTEXT, AI_CHAT_SHOW_CHATS_COMMAND, AI_CHAT_SUMMARIZE_CURRENT_SESSION, ChatCommands } from './chat-view-commands';
20+
import {
21+
AI_CHAT_NEW_CHAT_WINDOW_COMMAND,
22+
AI_CHAT_NEW_WITH_TASK_CONTEXT,
23+
AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION,
24+
AI_CHAT_SHOW_CHATS_COMMAND,
25+
AI_CHAT_SUMMARIZE_CURRENT_SESSION,
26+
ChatCommands
27+
} from './chat-view-commands';
2128
import { ChatAgentLocation, ChatService } from '@theia/ai-chat';
2229
import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
2330
import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
@@ -45,7 +52,6 @@ export class AIChatContribution extends AbstractViewContribution<ChatViewWidget>
4552
@inject(TaskContextService)
4653
protected readonly taskContextService: TaskContextService;
4754

48-
4955
protected static readonly RENAME_CHAT_BUTTON: QuickInputButton = {
5056
iconClass: 'codicon-edit',
5157
tooltip: nls.localize('theia/ai/chat-ui/renameChat', 'Rename Chat'),
@@ -109,11 +115,29 @@ export class AIChatContribution extends AbstractViewContribution<ChatViewWidget>
109115
isVisible: widget => {
110116
if (widget && !this.withWidget(widget)) { return false; }
111117
const activeSession = this.chatService.getActiveSession();
112-
return !!activeSession?.model.getRequests().length
113-
&& activeSession?.model.location === ChatAgentLocation.Panel
118+
return activeSession?.model.location === ChatAgentLocation.Panel
119+
&& !this.taskContextService.hasSummary(activeSession);
120+
},
121+
isEnabled: widget => {
122+
if (widget && !this.withWidget(widget)) { return false; }
123+
const activeSession = this.chatService.getActiveSession();
124+
return activeSession?.model.location === ChatAgentLocation.Panel
125+
&& !activeSession.model.isEmpty()
114126
&& !this.taskContextService.hasSummary(activeSession);
115127
}
116128
});
129+
registry.registerCommand(AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION, {
130+
execute: async () => {
131+
const id = await this.summarizeActiveSession();
132+
if (!id) { return; }
133+
await this.taskContextService.open(id);
134+
},
135+
isVisible: widget => {
136+
if (widget && !this.withWidget(widget)) { return false; }
137+
const activeSession = this.chatService.getActiveSession();
138+
return !!activeSession && this.taskContextService.hasSummary(activeSession);
139+
}
140+
});
117141
registry.registerCommand(AI_CHAT_SHOW_CHATS_COMMAND, {
118142
execute: () => this.selectChat(),
119143
isEnabled: widget => this.withWidget(widget) && this.chatService.getSessions().length > 1,
@@ -172,6 +196,11 @@ export class AIChatContribution extends AbstractViewContribution<ChatViewWidget>
172196
command: AI_CHAT_SUMMARIZE_CURRENT_SESSION.id,
173197
onDidChange: sessionSummarizibilityChangedEmitter.event
174198
});
199+
registry.registerItem({
200+
id: 'chat-view.' + AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION.id,
201+
command: AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION.id,
202+
onDidChange: sessionSummarizibilityChangedEmitter.event
203+
});
175204
}
176205

177206
protected async selectChat(sessionId?: string): Promise<void> {

packages/ai-chat-ui/src/browser/chat-input-agent-suggestions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ interface ChatInputAgestSuggestionProps {
5757

5858
const ChatInputAgentSuggestion: React.FC<ChatInputAgestSuggestionProps> = ({ suggestion, opener, handler }) => {
5959
const ref = useMarkdownRendering(getContent(suggestion), opener, true, handler);
60-
return <div className="chat-agent-suggestion" style={ChatSuggestionCallback.containsCallbackLink(suggestion) ? undefined : { cursor: 'pointer' }} ref={ref} />;
60+
return <div className="chat-agent-suggestion" style={(!handler || ChatSuggestionCallback.containsCallbackLink(suggestion)) ? undefined : { cursor: 'pointer' }} ref={ref} />;
6161
};
6262

6363
class ChatSuggestionClickHandler implements DeclaredEventsEventListenerObject {

packages/ai-chat-ui/src/browser/chat-input-widget.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//
1414
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
1515
// *****************************************************************************
16-
import { ChangeSet, ChatAgent, ChatChangeEvent, ChatModel, ChatRequestModel, ChatSuggestion } from '@theia/ai-chat';
16+
import { ChangeSet, ChatAgent, ChatChangeEvent, ChatModel, ChatRequestModel, ChatService, ChatSuggestion } from '@theia/ai-chat';
1717
import { Disposable, DisposableCollection, InMemoryResources, URI, nls } from '@theia/core';
1818
import { ContextMenuRenderer, LabelProvider, Message, OpenerService, ReactWidget } from '@theia/core/lib/browser';
1919
import { Deferred } from '@theia/core/lib/common/promise-util';
@@ -79,6 +79,9 @@ export class AIChatInputWidget extends ReactWidget {
7979
@inject(OpenerService)
8080
protected readonly openerService: OpenerService;
8181

82+
@inject(ChatService)
83+
protected readonly chatService: ChatService;
84+
8285
protected editorRef: MonacoEditor | undefined = undefined;
8386
protected readonly editorReady = new Deferred<void>();
8487

@@ -104,10 +107,6 @@ export class AIChatInputWidget extends ReactWidget {
104107
set onDeleteChangeSetElement(deleteChangeSetElement: DeleteChangeSetElement) {
105108
this._onDeleteChangeSetElement = deleteChangeSetElement;
106109
}
107-
private _onOpenContextELement: OpenContextElement;
108-
set onOpenContextElement(opener: OpenContextElement) {
109-
this._onOpenContextELement = opener;
110-
}
111110

112111
private _initialValue?: string;
113112
set initialValue(value: string | undefined) {
@@ -166,7 +165,7 @@ export class AIChatInputWidget extends ReactWidget {
166165
onAddContextElement={this.addContextElement.bind(this)}
167166
onDeleteContextElement={this.deleteContextElement.bind(this)}
168167
context={this.getContext()}
169-
onOpenContextElement={this._onOpenContextELement.bind(this)}
168+
onOpenContextElement={this.openContextElement.bind(this)}
170169
chatModel={this._chatModel}
171170
pinnedAgent={this._pinnedAgent}
172171
editorProvider={this.editorProvider}
@@ -225,6 +224,12 @@ export class AIChatInputWidget extends ReactWidget {
225224
});
226225
}
227226

227+
protected async openContextElement(request: AIVariableResolutionRequest): Promise<void> {
228+
const session = this.chatService.getSessions().find(candidate => candidate.model.id === this._chatModel.id);
229+
const context = { session };
230+
await this.variableService.open(request, context);
231+
}
232+
228233
public setEnabled(enabled: boolean): void {
229234
this.isEnabled = enabled;
230235
this.update();

packages/ai-chat-ui/src/browser/chat-view-commands.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ export const AI_CHAT_NEW_WITH_TASK_CONTEXT: Command = {
5151

5252
export const AI_CHAT_SUMMARIZE_CURRENT_SESSION: Command = {
5353
id: 'ai-chat-summary-current-session',
54-
iconClass: codicon('note')
54+
iconClass: codicon('go-to-editing-session'),
55+
label: 'Summarize Current Session'
56+
};
57+
58+
export const AI_CHAT_OPEN_SUMMARY_FOR_CURRENT_SESSION: Command = {
59+
id: 'ai-chat-open-current-session-summary',
60+
iconClass: codicon('note'),
61+
label: 'Open Current Session Summary'
5562
};
5663

5764
export const AI_CHAT_SHOW_CHATS_COMMAND: Command = {

packages/ai-chat-ui/src/browser/chat-view-widget.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
106106
this.inputWidget.pinnedAgent = this.chatSession.pinnedAgent;
107107
this.inputWidget.onDeleteChangeSet = this.onDeleteChangeSet.bind(this);
108108
this.inputWidget.onDeleteChangeSetElement = this.onDeleteChangeSetElement.bind(this);
109-
this.inputWidget.onOpenContextElement = this.onOpenContextElement.bind(this);
110109
this.treeWidget.trackChatModel(this.chatSession.model);
111110

112111
this.initListeners();
@@ -215,11 +214,6 @@ export class ChatViewWidget extends BaseWidget implements ExtractableWidget, Sta
215214
this.chatService.deleteChangeSetElement(sessionId, index);
216215
}
217216

218-
protected async onOpenContextElement(request: AIVariableResolutionRequest): Promise<void> {
219-
const context = { session: this.chatSession };
220-
await this.variableService.open(request, context);
221-
}
222-
223217
lock(): void {
224218
this.state = { ...deepClone(this.state), locked: true };
225219
}

packages/ai-chat/src/browser/task-context-service.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { MaybePromise, ProgressService, URI, generateUuid, Event } from '@theia/
1919
import { ChatAgent, ChatAgentLocation, ChatService, ChatSession, MutableChatModel, MutableChatRequestModel, ParsedChatRequestTextPart } from '../common';
2020
import { ChatSessionSummaryAgent } from '../common/chat-session-summary-agent';
2121
import { Deferred } from '@theia/core/lib/common/promise-util';
22-
import { PromptService } from '@theia/ai-core';
22+
import { AgentService, PromptService } from '@theia/ai-core';
2323
import { CHAT_SESSION_SUMMARY_PROMPT } from '../common/chat-session-summary-agent-prompt';
2424

2525
export interface SummaryMetadata {
@@ -49,7 +49,7 @@ export class TaskContextService {
4949
protected pendingSummaries = new Map<string, Promise<Summary>>();
5050

5151
@inject(ChatService) protected readonly chatService: ChatService;
52-
@inject(ChatSessionSummaryAgent) protected readonly summaryAgent: ChatSessionSummaryAgent;
52+
@inject(AgentService) protected readonly agentService: AgentService;
5353
@inject(PromptService) protected readonly promptService: PromptService;
5454
@inject(TaskContextStorageService) protected readonly storageService: TaskContextStorageService;
5555
@inject(ProgressService) protected readonly progressService: ProgressService;
@@ -104,7 +104,13 @@ export class TaskContextService {
104104
}
105105
}
106106

107-
protected async getLlmSummary(session: ChatSession, promptId: string = CHAT_SESSION_SUMMARY_PROMPT.id, agent: ChatAgent = this.summaryAgent): Promise<string> {
107+
protected async getLlmSummary(session: ChatSession, promptId: string = CHAT_SESSION_SUMMARY_PROMPT.id, agent?: ChatAgent): Promise<string> {
108+
agent = agent || this.agentService.getAgents().find<ChatAgent>((candidate): candidate is ChatAgent =>
109+
'invoke' in candidate
110+
&& typeof candidate.invoke === 'function'
111+
&& candidate.id === ChatSessionSummaryAgent.ID
112+
);
113+
if (!agent) { throw new Error('Unable to identify agent for summary.'); }
108114
const model = new MutableChatModel(ChatAgentLocation.Panel);
109115
const prompt = await this.promptService.getPrompt(promptId || CHAT_SESSION_SUMMARY_PROMPT.id, undefined, { model: session.model });
110116
if (!prompt) { return ''; }

packages/ai-chat/src/common/chat-session-summary-agent.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ export class ChatSessionSummaryAgent extends AbstractStreamParsingChatAgent impl
3838
override agentSpecificVariables = [];
3939
override functions = [];
4040
override locations = [];
41+
override tags = [];
4142
}

0 commit comments

Comments
 (0)