mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-01-14 12:59:16 +00:00
Compare commits
1 Commits
v0.7.1
...
fix/nonint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cb4371373 |
@@ -1826,7 +1826,7 @@ describe('runNonInteractive', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should print tool output to console in text mode (non-Task tools)', async () => {
|
||||
it('should print tool description and output to console in text mode (non-Task tools)', async () => {
|
||||
// Test that tool output is printed to stdout in text mode
|
||||
const toolCallEvent: ServerGeminiStreamEvent = {
|
||||
type: GeminiEventType.ToolCallRequest,
|
||||
@@ -1839,6 +1839,21 @@ describe('runNonInteractive', () => {
|
||||
},
|
||||
};
|
||||
|
||||
// Mock the tool registry to return a tool with displayName and build method
|
||||
const mockTool = {
|
||||
displayName: 'Shell',
|
||||
build: (args: Record<string, unknown>) => {
|
||||
// @ts-expect-error - accessing indexed property for test mock
|
||||
const command: string = args.command || '';
|
||||
return {
|
||||
getDescription: () => String(command),
|
||||
};
|
||||
},
|
||||
};
|
||||
vi.mocked(mockToolRegistry.getTool).mockReturnValue(
|
||||
mockTool as unknown as ReturnType<typeof mockToolRegistry.getTool>,
|
||||
);
|
||||
|
||||
// Mock tool execution with outputUpdateHandler being called
|
||||
mockCoreExecuteToolCall.mockImplementation(
|
||||
async (_config, _request, _signal, options) => {
|
||||
@@ -1901,8 +1916,15 @@ describe('runNonInteractive', () => {
|
||||
);
|
||||
|
||||
// Verify tool output was written to stdout
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('Package outdated\n');
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('npm@1.0.0 -> npm@2.0.0\n');
|
||||
// First call should be tool description
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('Shell: npm outdated');
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('\n');
|
||||
// Then the actual tool output
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('Package outdated');
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('npm@1.0.0 -> npm@2.0.0');
|
||||
// Final newline after tool execution
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('\n');
|
||||
// And the model's response
|
||||
expect(processStdoutSpy).toHaveBeenCalledWith('Dependencies checked');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -351,19 +351,51 @@ export async function runNonInteractive(
|
||||
const taskToolProgressHandler = taskToolProgress?.handler;
|
||||
|
||||
// Create output handler for non-Task tools in text mode (for console output)
|
||||
const toolOutputLines: string[] = [];
|
||||
const nonTaskOutputHandler =
|
||||
!isTaskTool && !adapter
|
||||
? (callId: string, outputChunk: ToolResultDisplay) => {
|
||||
const toolRegistry = config.getToolRegistry();
|
||||
const tool = toolRegistry.getTool(finalRequestInfo.name);
|
||||
if (tool) {
|
||||
try {
|
||||
const invocation = tool.build(finalRequestInfo.args);
|
||||
const description = invocation.getDescription();
|
||||
toolOutputLines.push(
|
||||
`${tool.displayName}: ${description}`,
|
||||
);
|
||||
toolOutputLines.push('\n');
|
||||
} catch {
|
||||
// If we can't build invocation, just show tool name
|
||||
toolOutputLines.push(`${tool.displayName}`);
|
||||
toolOutputLines.push('\n');
|
||||
}
|
||||
}
|
||||
// Print tool output to console in text mode
|
||||
if (typeof outputChunk === 'string') {
|
||||
process.stdout.write(outputChunk);
|
||||
// Indent output lines to show they're part of the tool execution
|
||||
const lines = outputChunk.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (i === lines.length - 1 && lines[i] === '') {
|
||||
// Skip trailing empty line
|
||||
continue;
|
||||
}
|
||||
toolOutputLines.push(lines[i]);
|
||||
}
|
||||
} else if (
|
||||
outputChunk &&
|
||||
typeof outputChunk === 'object' &&
|
||||
'ansiOutput' in outputChunk
|
||||
) {
|
||||
// Handle ANSI output - just print as string for now
|
||||
process.stdout.write(String(outputChunk.ansiOutput));
|
||||
// Handle ANSI output - indent it similarly
|
||||
const ansiStr = String(outputChunk.ansiOutput);
|
||||
const lines = ansiStr.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (i === lines.length - 1 && lines[i] === '') {
|
||||
continue;
|
||||
}
|
||||
toolOutputLines.push(lines[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
: undefined;
|
||||
@@ -386,6 +418,11 @@ export async function runNonInteractive(
|
||||
: undefined,
|
||||
);
|
||||
|
||||
if (toolOutputLines.length > 0) {
|
||||
toolOutputLines.forEach((line) => process.stdout.write(line));
|
||||
process.stdout.write('\n');
|
||||
}
|
||||
|
||||
// Note: In JSON mode, subagent messages are automatically added to the main
|
||||
// adapter's messages array and will be output together on emitResult()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user