{!inProgress &&
toolbarContributions.length > 0 &&
@@ -340,12 +342,28 @@ export class ChatViewTreeWidget extends TreeWidget {
{!node.response.isComplete
&& node.response.response.content.length === 0
- && node.response.progressMessages.map((c, i) =>
-
- )}
+ && node.response.progressMessages
+ .filter(c => c.show === 'untilFirstContent')
+ .map((c, i) =>
+
+ )
+ }
{node.response.response.content.map((c, i) =>
{this.getChatResponsePartRenderer(c, node)}
)}
+ {!node.response.isComplete
+ && node.response.progressMessages
+ .filter(c => c.show === 'whileIncomplete')
+ .map((c, i) =>
+
+ )
+ }
+ {node.response.progressMessages
+ .filter(c => c.show === 'forever')
+ .map((c, i) =>
+
+ )
+ }
);
}
diff --git a/packages/ai-chat-ui/src/browser/style/index.css b/packages/ai-chat-ui/src/browser/style/index.css
index 4c86cfe272689..bd9dc56775816 100644
--- a/packages/ai-chat-ui/src/browser/style/index.css
+++ b/packages/ai-chat-ui/src/browser/style/index.css
@@ -231,7 +231,7 @@ div:last-child > .theia-ChatNode {
display: flex;
flex-direction: column;
gap: 2px;
- border: 1px solid var(--theia-input-border);
+ border: var(--theia-border-width) solid var(--theia-input-border);
border-radius: 4px;
}
@@ -265,6 +265,33 @@ div:last-child > .theia-ChatNode {
background-color: var(--theia-input-border);
}
+.theia-QuestionPartRenderer-root {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ border: var(--theia-border-width) solid
+ var(--theia-sideBarSectionHeader-border);
+ padding: 8px 12px 12px;
+ border-radius: 5px;
+ margin: 0 0 8px 0;
+}
+.theia-QuestionPartRenderer-options {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+}
+.theia-QuestionPartRenderer-option {
+ min-width: 100px;
+ flex: 1 1 auto;
+ margin: 0;
+}
+.theia-QuestionPartRenderer-option.selected:disabled:hover {
+ background-color: var(--theia-button-disabledBackground);
+}
+.theia-QuestionPartRenderer-option:disabled:not(.selected) {
+ background-color: var(--theia-button-secondaryBackground);
+}
+
.theia-toolCall {
font-weight: normal;
color: var(--theia-descriptionForeground);
diff --git a/packages/ai-chat/src/common/chat-agents.ts b/packages/ai-chat/src/common/chat-agents.ts
index f5b9f1e735e99..542cbfc462c4b 100644
--- a/packages/ai-chat/src/common/chat-agents.ts
+++ b/packages/ai-chat/src/common/chat-agents.ts
@@ -144,7 +144,12 @@ export abstract class AbstractChatAgent {
@postConstruct()
init(): void {
- this.contentMatchers = this.contentMatcherProviders.getContributions().flatMap(provider => provider.matchers);
+ this.initializeContentMatchers();
+ }
+
+ protected initializeContentMatchers(): void {
+ const contributedContentMatchers = this.contentMatcherProviders.getContributions().flatMap(provider => provider.matchers);
+ this.contentMatchers.push(...contributedContentMatchers);
}
async invoke(request: ChatRequestModelImpl): Promise
{
@@ -195,7 +200,7 @@ export abstract class AbstractChatAgent {
cancellationToken.token
);
await this.addContentsToResponse(languageModelResponse, request);
- request.response.complete();
+ await this.onResponseComplete(request);
if (this.defaultLogging) {
this.recordingService.recordResponse(ChatHistoryEntry.fromResponse(this.id, request));
}
@@ -204,9 +209,10 @@ export abstract class AbstractChatAgent {
}
}
- protected parseContents(text: string): ChatResponseContent[] {
+ protected parseContents(text: string, request: ChatRequestModelImpl): ChatResponseContent[] {
return parseContents(
text,
+ request,
this.contentMatchers,
this.defaultContentFactory?.create.bind(this.defaultContentFactory)
);
@@ -290,6 +296,16 @@ export abstract class AbstractChatAgent {
return undefined;
}
+ /**
+ * Invoked after the response by the LLM completed successfully.
+ *
+ * The default implementation sets the state of the response to `complete`.
+ * Subclasses may override this method to perform additional actions or keep the response open for processing further requests.
+ */
+ protected async onResponseComplete(request: ChatRequestModelImpl): Promise {
+ return request.response.complete();
+ }
+
protected abstract addContentsToResponse(languageModelResponse: LanguageModelResponse, request: ChatRequestModelImpl): Promise;
}
@@ -313,20 +329,12 @@ export abstract class AbstractStreamParsingChatAgent extends AbstractChatAgent {
protected override async addContentsToResponse(languageModelResponse: LanguageModelResponse, request: ChatRequestModelImpl): Promise {
if (isLanguageModelTextResponse(languageModelResponse)) {
- const contents = this.parseContents(languageModelResponse.text);
+ const contents = this.parseContents(languageModelResponse.text, request);
request.response.response.addContents(contents);
- request.response.complete();
- if (this.defaultLogging) {
- this.recordingService.recordResponse(ChatHistoryEntry.fromResponse(this.id, request));
- }
return;
}
if (isLanguageModelStreamResponse(languageModelResponse)) {
await this.addStreamResponse(languageModelResponse, request);
- request.response.complete();
- if (this.defaultLogging) {
- this.recordingService.recordResponse(ChatHistoryEntry.fromResponse(this.id, request));
- }
return;
}
this.logger.error(
@@ -341,7 +349,7 @@ export abstract class AbstractStreamParsingChatAgent extends AbstractChatAgent {
protected async addStreamResponse(languageModelResponse: LanguageModelStreamResponse, request: ChatRequestModelImpl): Promise {
for await (const token of languageModelResponse.stream) {
- const newContents = this.parse(token, request.response.response.content);
+ const newContents = this.parse(token, request);
if (isArray(newContents)) {
request.response.response.addContents(newContents);
} else {
@@ -357,7 +365,7 @@ export abstract class AbstractStreamParsingChatAgent extends AbstractChatAgent {
return;
}
- const result: ChatResponseContent[] = findFirstMatch(this.contentMatchers, text) ? this.parseContents(text) : [];
+ const result: ChatResponseContent[] = findFirstMatch(this.contentMatchers, text) ? this.parseContents(text, request) : [];
if (result.length > 0) {
request.response.response.addContents(result);
} else {
@@ -366,11 +374,11 @@ export abstract class AbstractStreamParsingChatAgent extends AbstractChatAgent {
}
}
- protected parse(token: LanguageModelStreamResponsePart, previousContent: ChatResponseContent[]): ChatResponseContent | ChatResponseContent[] {
+ protected parse(token: LanguageModelStreamResponsePart, request: ChatRequestModelImpl): ChatResponseContent | ChatResponseContent[] {
const content = token.content;
// eslint-disable-next-line no-null/no-null
if (content !== undefined && content !== null) {
- return this.defaultContentFactory.create(content);
+ return this.defaultContentFactory.create(content, request);
}
const toolCalls = token.tool_calls;
if (toolCalls !== undefined) {
@@ -378,7 +386,7 @@ export abstract class AbstractStreamParsingChatAgent extends AbstractChatAgent {
new ToolCallChatResponseContentImpl(toolCall.id, toolCall.function?.name, toolCall.function?.arguments, toolCall.finished, toolCall.result));
return toolCallContents;
}
- return this.defaultContentFactory.create('');
+ return this.defaultContentFactory.create('', request);
}
}
diff --git a/packages/ai-chat/src/common/chat-model-util.ts b/packages/ai-chat/src/common/chat-model-util.ts
new file mode 100644
index 0000000000000..1bad8b6bad0c6
--- /dev/null
+++ b/packages/ai-chat/src/common/chat-model-util.ts
@@ -0,0 +1,44 @@
+// *****************************************************************************
+// Copyright (C) 2024 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 { ChatProgressMessage, ChatRequestModel, ChatResponse, ChatResponseContent, ChatResponseModel, QuestionResponseContent } from './chat-model';
+
+export function lastResponseContent(request: ChatRequestModel): ChatResponseContent | undefined {
+ return lastContentOfResponse(request.response?.response);
+}
+
+export function lastContentOfResponse(response: ChatResponse | undefined): ChatResponseContent | undefined {
+ const content = response?.content;
+ return content && content.length > 0 ? content[content.length - 1] : undefined;
+}
+
+export function lastProgressMessage(request: ChatRequestModel): ChatProgressMessage | undefined {
+ return lastProgressMessageOfResponse(request.response);
+}
+
+export function lastProgressMessageOfResponse(response: ChatResponseModel | undefined): ChatProgressMessage | undefined {
+ const progressMessages = response?.progressMessages;
+ return progressMessages && progressMessages.length > 0 ? progressMessages[progressMessages.length - 1] : undefined;
+}
+
+export function unansweredQuestions(request: ChatRequestModel): QuestionResponseContent[] {
+ const response = request.response;
+ return unansweredQuestionsOfResponse(response);
+}
+
+function unansweredQuestionsOfResponse(response: ChatResponseModel | undefined): QuestionResponseContent[] {
+ if (!response || !response.response) { return []; }
+ return response.response.content.filter((c): c is QuestionResponseContent => QuestionResponseContent.is(c) && c.selectedOption === undefined);
+}
diff --git a/packages/ai-chat/src/common/chat-model.ts b/packages/ai-chat/src/common/chat-model.ts
index 0decfb284da35..9c6cd66af14b4 100644
--- a/packages/ai-chat/src/common/chat-model.ts
+++ b/packages/ai-chat/src/common/chat-model.ts
@@ -80,6 +80,7 @@ export interface ChatProgressMessage {
kind: 'progressMessage';
id: string;
status: 'inProgress' | 'completed' | 'failed';
+ show: 'untilFirstContent' | 'whileIncomplete' | 'forever';
content: string;
}
@@ -279,6 +280,42 @@ export namespace ErrorChatResponseContent {
}
}
+export type QuestionResponseHandler = (
+ selectedOption: { text: string, value?: string },
+) => void;
+
+export interface QuestionResponseContent extends ChatResponseContent {
+ kind: 'question';
+ question: string;
+ options: { text: string, value?: string }[];
+ selectedOption?: { text: string, value?: string };
+ handler: QuestionResponseHandler;
+ request: ChatRequestModelImpl;
+}
+
+export namespace QuestionResponseContent {
+ export function is(obj: unknown): obj is QuestionResponseContent {
+ return (
+ ChatResponseContent.is(obj) &&
+ obj.kind === 'question' &&
+ 'question' in obj &&
+ typeof (obj as { question: unknown }).question === 'string' &&
+ 'options' in obj &&
+ Array.isArray((obj as { options: unknown }).options) &&
+ (obj as { options: unknown[] }).options.every(option =>
+ typeof option === 'object' &&
+ option && 'text' in option &&
+ typeof (option as { text: unknown }).text === 'string' &&
+ ('value' in option ? typeof (option as { value: unknown }).value === 'string' || typeof (option as { value: unknown }).value === 'undefined' : true)
+ ) &&
+ 'handler' in obj &&
+ typeof (obj as { handler: unknown }).handler === 'function' &&
+ 'request' in obj &&
+ obj.request instanceof ChatRequestModelImpl
+ );
+ }
+}
+
export interface ChatResponse {
readonly content: ChatResponseContent[];
asString(): string;
@@ -292,6 +329,7 @@ export interface ChatResponseModel {
readonly response: ChatResponse;
readonly isComplete: boolean;
readonly isCanceled: boolean;
+ readonly isWaitingForInput: boolean;
readonly isError: boolean;
readonly agentId?: string
readonly errorObject?: Error;
@@ -602,6 +640,31 @@ export class HorizontalLayoutChatResponseContentImpl implements HorizontalLayout
}
}
+/**
+ * Default implementation for the QuestionResponseContent.
+ */
+export class QuestionResponseContentImpl implements QuestionResponseContent {
+ readonly kind = 'question';
+ protected _selectedOption: { text: string; value?: string } | undefined;
+ constructor(public question: string, public options: { text: string, value?: string }[],
+ public request: ChatRequestModelImpl, public handler: QuestionResponseHandler) {
+ }
+ set selectedOption(option: { text: string; value?: string; } | undefined) {
+ this._selectedOption = option;
+ this.request.response.response.responseContentChanged();
+ }
+ get selectedOption(): { text: string; value?: string; } | undefined {
+ return this._selectedOption;
+ }
+ asString?(): string | undefined {
+ return `Question: ${this.question}
+${this.selectedOption ? `Answer: ${this.selectedOption?.text}` : 'No answer'}`;
+ }
+ merge?(): boolean {
+ return false;
+ }
+}
+
class ChatResponseImpl implements ChatResponse {
protected readonly _onDidChangeEmitter = new Emitter();
onDidChange: Event = this._onDidChangeEmitter.event;
@@ -654,6 +717,11 @@ class ChatResponseImpl implements ChatResponse {
this._updateResponseRepresentation();
}
+ responseContentChanged(): void {
+ this._updateResponseRepresentation();
+ this._onDidChangeEmitter.fire();
+ }
+
protected _updateResponseRepresentation(): void {
this._responseRepresentation = this._content
.map(responseContent => {
@@ -688,6 +756,7 @@ class ChatResponseModelImpl implements ChatResponseModel {
protected _response: ChatResponseImpl;
protected _isComplete: boolean;
protected _isCanceled: boolean;
+ protected _isWaitingForInput: boolean;
protected _agentId?: string;
protected _isError: boolean;
protected _errorObject: Error | undefined;
@@ -702,6 +771,7 @@ class ChatResponseModelImpl implements ChatResponseModel {
this._response = response;
this._isComplete = false;
this._isCanceled = false;
+ this._isWaitingForInput = false;
this._agentId = agentId;
}
@@ -728,6 +798,7 @@ class ChatResponseModelImpl implements ChatResponseModel {
kind: 'progressMessage',
id,
status: message.status ?? 'inProgress',
+ show: message.show ?? 'untilFirstContent',
...message,
};
this._progressMessages.push(newMessage);
@@ -759,6 +830,10 @@ class ChatResponseModelImpl implements ChatResponseModel {
return this._isCanceled;
}
+ get isWaitingForInput(): boolean {
+ return this._isWaitingForInput;
+ }
+
get agentId(): string | undefined {
return this._agentId;
}
@@ -769,17 +844,31 @@ class ChatResponseModelImpl implements ChatResponseModel {
complete(): void {
this._isComplete = true;
+ this._isWaitingForInput = false;
this._onDidChangeEmitter.fire();
}
cancel(): void {
this._isComplete = true;
this._isCanceled = true;
+ this._isWaitingForInput = false;
this._onDidChangeEmitter.fire();
}
+
+ waitForInput(): void {
+ this._isWaitingForInput = true;
+ this._onDidChangeEmitter.fire();
+ }
+
+ stopWaitingForInput(): void {
+ this._isWaitingForInput = false;
+ this._onDidChangeEmitter.fire();
+ }
+
error(error: Error): void {
this._isComplete = true;
this._isCanceled = false;
+ this._isWaitingForInput = false;
this._isError = true;
this._errorObject = error;
this._onDidChangeEmitter.fire();
diff --git a/packages/ai-chat/src/common/index.ts b/packages/ai-chat/src/common/index.ts
index cf160ddcadf10..b0100cff31203 100644
--- a/packages/ai-chat/src/common/index.ts
+++ b/packages/ai-chat/src/common/index.ts
@@ -16,6 +16,7 @@
export * from './chat-agents';
export * from './chat-agent-service';
export * from './chat-model';
+export * from './chat-model-util';
export * from './chat-request-parser';
export * from './chat-service';
export * from './command-chat-agents';
diff --git a/packages/ai-chat/src/common/parse-contents.spec.ts b/packages/ai-chat/src/common/parse-contents.spec.ts
index c0a009f8cb814..cba9fa1b598e6 100644
--- a/packages/ai-chat/src/common/parse-contents.spec.ts
+++ b/packages/ai-chat/src/common/parse-contents.spec.ts
@@ -15,7 +15,7 @@
// *****************************************************************************
import { expect } from 'chai';
-import { ChatResponseContent, CodeChatResponseContentImpl, MarkdownChatResponseContentImpl } from './chat-model';
+import { ChatRequestModelImpl, ChatResponseContent, CodeChatResponseContentImpl, MarkdownChatResponseContentImpl } from './chat-model';
import { parseContents } from './parse-contents';
import { CodeContentMatcher, ResponseContentMatcher } from './response-content-matcher';
@@ -33,22 +33,24 @@ export const CommandContentMatcher: ResponseContentMatcher = {
}
};
+const fakeRequest = {} as ChatRequestModelImpl;
+
describe('parseContents', () => {
it('should parse code content', () => {
const text = '```typescript\nconsole.log("Hello World");\n```';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([new CodeChatResponseContentImpl('console.log("Hello World");', 'typescript')]);
});
it('should parse markdown content', () => {
const text = 'Hello **World**';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([new MarkdownChatResponseContentImpl('Hello **World**')]);
});
it('should parse multiple content blocks', () => {
const text = '```typescript\nconsole.log("Hello World");\n```\nHello **World**';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([
new CodeChatResponseContentImpl('console.log("Hello World");', 'typescript'),
new MarkdownChatResponseContentImpl('\nHello **World**')
@@ -57,7 +59,7 @@ describe('parseContents', () => {
it('should parse multiple content blocks with different languages', () => {
const text = '```typescript\nconsole.log("Hello World");\n```\n```python\nprint("Hello World")\n```';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([
new CodeChatResponseContentImpl('console.log("Hello World");', 'typescript'),
new CodeChatResponseContentImpl('print("Hello World")', 'python')
@@ -66,7 +68,7 @@ describe('parseContents', () => {
it('should parse multiple content blocks with different languages and markdown', () => {
const text = '```typescript\nconsole.log("Hello World");\n```\nHello **World**\n```python\nprint("Hello World")\n```';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([
new CodeChatResponseContentImpl('console.log("Hello World");', 'typescript'),
new MarkdownChatResponseContentImpl('\nHello **World**\n'),
@@ -76,7 +78,7 @@ describe('parseContents', () => {
it('should parse content blocks with empty content', () => {
const text = '```typescript\n```\nHello **World**\n```python\nprint("Hello World")\n```';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([
new CodeChatResponseContentImpl('', 'typescript'),
new MarkdownChatResponseContentImpl('\nHello **World**\n'),
@@ -86,7 +88,7 @@ describe('parseContents', () => {
it('should parse content with markdown, code, and markdown', () => {
const text = 'Hello **World**\n```typescript\nconsole.log("Hello World");\n```\nGoodbye **World**';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([
new MarkdownChatResponseContentImpl('Hello **World**\n'),
new CodeChatResponseContentImpl('console.log("Hello World");', 'typescript'),
@@ -96,25 +98,25 @@ describe('parseContents', () => {
it('should handle text with no special content', () => {
const text = 'Just some plain text.';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([new MarkdownChatResponseContentImpl('Just some plain text.')]);
});
it('should handle text with only start code block', () => {
const text = '```typescript\nconsole.log("Hello World");';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([new MarkdownChatResponseContentImpl('```typescript\nconsole.log("Hello World");')]);
});
it('should handle text with only end code block', () => {
const text = 'console.log("Hello World");\n```';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([new MarkdownChatResponseContentImpl('console.log("Hello World");\n```')]);
});
it('should handle text with unmatched code block', () => {
const text = '```typescript\nconsole.log("Hello World");\n```\n```python\nprint("Hello World")';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([
new CodeChatResponseContentImpl('console.log("Hello World");', 'typescript'),
new MarkdownChatResponseContentImpl('\n```python\nprint("Hello World")')
@@ -123,7 +125,7 @@ describe('parseContents', () => {
it('should parse code block without newline after language', () => {
const text = '```typescript console.log("Hello World");```';
- const result = parseContents(text);
+ const result = parseContents(text, fakeRequest);
expect(result).to.deep.equal([
new MarkdownChatResponseContentImpl('```typescript console.log("Hello World");```')
]);
@@ -131,7 +133,7 @@ describe('parseContents', () => {
it('should parse with matches of multiple different matchers and default', () => {
const text = '\nMY_SPECIAL_COMMAND\n\nHello **World**\n```python\nprint("Hello World")\n```\n\nMY_SPECIAL_COMMAND2\n';
- const result = parseContents(text, [CodeContentMatcher, CommandContentMatcher]);
+ const result = parseContents(text, fakeRequest, [CodeContentMatcher, CommandContentMatcher]);
expect(result).to.deep.equal([
new CommandChatResponseContentImpl('MY_SPECIAL_COMMAND'),
new MarkdownChatResponseContentImpl('\nHello **World**\n'),
diff --git a/packages/ai-chat/src/common/parse-contents.ts b/packages/ai-chat/src/common/parse-contents.ts
index 16f405495ce20..1dd1afbbe1ee8 100644
--- a/packages/ai-chat/src/common/parse-contents.ts
+++ b/packages/ai-chat/src/common/parse-contents.ts
@@ -13,7 +13,7 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
*/
-import { ChatResponseContent } from './chat-model';
+import { ChatRequestModelImpl, ChatResponseContent } from './chat-model';
import { CodeContentMatcher, MarkdownContentFactory, ResponseContentFactory, ResponseContentMatcher } from './response-content-matcher';
interface Match {
@@ -24,6 +24,7 @@ interface Match {
export function parseContents(
text: string,
+ request: ChatRequestModelImpl,
contentMatchers: ResponseContentMatcher[] = [CodeContentMatcher],
defaultContentFactory: ResponseContentFactory = MarkdownContentFactory
): ChatResponseContent[] {
@@ -36,7 +37,7 @@ export function parseContents(
if (!match) {
// Add the remaining text as default content
if (remainingText.length > 0) {
- result.push(defaultContentFactory(remainingText));
+ result.push(defaultContentFactory(remainingText, request));
}
break;
}
@@ -45,11 +46,11 @@ export function parseContents(
if (match.index > 0) {
const precedingContent = remainingText.substring(0, match.index);
if (precedingContent.trim().length > 0) {
- result.push(defaultContentFactory(precedingContent));
+ result.push(defaultContentFactory(precedingContent, request));
}
}
// 2. Add the matched content object
- result.push(match.matcher.contentFactory(match.content));
+ result.push(match.matcher.contentFactory(match.content, request));
// Update currentIndex to the end of the end of the match
// And continue with the search after the end of the match
currentIndex += match.index + match.content.length;
diff --git a/packages/ai-chat/src/common/response-content-matcher.ts b/packages/ai-chat/src/common/response-content-matcher.ts
index 3fb785e603c5f..86aa7e83316cb 100644
--- a/packages/ai-chat/src/common/response-content-matcher.ts
+++ b/packages/ai-chat/src/common/response-content-matcher.ts
@@ -14,13 +14,14 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
*/
import {
+ ChatRequestModelImpl,
ChatResponseContent,
CodeChatResponseContentImpl,
MarkdownChatResponseContentImpl
} from './chat-model';
import { injectable } from '@theia/core/shared/inversify';
-export type ResponseContentFactory = (content: string) => ChatResponseContent;
+export type ResponseContentFactory = (content: string, request: ChatRequestModelImpl) => ChatResponseContent;
export const MarkdownContentFactory: ResponseContentFactory = (content: string) =>
new MarkdownChatResponseContentImpl(content);
@@ -33,8 +34,8 @@ export const MarkdownContentFactory: ResponseContentFactory = (content: string)
*/
@injectable()
export class DefaultResponseContentFactory {
- create(content: string): ChatResponseContent {
- return MarkdownContentFactory(content);
+ create(content: string, request: ChatRequestModelImpl): ChatResponseContent {
+ return MarkdownContentFactory(content, request);
}
}