terminal tool improvements

This commit is contained in:
Andrew Pareles 2025-05-09 01:39:15 -07:00
parent ae55e97c18
commit 6ada92e6f5
3 changed files with 46 additions and 30 deletions

View file

@ -5,4 +5,6 @@ Most code we care about lives in src/vs/workbench/contrib/void.
You may often need to explore the full repo to find relevant parts of code.
Look for services and built-in functions that you might need to use to solve the problem.
NEVER lazily cast to 'any' in typescript. Find the correct type to apply and use it.
In typescript, do NOT cast to types if not neccessary. NEVER lazily cast to 'any'. Find the correct type to apply and use it.
Do not add or remove semicolons to any of my files. Just go with convention and make the least number of changes.

View file

@ -1788,6 +1788,10 @@ const CommandTool = ({ toolMessage, type, threadId }: { threadId: string } & ({
if (type === 'run_command') msg = toolsService.stringOfResult['run_command'](toolMessage.params, result)
else msg = toolsService.stringOfResult['run_persistent_command'](toolMessage.params, result)
if (type === 'run_persistent_command') {
componentParams.info = persistentTerminalNameOfId(toolMessage.params.persistentTerminalId)
}
componentParams.children = <ToolChildrenWrapper className='whitespace-pre text-nowrap overflow-auto text-sm'>
<div className='!select-text cursor-auto'>
<BlockCode initValue={`${msg.trim()}`} language='shellscript' />
@ -1803,7 +1807,8 @@ const CommandTool = ({ toolMessage, type, threadId }: { threadId: string } & ({
</BottomChildren>
}
else if (toolMessage.type === 'running_now') {
componentParams.children = <div ref={divRef} className='relative h-[300px] text-sm' />
if (type === 'run_command')
componentParams.children = <div ref={divRef} className='relative h-[300px] text-sm' />
}
else if (toolMessage.type === 'rejected' || toolMessage.type === 'tool_request') {
}
@ -2290,7 +2295,9 @@ const toolNameToComponent: { [T in ToolName]: { resultWrapper: ResultWrapper<T>,
const { rawParams, params } = toolMessage
const componentParams: ToolHeaderParams = { title, desc1, desc1Info, isError, icon, isRejected, }
componentParams.info = params.cwd ? `Running in ${getRelative(URI.file(params.cwd), accessor)}` : ''
const relativePath = params.cwd ? getRelative(URI.file(params.cwd), accessor) : ''
componentParams.info = relativePath ? `Running in ${relativePath}` : undefined
if (toolMessage.type === 'success') {
const { result } = toolMessage
const { persistentTerminalId } = result

View file

@ -26,9 +26,10 @@ export interface ITerminalToolService {
focusPersistentTerminal(terminalId: string): Promise<void>
persistentTerminalExists(terminalId: string): boolean
readTerminal(terminalId: string): Promise<string>
createPersistentTerminal(opts: { cwd: string | null }): Promise<string>
killPersistentTerminal(terminalId: string): Promise<void>
// readTerminal(terminalId: string): Promise<string>
getPersistentTerminal(terminalId: string): ITerminalInstance | undefined
getTemporaryTerminal(terminalId: string): ITerminalInstance | undefined
@ -201,33 +202,33 @@ export class TerminalToolService extends Disposable implements ITerminalToolServ
// readTerminal: ITerminalToolService['readTerminal'] = async (terminalId) => {
// // Try persistent first, then temporary
// const terminal = this.getPersistentTerminal(terminalId) ?? this.getTemporaryTerminal(terminalId);
// if (!terminal) {
// throw new Error(`Read Terminal: Terminal with ID ${terminalId} does not exist.`);
// }
readTerminal: ITerminalToolService['readTerminal'] = async (terminalId) => {
// Try persistent first, then temporary
const terminal = this.getPersistentTerminal(terminalId) ?? this.getTemporaryTerminal(terminalId);
if (!terminal) {
throw new Error(`Read Terminal: Terminal with ID ${terminalId} does not exist.`);
}
// // Ensure the xterm.js instance has been created otherwise we cannot access the buffer.
// if (!terminal.xterm) {
// throw new Error('Read Terminal: The requested terminal has not yet been rendered and therefore has no scrollback buffer available.');
// }
// Ensure the xterm.js instance has been created otherwise we cannot access the buffer.
if (!terminal.xterm) {
throw new Error('Read Terminal: The requested terminal has not yet been rendered and therefore has no scrollback buffer available.');
}
// // Collect lines from the buffer iterator (oldest to newest)
// const lines: string[] = [];
// for (const line of terminal.xterm.getBufferReverseIterator()) {
// lines.unshift(line);
// }
// Collect lines from the buffer iterator (oldest to newest)
const lines: string[] = [];
for (const line of terminal.xterm.getBufferReverseIterator()) {
lines.unshift(line);
}
// let result = removeAnsiEscapeCodes(lines.join('\n'));
let result = removeAnsiEscapeCodes(lines.join('\n'));
// if (result.length > MAX_TERMINAL_CHARS) {
// const half = MAX_TERMINAL_CHARS / 2;
// result = result.slice(0, half) + '\n...\n' + result.slice(result.length - half);
// }
if (result.length > MAX_TERMINAL_CHARS) {
const half = MAX_TERMINAL_CHARS / 2;
result = result.slice(0, half) + '\n...\n' + result.slice(result.length - half);
}
// return result;
// };
return result
};
private async _waitForCommandDetectionCapability(terminal: ITerminalInstance) {
const cmdCap = terminal.capabilities.get(TerminalCapability.CommandDetection);
@ -249,14 +250,14 @@ export class TerminalToolService extends Disposable implements ITerminalToolServ
}
runCommand: ITerminalToolService['runCommand'] = async (command, params) => {
const { type } = params
await this.terminalService.whenConnected;
const { type } = params
const isPersistent = type === 'persistent'
let terminal: ITerminalInstance
const disposables: IDisposable[] = []
const isPersistent = type === 'persistent'
if (isPersistent) { // BG process
const { persistentTerminalId } = params
terminal = this.persistentTerminalInstanceOfId[persistentTerminalId];
@ -281,7 +282,7 @@ export class TerminalToolService extends Disposable implements ITerminalToolServ
await this.terminalService.focusActiveInstance()
}
let result: string = ''
let resolveReason: TerminalResolveReason | undefined = undefined
let resolveReason: TerminalResolveReason | undefined
const cmdCap = await this._waitForCommandDetectionCapability(terminal)
@ -340,6 +341,12 @@ export class TerminalToolService extends Disposable implements ITerminalToolServ
if (!resolveReason) throw new Error('Unexpected internal error: Promise.any should have resolved with a reason.')
// read result if timed out, since we didn't get it (could clean this code up but it's ok)
if (resolveReason.type === 'timeout') {
const terminalId = isPersistent ? params.persistentTerminalId : params.terminalId
result = await this.readTerminal(terminalId)
}
result = removeAnsiEscapeCodes(result)
if (result.length > MAX_TERMINAL_CHARS) {