Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into planger/request-c…
Browse files Browse the repository at this point in the history
…ontext
  • Loading branch information
sdirix committed Feb 17, 2025
2 parents fb4c2b5 + 91c52c4 commit aea0e4d
Show file tree
Hide file tree
Showing 109 changed files with 1,585 additions and 673 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

- [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/)

## 1.59.0

<a name="breaking_changes_1.59.0">[Breaking Changes:](#breaking_changes_1.59.0)</a>

- [core] Adjusted the binding of named `ILogger` injections. These no longer have to be bound explicitly.
If you encounter errors such as `Error: Ambiguous match found for serviceIdentifier: Symbol(ILogger)`, remove your bindings for the `ILogger` symbol.

## 1.58.0 - 01/30/2025

- [ai] added 'required' property to tool call parameters [#14673](https://github.com/eclipse-theia/theia/pull/14673)
Expand Down Expand Up @@ -33,7 +40,7 @@
- [core] added support for dragging files in browser [#14756](https://github.com/eclipse-theia/theia/pull/14756)
- [core] fixed dragging file from outside the workspace [#14746](https://github.com/eclipse-theia/theia/pull/14746)
- [core] fixed override of default key bindings [#14668](https://github.com/eclipse-theia/theia/pull/14668)
- [core] fixed workbench.action.files.newUntitledFile [#0](https://github.com/eclipse-theia/theia/pull/0)
- [core] fixed `workbench.action.files.newUntitledFile` command [#14754](https://github.com/eclipse-theia/theia/pull/14754)
- [core] fixed z-index overlay issue in dock panels [#14695](https://github.com/eclipse-theia/theia/pull/14695)
- [core] updated build scripts to use npm instead of yarn to build Theia [#14481](https://github.com/eclipse-theia/theia/pull/14481) - Contributed on behalf of STMicroelectronics
- [core] updated keytar and drivelist [#14306](https://github.com/eclipse-theia/theia/pull/14306)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ import {
ChatAgent,
ChatMessage,
ChatModel,
ChatRequestModelImpl,
MutableChatRequestModel,
lastProgressMessage,
QuestionResponseContentImpl,
SystemMessageDescription,
unansweredQuestions
} from '@theia/ai-chat';
import { Agent, PromptTemplate } from '@theia/ai-core';
Expand Down Expand Up @@ -109,21 +108,26 @@ Do not ask further questions once the text contains 5 or more "Question/Answer"
* This is a very simple example agent that asks questions and continues the conversation based on the user's answers.
*/
@injectable()
export class AskAndContinueChatAgent extends AbstractStreamParsingChatAgent implements ChatAgent {
override id = 'AskAndContinue';
readonly name = 'AskAndContinue';
override defaultLanguageModelPurpose = 'chat';
readonly description = 'This chat will ask questions related to the input and continues after that.';
readonly variables = [];
readonly agentSpecificVariables = [];
readonly functions = [];
export class AskAndContinueChatAgent extends AbstractStreamParsingChatAgent {
id = 'AskAndContinue';
name = 'AskAndContinue';
override description = 'This chat will ask questions related to the input and continues after that.';
protected defaultLanguageModelPurpose = 'chat';
override languageModelRequirements = [
{
purpose: 'chat',
identifier: 'openai/gpt-4o',
}
];
override promptTemplates = [systemPrompt];
protected override systemPromptId: string | undefined = systemPrompt.id;

@postConstruct()
addContentMatchers(): void {
this.contentMatchers.push({
start: /^<question>.*$/m,
end: /^<\/question>$/m,
contentFactory: (content: string, request: ChatRequestModelImpl) => {
contentFactory: (content: string, request: MutableChatRequestModel) => {
const question = content.replace(/^<question>\n|<\/question>$/g, '');
const parsedQuestion = JSON.parse(question);
return new QuestionResponseContentImpl(parsedQuestion.question, parsedQuestion.options, request, selectedOption => {
Expand All @@ -133,21 +137,7 @@ export class AskAndContinueChatAgent extends AbstractStreamParsingChatAgent impl
});
}

override languageModelRequirements = [
{
purpose: 'chat',
identifier: 'openai/gpt-4o',
}
];

readonly promptTemplates = [systemPrompt];

protected override async getSystemMessageDescription(): Promise<SystemMessageDescription | undefined> {
const resolvedPrompt = await this.promptService.getPrompt(systemPrompt.id);
return resolvedPrompt ? SystemMessageDescription.fromResolvedPromptTemplate(resolvedPrompt) : undefined;
}

protected override async onResponseComplete(request: ChatRequestModelImpl): Promise<void> {
protected override async onResponseComplete(request: MutableChatRequestModel): Promise<void> {
const unansweredQs = unansweredQuestions(request);
if (unansweredQs.length < 1) {
return super.onResponseComplete(request);
Expand All @@ -156,7 +146,7 @@ export class AskAndContinueChatAgent extends AbstractStreamParsingChatAgent impl
request.response.waitForInput();
}

protected handleAnswer(selectedOption: { text: string; value?: string; }, request: ChatRequestModelImpl): void {
protected handleAnswer(selectedOption: { text: string; value?: string; }, request: MutableChatRequestModel): void {
const progressMessage = lastProgressMessage(request);
if (progressMessage) {
request.response.updateProgressMessage({ ...progressMessage, show: 'untilFirstContent', status: 'completed' });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import {
AbstractStreamParsingChatAgent,
ChangeSetImpl,
ChatAgent,
ChatRequestModelImpl,
MutableChatRequestModel,
MarkdownChatResponseContentImpl,
SystemMessageDescription
} from '@theia/ai-chat';
import { ChangeSetFileElementFactory } from '@theia/ai-chat/lib/browser/change-set-file-element';
import { Agent, PromptTemplate } from '@theia/ai-core';
import { Agent, LanguageModelRequirement } from '@theia/ai-core';
import { URI } from '@theia/core';
import { inject, injectable, interfaces } from '@theia/core/shared/inversify';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
Expand All @@ -39,16 +39,12 @@ export function bindChangeSetChatAgentContribution(bind: interfaces.Bind): void
* This is a test agent demonstrating how to create change sets in AI chats.
*/
@injectable()
export class ChangeSetChatAgent extends AbstractStreamParsingChatAgent implements ChatAgent {
override id = 'ChangeSet';
export class ChangeSetChatAgent extends AbstractStreamParsingChatAgent {
readonly id = 'ChangeSet';
readonly name = 'ChangeSet';
override defaultLanguageModelPurpose = 'chat';
readonly description = 'This chat will create and modify a change set.';
readonly variables = [];
readonly agentSpecificVariables = [];
readonly functions = [];
override languageModelRequirements = [];
promptTemplates: PromptTemplate[] = [];
readonly defaultLanguageModelPurpose = 'chat';
override readonly description = 'This chat will create and modify a change set.';
override languageModelRequirements: LanguageModelRequirement[] = [];

@inject(WorkspaceService)
protected readonly workspaceService: WorkspaceService;
Expand All @@ -59,7 +55,7 @@ export class ChangeSetChatAgent extends AbstractStreamParsingChatAgent implement
@inject(ChangeSetFileElementFactory)
protected readonly fileChangeFactory: ChangeSetFileElementFactory;

override async invoke(request: ChatRequestModelImpl): Promise<void> {
override async invoke(request: MutableChatRequestModel): Promise<void> {
const roots = this.workspaceService.tryGetRoots();
if (roots.length === 0) {
request.response.response.addContent(new MarkdownChatResponseContentImpl(
Expand Down
37 changes: 22 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions packages/ai-chat-ui/src/browser/chat-input-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -504,11 +504,13 @@ const ChangeSetBox: React.FunctionComponent<{ changeSet: ChangeSetUI }> = ({ cha
{changeSet.elements.map((element, index) => (
<li key={index} title='Open Diff' onClick={() => element.openChange?.()}>
<div className={`theia-ChatInput-ChangeSet-Icon ${element.iconClass}`} />
<span className={`theia-ChatInput-ChangeSet-title ${element.nameClass}`}>
{element.name}
</span>
<span className='theia-ChatInput-ChangeSet-additionalInfo'>
{element.additionalInfo}
<span className='theia-ChatInput-ChangeSet-labelParts'>
<span className={`theia-ChatInput-ChangeSet-title ${element.nameClass}`}>
{element.name}
</span>
<span className='theia-ChatInput-ChangeSet-additionalInfo'>
{element.additionalInfo}
</span>
</span>
<div className='theia-ChatInput-ChangeSet-Actions'>
{element.open && (<span className='codicon codicon-file action' title='Open Original File' onClick={noPropagation(() => element.open!())} />)}
Expand Down
12 changes: 6 additions & 6 deletions packages/ai-chat-ui/src/browser/chat-view-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
const parent = extractRequestOrResponseNodes(args).find(arg => arg.parent)?.parent;
const text = parent?.children
.filter(isRequestOrResponseNode)
.map(child => this.getText(child))
.map(child => this.getCopyText(child))
.join('\n\n---\n\n');
if (text) {
this.clipboardService.writeText(text);
Expand All @@ -93,19 +93,19 @@ export class ChatViewMenuContribution implements MenuContribution, CommandContri
}

protected copyMessage(args: (RequestNode | ResponseNode)[]): void {
const text = this.getTextAndJoin(args);
const text = this.getCopyTextAndJoin(args);
this.clipboardService.writeText(text);
}

protected getTextAndJoin(args: (RequestNode | ResponseNode)[] | undefined): string {
return args !== undefined ? args.map(arg => this.getText(arg)).join() : '';
protected getCopyTextAndJoin(args: (RequestNode | ResponseNode)[] | undefined): string {
return args !== undefined ? args.map(arg => this.getCopyText(arg)).join() : '';
}

protected getText(arg: RequestNode | ResponseNode): string {
protected getCopyText(arg: RequestNode | ResponseNode): string {
if (isRequestNode(arg)) {
return arg.request.request.text;
} else if (isResponseNode(arg)) {
return arg.response.response.asString();
return arg.response.response.asDisplayString();
}
return '';
}
Expand Down
Loading

0 comments on commit aea0e4d

Please sign in to comment.