Skip to content

Commit a14ff27

Browse files
ensorrowRicbet
andauthored
refactor: refactor applyService to support apply recover (#4412)
* feat: add chat history module styles with less (#4404) * fix: apply filename too long * refactor: refactor applyService to support apply recover * feat: supoort show codeblock diffResult * fix: build error * feat: support stream apply * fix: save session when request updates * fix: stream render & save session * feat: support accept/reject all * fix: hide diff manager when block resolved * fix: status label * fix: empty * chore: renderRemovedWidgetImmediately false for stream * fix: button z-index * fix: lastMessageId may be empty, update to show manager --------- Co-authored-by: John <qingyi.xjh@antgroup.com>
1 parent f7916df commit a14ff27

21 files changed

Lines changed: 620 additions & 366 deletions

File tree

packages/ai-native/src/browser/ai-core.contribution.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ import {
5959
} from '@opensumi/ide-core-common';
6060
import { DESIGN_MENU_BAR_RIGHT } from '@opensumi/ide-design';
6161
import { IEditor, WorkbenchEditorService } from '@opensumi/ide-editor';
62-
import { BrowserEditorContribution, IEditorFeatureRegistry } from '@opensumi/ide-editor/lib/browser';
62+
import {
63+
BrowserEditorContribution,
64+
EditorComponentRegistry,
65+
IEditorFeatureRegistry,
66+
} from '@opensumi/ide-editor/lib/browser';
6367
import { WorkbenchEditorServiceImpl } from '@opensumi/ide-editor/lib/browser/workbench-editor.service';
6468
import { IMainLayoutService } from '@opensumi/ide-main-layout';
6569
import { ISettingRegistry, SettingContribution } from '@opensumi/ide-preferences';
@@ -100,6 +104,7 @@ import {
100104
AIRightTabRenderer,
101105
} from './layout/tabbar.view';
102106
import { AIChatLogoAvatar } from './layout/view/avatar/avatar.view';
107+
import { BaseApplyService } from './mcp/base-apply.service';
103108
import {
104109
AINativeCoreContribution,
105110
IChatFeatureRegistry,
@@ -116,13 +121,16 @@ import {
116121
import { InlineChatEditorController } from './widget/inline-chat/inline-chat-editor.controller';
117122
import { InlineChatFeatureRegistry } from './widget/inline-chat/inline-chat.feature.registry';
118123
import { InlineChatService } from './widget/inline-chat/inline-chat.service';
124+
import { InlineDiffManager } from './widget/inline-diff/inline-diff-manager';
119125
import { InlineDiffController } from './widget/inline-diff/inline-diff.controller';
120126
import { InlineHintController } from './widget/inline-hint/inline-hint.controller';
121127
import { InlineInputController } from './widget/inline-input/inline-input.controller';
122128
import { InlineInputService } from './widget/inline-input/inline-input.service';
123129
import { InlineStreamDiffService } from './widget/inline-stream-diff/inline-stream-diff.service';
124130
import { SumiLightBulbWidget } from './widget/light-bulb';
125131

132+
export const INLINE_DIFF_MANAGER_WIDGET_ID = 'inline-diff-manager-widget';
133+
126134
@Domain(
127135
ClientAppContribution,
128136
BrowserEditorContribution,
@@ -237,6 +245,9 @@ export class AINativeBrowserContribution
237245
@Autowired(IChatInternalService)
238246
private readonly chatInternalService: ChatInternalService;
239247

248+
@Autowired(BaseApplyService)
249+
private readonly applyService: BaseApplyService;
250+
240251
constructor() {
241252
this.registerFeature();
242253
}
@@ -524,6 +535,19 @@ export class AINativeBrowserContribution
524535
});
525536
}
526537

538+
registerEditorComponent(registry: EditorComponentRegistry): void {
539+
registry.registerEditorSideWidget({
540+
id: INLINE_DIFF_MANAGER_WIDGET_ID,
541+
component: InlineDiffManager,
542+
displaysOnResource: (resource) => {
543+
if (this.applyService.getUriPendingCodeBlock(resource.uri)) {
544+
return true;
545+
}
546+
return false;
547+
},
548+
});
549+
}
550+
527551
registerCommands(commands: CommandRegistry): void {
528552
commands.registerCommand(AI_INLINE_CHAT_VISIBLE, {
529553
execute: (value: boolean) => {

packages/ai-native/src/browser/chat/chat-manager.service.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
IStorage,
1010
STORAGE_NAMESPACE,
1111
StorageProvider,
12+
debounce,
1213
} from '@opensumi/ide-core-common';
1314
import { ChatMessageRole, IChatMessage, IHistoryChatMessage } from '@opensumi/ide-core-common/lib/types/ai-native';
1415

@@ -89,6 +90,7 @@ export class ChatManagerService extends Disposable {
8990
const savedSessions = this.fromJSON(sessionsModelData);
9091
savedSessions.forEach((session) => {
9192
this.#sessionModels.set(session.sessionId, session);
93+
this.listenSession(session);
9294
});
9395
await this.storageInitEmitter.fireAndAwait();
9496
}
@@ -100,6 +102,7 @@ export class ChatManagerService extends Disposable {
100102
startSession() {
101103
const model = new ChatModel();
102104
this.#sessionModels.set(model.sessionId, model);
105+
this.listenSession(model);
103106
return model;
104107
}
105108

@@ -196,6 +199,15 @@ export class ChatManagerService extends Disposable {
196199
}
197200
}
198201

202+
protected listenSession(session: ChatModel) {
203+
this.addDispose(
204+
session.history.onMessageAdditionalChange(() => {
205+
this.saveSessions();
206+
}),
207+
);
208+
}
209+
210+
@debounce(1000)
199211
protected saveSessions() {
200212
this._chatStorage.set('sessionModels', this.getSessions());
201213
}

packages/ai-native/src/browser/chat/chat.internal.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ export class ChatInternalService extends Disposable {
9494
return this.chatManagerService.getSessions();
9595
}
9696

97+
getSession(sessionId: string) {
98+
return this.chatManagerService.getSession(sessionId);
99+
}
100+
97101
activateSession(sessionId: string) {
98102
const targetSession = this.chatManagerService.getSession(sessionId);
99103
if (!targetSession) {

packages/ai-native/src/browser/components/ChatHistory.tsx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import cls from 'classnames';
22
import React, { FC, memo, useCallback, useEffect, useRef, useState } from 'react';
33

44
import { Icon, Input, Loading, Popover, PopoverPosition, PopoverTriggerType, getIcon } from '@opensumi/ide-components';
5-
import './chat-history.css';
65
import { localize } from '@opensumi/ide-core-browser';
76
import { EnhanceIcon } from '@opensumi/ide-core-browser/lib/components/ai-native';
87

8+
import styles from './chat-history.module.less';
9+
910
export interface IChatHistoryItem {
1011
id: string;
1112
title: string;
@@ -162,22 +163,25 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
162163
(item: IChatHistoryItem) => (
163164
<div
164165
key={item.id}
165-
className={cls('dm-chat-history-item', item.id === currentId ? 'dm-chat-history-item-selected' : '')}
166+
className={cls(
167+
styles['dm-chat-history-item'],
168+
item.id === currentId ? styles['dm-chat-history-item-selected'] : '',
169+
)}
166170
onClick={() => handleHistoryItemSelect(item)}
167171
>
168-
<div className='dm-chat-history-item-content'>
172+
<div className={styles['dm-chat-history-item-content']}>
169173
{item.loading ? (
170174
<Loading />
171175
) : (
172176
<Icon icon='message' style={{ width: '16px', height: '16px', marginRight: 4 }} />
173177
)}
174178
{!historyTitleEditable?.[item.id] ? (
175-
<span id={`dm-chat-history-item-title-${item.id}`} className='dm-chat-history-item-title'>
179+
<span id={`dm-chat-history-item-title-${item.id}`} className={styles['dm-chat-history-item-title']}>
176180
{item.title}
177181
</span>
178182
) : (
179183
<Input
180-
className='dm-chat-history-item-title'
184+
className={styles['dm-chat-history-item-title']}
181185
defaultValue={item.title}
182186
ref={inputRef}
183187
onPressEnter={(e: any) => {
@@ -187,7 +191,7 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
187191
/>
188192
)}
189193
</div>
190-
<div className='dm-chat-history-item-actions'>
194+
<div className={styles['dm-chat-history-item-actions']}>
191195
{/* <EditOutlined
192196
title={localize('aiNative.operate.chatHistory.edit')}
193197
style={{ marginRight: 8 }}
@@ -198,7 +202,7 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
198202
}}
199203
/> */}
200204
<EnhanceIcon
201-
className={cls('dm-chat-history-item-actions-delete', getIcon('delete'))}
205+
className={cls(styles['dm-chat-history-item-actions-delete'], getIcon('delete'))}
202206
onClick={(e) => {
203207
e.preventDefault();
204208
e.stopPropagation();
@@ -237,10 +241,10 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
237241
value={searchValue}
238242
onChange={handleSearchChange}
239243
/>
240-
<div className='dm-chat-history-list'>
244+
<div className={styles['dm-chat-history-list']}>
241245
{groupedHistoryList.map((group) => (
242246
<div key={group.key} style={{ padding: '4px' }}>
243-
<div className='dm-chat-history-time'>{group.key}</div>
247+
<div className={styles['dm-chat-history-time']}>{group.key}</div>
244248
{group.items.map(renderHistoryItem)}
245249
</div>
246250
))}
@@ -253,11 +257,11 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
253257
const getPopupContainer = useCallback((triggerNode: HTMLElement) => triggerNode.parentElement!, []);
254258

255259
return (
256-
<div className={cls('dm-chat-history-header', className)}>
257-
<div className='dm-chat-history-header-title'>
260+
<div className={cls(styles['dm-chat-history-header'], className)}>
261+
<div className={styles['dm-chat-history-header-title']}>
258262
<span>{title}</span>
259263
</div>
260-
<div className='dm-chat-history-header-actions'>
264+
<div className={styles['dm-chat-history-header-actions']}>
261265
<Popover
262266
id='dm-chat-history-header-actions-history'
263267
content={renderHistory()}
@@ -267,10 +271,12 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
267271
getPopupContainer={getPopupContainer}
268272
>
269273
<div
270-
className='dm-chat-history-header-actions-history'
274+
className={styles['dm-chat-history-header-actions-history']}
271275
title={localize('aiNative.operate.chatHistory.title')}
272276
>
273-
<EnhanceIcon className={cls('dm-chat-history-header-actions-history', 'codicon codicon-history')} />
277+
<EnhanceIcon
278+
className={cls(styles['dm-chat-history-header-actions-history'], 'codicon codicon-history')}
279+
/>
274280
</div>
275281
</Popover>
276282
<Popover
@@ -279,7 +285,7 @@ const ChatHistory: FC<IChatHistoryProps> = memo(
279285
title={localize('aiNative.operate.newChat.title')}
280286
>
281287
<EnhanceIcon
282-
className={cls('dm-chat-history-header-actions-new', getIcon('plus'))}
288+
className={cls(styles['dm-chat-history-header-actions-new'], getIcon('plus'))}
283289
onClick={handleNewChat}
284290
/>
285291
</Popover>

packages/ai-native/src/browser/components/chat-history.css renamed to packages/ai-native/src/browser/components/chat-history.module.less

File renamed without changes.

0 commit comments

Comments
 (0)