Skip to content

Add the terminal output to the chat context #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
37 changes: 36 additions & 1 deletion apps/studio/src/lib/editor/engine/chat/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
type HighlightMessageContext,
type ImageMessageContext,
type ProjectMessageContext,
type TerminalMessageContext,
} from '@onlook/models/chat';
import type { DomElement } from '@onlook/models/element';
import type { ParsedError } from '@onlook/utility';
Expand Down Expand Up @@ -44,7 +45,14 @@ export class ChatContext {
const fileContext = await this.getFileContext(fileNames);
const imageContext = await this.getImageContext();
const projectContext = await this.getProjectContext();
const context = [...fileContext, ...highlightedContext, ...imageContext, ...projectContext];
const terminalContext = await this.getTerminalContext();
const context = [
...fileContext,
...highlightedContext,
...imageContext,
...projectContext,
...terminalContext,
];
return context;
}

Expand Down Expand Up @@ -72,6 +80,13 @@ export class ChatContext {
return fileContext;
}

private async getTerminalContext(): Promise<TerminalMessageContext[]> {
const terminalContext = this.context.filter(
(context) => context.type === MessageContextType.TERMINAL,
);
return terminalContext;
}

private async getHighlightedContext(
selected: DomElement[],
fileNames: Set<string>,
Expand Down Expand Up @@ -111,6 +126,26 @@ export class ChatContext {
this.context = [];
}

async addTerminalContext() {
const terminalContent = await this.getTerminalContent();
if (terminalContent) {
this.context = this.context.filter((ctx) => ctx.type !== MessageContextType.TERMINAL);
this.context.push(terminalContent);
}
}

async getTerminalContent(): Promise<TerminalMessageContext | null> {
const output = await this.editorEngine.getTerminalOutput();
if (!output) {
return null;
}
return {
type: MessageContextType.TERMINAL,
content: output,
displayName: 'Terminal',
};
}

async addScreenshotContext() {
const screenshot = await this.getScreenshotContext();
if (screenshot) {
Expand Down
12 changes: 12 additions & 0 deletions apps/studio/src/lib/editor/engine/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,18 @@ export class EditorEngine {
};
}

async getTerminalOutput(): Promise<string | null> {
try {
if (!this.projectsManager.runner) {
return null;
}
const history = await this.projectsManager.runner.getHistory();
return history || null;
} catch (error) {
console.error('Failed to get terminal output:', error);
return null;
}
}
canDeleteWindow() {
return this.canvas.frames.length > 1;
}
Expand Down
27 changes: 27 additions & 0 deletions apps/studio/src/routes/editor/EditPanel/ChatTab/ChatInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,33 @@ export const ChatInput = observer(() => {
</TooltipContent>
</TooltipPortal>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant={'ghost'}
size={'icon'}
className="w-9 h-9 text-foreground-tertiary group hover:bg-transparent"
onClick={() => {
editorEngine.chat.context.addTerminalContext();
}}
disabled={disabled}
>
<Icons.Terminal
className={cn(
'w-5 h-5',
disabled
? 'text-foreground-tertiary'
: 'group-hover:text-foreground',
)}
/>
</Button>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="top" sideOffset={5}>
{disabled ? 'Select an element to start' : 'Add terminal output'}
</TooltipContent>
</TooltipPortal>
</Tooltip>
<Button
variant={'outline'}
className="w-fit h-fit py-0.5 px-2.5 text-foreground-tertiary hidden"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export function getContextIcon(context: ChatMessageContext) {
case MessageContextType.PROJECT:
icon = Icons.Cube;
break;
case MessageContextType.TERMINAL:
icon = Icons.Terminal;
break;
default:
assertNever(context);
}
Expand Down
10 changes: 9 additions & 1 deletion packages/models/src/chat/message/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum MessageContextType {
IMAGE = 'image',
ERROR = 'error',
PROJECT = 'project',
TERMINAL = 'terminal',
}

type BaseMessageContext = {
Expand Down Expand Up @@ -38,9 +39,16 @@ export type ProjectMessageContext = BaseMessageContext & {
path: string;
};

export type TerminalMessageContext = BaseMessageContext & {
type: MessageContextType.TERMINAL;
content: string;
displayName: string;
};

export type ChatMessageContext =
| FileMessageContext
| HighlightMessageContext
| ImageMessageContext
| ErrorMessageContext
| ProjectMessageContext;
| ProjectMessageContext
| TerminalMessageContext;