mirror of https://github.com/buster-so/buster.git
refactor: rename respondWithoutAnalysis to respondWithoutAssetCreation
- Updated references across multiple files to reflect the new tool name. - Adjusted unit tests and schemas to ensure compatibility with the renamed tool. - Removed the old respondWithoutAnalysis tool implementation and its associated tests. - Ensured backward compatibility for existing functionality using the old tool name.
This commit is contained in:
parent
7ddc683104
commit
24cfab962d
|
@ -80,7 +80,7 @@ steps/
|
|||
tools/
|
||||
├── communication-tools/ # Agent-to-agent communication
|
||||
│ ├── done-tool.ts
|
||||
│ ├── respond-without-analysis.ts
|
||||
│ ├── respond-without-asset-creation.ts
|
||||
│ └── submit-thoughts-tool.ts
|
||||
├── database-tools/ # Data access
|
||||
│ └── find-required-text-values.ts
|
||||
|
|
|
@ -95,8 +95,8 @@ describe('Format Output Step Unit Tests', () => {
|
|||
],
|
||||
finished: true,
|
||||
metadata: {
|
||||
toolsUsed: ['respondWithoutAnalysis'],
|
||||
finalTool: 'respondWithoutAnalysis',
|
||||
toolsUsed: ['respondWithoutAssetCreation'],
|
||||
finalTool: 'respondWithoutAssetCreation',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -137,11 +137,11 @@ describe('onStepFinish message conversion', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should convert respondWithoutAnalysis to response text messages', async () => {
|
||||
it('should convert respondWithoutAssetCreation to response text messages', async () => {
|
||||
const toolCalls = [
|
||||
{
|
||||
toolCallId: 'respond-1',
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
args: {
|
||||
message: 'Here is a quick answer without analysis',
|
||||
},
|
||||
|
@ -155,7 +155,7 @@ describe('onStepFinish message conversion', () => {
|
|||
{
|
||||
type: 'tool-call',
|
||||
toolCallId: 'respond-1',
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
args: {
|
||||
message: 'Here is a quick answer without analysis',
|
||||
},
|
||||
|
@ -168,7 +168,7 @@ describe('onStepFinish message conversion', () => {
|
|||
{
|
||||
type: 'tool-result',
|
||||
toolCallId: 'respond-1',
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
result: {
|
||||
message: 'Here is a quick answer without analysis',
|
||||
},
|
||||
|
@ -180,13 +180,13 @@ describe('onStepFinish message conversion', () => {
|
|||
const step = createMockStepResult(toolCalls, responseMessages);
|
||||
const toolNames = step.toolCalls.map((call) => call.toolName);
|
||||
|
||||
// Check that respondWithoutAnalysis is a finishing tool
|
||||
// Check that respondWithoutAssetCreation is a finishing tool
|
||||
const hasFinishingTools = toolNames.some((toolName: string) =>
|
||||
['submitThoughts', 'respondWithoutAnalysis'].includes(toolName)
|
||||
['submitThoughts', 'respondWithoutAssetCreation'].includes(toolName)
|
||||
);
|
||||
|
||||
expect(hasFinishingTools).toBe(true);
|
||||
expect(toolNames.includes('respondWithoutAnalysis')).toBe(true);
|
||||
expect(toolNames.includes('respondWithoutAssetCreation')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ const createStepResult = (
|
|||
toolsUsed: getAllToolsUsed(conversationHistory),
|
||||
finalTool: getLastToolUsed(conversationHistory) as
|
||||
| 'submitThoughts'
|
||||
| 'respondWithoutAnalysis'
|
||||
| 'respondWithoutAssetCreation'
|
||||
| 'messageUserClarifyingQuestion'
|
||||
| undefined,
|
||||
text: undefined,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from 'vitest';
|
||||
import { validateArrayAccess } from '../../utils/validation-helpers';
|
||||
import { parseStreamingArgs } from './respond-without-analysis';
|
||||
import { parseStreamingArgs } from './respond-without-asset-creation';
|
||||
|
||||
describe('Respond Without Analysis Tool Streaming Parser', () => {
|
||||
test('should return null for empty or invalid input', () => {
|
|
@ -3,7 +3,7 @@ import { wrapTraced } from 'braintrust';
|
|||
import { z } from 'zod';
|
||||
|
||||
// Input/Output schemas
|
||||
const respondWithoutAnalysisInputSchema = z.object({
|
||||
const respondWithoutAssetCreationInputSchema = z.object({
|
||||
final_response: z
|
||||
.string()
|
||||
.min(1, 'Final response is required')
|
||||
|
@ -13,12 +13,12 @@ const respondWithoutAnalysisInputSchema = z.object({
|
|||
});
|
||||
|
||||
/**
|
||||
* Optimistic parsing function for streaming respond-without-analysis tool arguments
|
||||
* Optimistic parsing function for streaming respond-without-asset-creation tool arguments
|
||||
* Extracts the final_response field as it's being built incrementally
|
||||
*/
|
||||
export function parseStreamingArgs(
|
||||
accumulatedText: string
|
||||
): Partial<z.infer<typeof respondWithoutAnalysisInputSchema>> | null {
|
||||
): Partial<z.infer<typeof respondWithoutAssetCreationInputSchema>> | null {
|
||||
// Validate input type
|
||||
if (typeof accumulatedText !== 'string') {
|
||||
throw new Error(`parseStreamingArgs expects string input, got ${typeof accumulatedText}`);
|
||||
|
@ -63,11 +63,11 @@ export function parseStreamingArgs(
|
|||
}
|
||||
}
|
||||
|
||||
const respondWithoutAnalysisOutputSchema = z.object({});
|
||||
const respondWithoutAssetCreationOutputSchema = z.object({});
|
||||
|
||||
// Process respond without analysis tool execution
|
||||
async function processRespondWithoutAnalysis(): Promise<
|
||||
z.infer<typeof respondWithoutAnalysisOutputSchema>
|
||||
async function processRespondWithoutAssetCreation(): Promise<
|
||||
z.infer<typeof respondWithoutAssetCreationOutputSchema>
|
||||
> {
|
||||
// This tool signals the end of the workflow and provides the final response.
|
||||
// The actual agent termination logic resides elsewhere.
|
||||
|
@ -75,21 +75,21 @@ async function processRespondWithoutAnalysis(): Promise<
|
|||
}
|
||||
|
||||
// Main respond without analysis function with tracing
|
||||
const executeRespondWithoutAnalysis = wrapTraced(
|
||||
async (): Promise<z.infer<typeof respondWithoutAnalysisOutputSchema>> => {
|
||||
return await processRespondWithoutAnalysis();
|
||||
const executeRespondWithoutAssetCreation = wrapTraced(
|
||||
async (): Promise<z.infer<typeof respondWithoutAssetCreationOutputSchema>> => {
|
||||
return await processRespondWithoutAssetCreation();
|
||||
},
|
||||
{ name: 'respond-without-asset-creation' }
|
||||
);
|
||||
|
||||
// Export the tool
|
||||
export const respondWithoutAssetCreation = createTool({
|
||||
id: 'respond-without-analysis',
|
||||
id: 'respond-without-asset-creation',
|
||||
description:
|
||||
"Marks all remaining unfinished tasks as complete, sends a final response to the user, and ends the workflow. Use this when the workflow is finished. This must be in markdown format and not use the '•' bullet character.",
|
||||
inputSchema: respondWithoutAnalysisInputSchema,
|
||||
outputSchema: respondWithoutAnalysisOutputSchema,
|
||||
execute: executeRespondWithoutAnalysis,
|
||||
inputSchema: respondWithoutAssetCreationInputSchema,
|
||||
outputSchema: respondWithoutAssetCreationOutputSchema,
|
||||
execute: executeRespondWithoutAssetCreation,
|
||||
});
|
||||
|
||||
export default respondWithoutAssetCreation;
|
|
@ -1,6 +1,6 @@
|
|||
export { doneTool } from './communication-tools/done-tool';
|
||||
export { idleTool } from './communication-tools/idle-tool';
|
||||
export { respondWithoutAssetCreation } from './communication-tools/respond-without-analysis';
|
||||
export { respondWithoutAssetCreation } from './communication-tools/respond-without-asset-creation';
|
||||
export { submitThoughts } from './communication-tools/submit-thoughts-tool';
|
||||
export { messageUserClarifyingQuestion } from './communication-tools/message-user-clarifying-question';
|
||||
export { sequentialThinking } from './planning-thinking-tools/sequential-thinking-tool';
|
||||
|
|
|
@ -48,7 +48,7 @@ describe('ChunkProcessor', () => {
|
|||
});
|
||||
|
||||
it('should extract response messages with correct field names', async () => {
|
||||
const availableTools = new Set(['doneTool', 'respondWithoutAnalysis']);
|
||||
const availableTools = new Set(['doneTool', 'respondWithoutAssetCreation']);
|
||||
const processor = new ChunkProcessor(mockMessageId, [], [], [], undefined, availableTools);
|
||||
|
||||
// Process doneTool with final_response
|
||||
|
@ -61,11 +61,11 @@ describe('ChunkProcessor', () => {
|
|||
},
|
||||
} as TextStreamPart<ToolSet>);
|
||||
|
||||
// Process respondWithoutAnalysis with final_response
|
||||
// Process respondWithoutAssetCreation with final_response
|
||||
await processor.processChunk({
|
||||
type: 'tool-call',
|
||||
toolCallId: 'respond-1',
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
args: {
|
||||
final_response: 'I cannot analyze this type of data.',
|
||||
},
|
||||
|
|
|
@ -1691,7 +1691,7 @@ export class ChunkProcessor<T extends ToolSet = GenericToolSet> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if a tool is a response tool (doneTool, respondWithoutAnalysis)
|
||||
* Check if a tool is a response tool (doneTool, respondWithoutAssetCreation)
|
||||
*/
|
||||
private isResponseTool(toolName: string): boolean {
|
||||
const responseTools = [
|
||||
|
|
|
@ -186,6 +186,8 @@ function formatMessageAsReasoningEntry(
|
|||
|
||||
case 'doneTool':
|
||||
case 'done-tool':
|
||||
case 'respondWithoutAssetCreation':
|
||||
case 'respond-without-asset-creation':
|
||||
case 'respondWithoutAnalysis':
|
||||
case 'respond-without-analysis':
|
||||
// These are response messages, not reasoning messages
|
||||
|
@ -246,7 +248,7 @@ function formatMessageAsReasoningEntry(
|
|||
return reasoningMessages;
|
||||
}
|
||||
if (toolCalls.length > 0) {
|
||||
// We had tool calls but no reasoning messages (e.g., doneTool, respondWithoutAnalysis)
|
||||
// We had tool calls but no reasoning messages (e.g., doneTool, respondWithoutAssetCreation)
|
||||
// Return null to skip this message
|
||||
return null;
|
||||
}
|
||||
|
@ -407,7 +409,7 @@ export function appendToReasoning(
|
|||
|
||||
/**
|
||||
* Extract response messages from CoreMessages
|
||||
* Specifically looks for doneTool and respondWithoutAnalysis tool calls
|
||||
* Specifically looks for doneTool and respondWithoutAssetCreation tool calls
|
||||
*/
|
||||
export function extractResponseMessages(messages: CoreMessage[]): ChatMessageResponseMessage[] {
|
||||
if (!Array.isArray(messages)) {
|
||||
|
@ -439,8 +441,11 @@ export function extractResponseMessages(messages: CoreMessage[]): ChatMessageRes
|
|||
console.error('Invalid response message:', error, responseMessage);
|
||||
}
|
||||
} else if (
|
||||
// Backwards compatible with respond without anlysis since that was an old tool we used before.
|
||||
toolCall.toolName === 'respondWithoutAnalysis' ||
|
||||
toolCall.toolName === 'respond-without-analysis'
|
||||
toolCall.toolName === 'respond-without-analysis' ||
|
||||
toolCall.toolName === 'respondWithoutAssetCreation' ||
|
||||
toolCall.toolName === 'respond-without-asset-creation'
|
||||
) {
|
||||
const responseMessage: ResponseTextMessage = {
|
||||
id: toolCall.toolCallId,
|
||||
|
|
|
@ -93,9 +93,9 @@ describe('ChunkProcessor - Response Message Streaming', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('respondWithoutAnalysis streaming', () => {
|
||||
describe('respondWithoutAssetCreation streaming', () => {
|
||||
it('should create and update response message as response streams', async () => {
|
||||
const availableTools = new Set(['respondWithoutAnalysis']);
|
||||
const availableTools = new Set(['respondWithoutAssetCreation']);
|
||||
const processor = new ChunkProcessor(null, [], [], [], undefined, availableTools);
|
||||
const toolCallId = 'respond-tool-1';
|
||||
|
||||
|
@ -103,14 +103,14 @@ describe('ChunkProcessor - Response Message Streaming', () => {
|
|||
await processor.processChunk({
|
||||
type: 'tool-call-streaming-start',
|
||||
toolCallId,
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
} as TextStreamPart<never>);
|
||||
|
||||
// Stream partial response
|
||||
await processor.processChunk({
|
||||
type: 'tool-call-delta',
|
||||
toolCallId,
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
argsTextDelta: '{"final_response": "Based on',
|
||||
} as TextStreamPart<never>);
|
||||
|
||||
|
@ -127,7 +127,7 @@ describe('ChunkProcessor - Response Message Streaming', () => {
|
|||
await processor.processChunk({
|
||||
type: 'tool-call-delta',
|
||||
toolCallId,
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
argsTextDelta: ' the analysis"}',
|
||||
} as TextStreamPart<never>);
|
||||
|
||||
|
@ -156,15 +156,15 @@ describe('ChunkProcessor - Response Message Streaming', () => {
|
|||
expect(processor.getReasoningHistory()).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should not create reasoning entries for respondWithoutAnalysis', async () => {
|
||||
const availableTools = new Set(['respondWithoutAnalysis']);
|
||||
it('should not create reasoning entries for respondWithoutAssetCreation', async () => {
|
||||
const availableTools = new Set(['respondWithoutAssetCreation']);
|
||||
const processor = new ChunkProcessor(null, [], [], [], undefined, availableTools);
|
||||
const toolCallId = 'respond-tool-2';
|
||||
|
||||
await processor.processChunk({
|
||||
type: 'tool-call',
|
||||
toolCallId,
|
||||
toolName: 'respondWithoutAnalysis',
|
||||
toolName: 'respondWithoutAssetCreation',
|
||||
args: {
|
||||
final_response: 'Quick response',
|
||||
},
|
||||
|
|
|
@ -53,8 +53,8 @@ describe('message-converters', () => {
|
|||
});
|
||||
|
||||
describe('Respond Without Analysis tool', () => {
|
||||
it('should convert respondWithoutAnalysis to response text message', () => {
|
||||
const toolCall = createToolCall('test-id-3', 'respondWithoutAnalysis', {
|
||||
it('should convert respondWithoutAssetCreation to response text message', () => {
|
||||
const toolCall = createToolCall('test-id-3', 'respondWithoutAssetCreation', {
|
||||
message: 'Quick response',
|
||||
});
|
||||
const toolResult = { message: 'Quick response' };
|
||||
|
|
|
@ -14,7 +14,7 @@ const DoneToolResultSchema = z.object({
|
|||
message: z.string(),
|
||||
});
|
||||
|
||||
const RespondWithoutAnalysisResultSchema = z.object({
|
||||
const RespondWithoutAssetCreationResultSchema = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
|
@ -85,7 +85,7 @@ const ExecuteSqlResultSchema = z.object({
|
|||
// Type for parsed tool results
|
||||
type ParsedToolResult =
|
||||
| z.infer<typeof DoneToolResultSchema>
|
||||
| z.infer<typeof RespondWithoutAnalysisResultSchema>
|
||||
| z.infer<typeof RespondWithoutAssetCreationResultSchema>
|
||||
| z.infer<typeof SequentialThinkingResultSchema>
|
||||
| z.infer<typeof CreateMetricsFileResultSchema>
|
||||
| z.infer<typeof CreateDashboardFileResultSchema>
|
||||
|
@ -133,11 +133,28 @@ export function convertToolCallToMessage(
|
|||
}
|
||||
}
|
||||
|
||||
case 'respondWithoutAssetCreation':
|
||||
case 'respond-without-asset-creation': {
|
||||
// Respond Without Analysis generates a response message
|
||||
try {
|
||||
const parsed = RespondWithoutAssetCreationResultSchema.parse(toolResult);
|
||||
const responseMessage: Extract<ChatMessageResponseMessage, { type: 'text' }> = {
|
||||
id: toolId,
|
||||
type: 'text',
|
||||
message: parsed.message,
|
||||
};
|
||||
return { type: 'response', message: responseMessage };
|
||||
} catch (_error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: Here for backwards compatibility
|
||||
case 'respondWithoutAnalysis':
|
||||
case 'respond-without-analysis': {
|
||||
// Respond Without Analysis generates a response message
|
||||
try {
|
||||
const parsed = RespondWithoutAnalysisResultSchema.parse(toolResult);
|
||||
const parsed = RespondWithoutAssetCreationResultSchema.parse(toolResult);
|
||||
const responseMessage: Extract<ChatMessageResponseMessage, { type: 'text' }> = {
|
||||
id: toolId,
|
||||
type: 'text',
|
||||
|
|
|
@ -239,7 +239,7 @@ export const ThinkAndPrepOutputSchema = z.object({
|
|||
.object({
|
||||
toolsUsed: z.array(z.string()),
|
||||
finalTool: z
|
||||
.enum(['submitThoughts', 'respondWithoutAnalysis', 'messageUserClarifyingQuestion'])
|
||||
.enum(['submitThoughts', 'respondWithoutAssetCreation', 'messageUserClarifyingQuestion'])
|
||||
.optional(),
|
||||
text: z.string().optional(),
|
||||
reasoning: z.string().optional(),
|
||||
|
|
|
@ -36,7 +36,7 @@ Please use one of these tools to continue with your task. Make sure to use the e
|
|||
const pipelineContext = `
|
||||
|
||||
This workflow has two steps:
|
||||
1. think-and-prep mode: Available tools are sequentialThinking, executeSql, respondWithoutAnalysis, submitThoughts, messageUserClarifyingQuestion
|
||||
1. think-and-prep mode: Available tools are sequentialThinking, executeSql, respondWithoutAssetCreation, submitThoughts, messageUserClarifyingQuestion
|
||||
2. analyst mode: Available tools are createMetrics, modifyMetrics, createDashboards, modifyDashboards, doneTool
|
||||
|
||||
You are currently in ${currentStep} mode. Please use one of the tools available in your current mode.
|
||||
|
|
|
@ -54,7 +54,7 @@ interface AnalystInputData {
|
|||
conversationHistory: CoreMessage[];
|
||||
metadata: {
|
||||
toolsUsed: string[];
|
||||
finalTool?: 'submitThoughts' | 'respondWithoutAnalysis' | undefined;
|
||||
finalTool?: 'submitThoughts' | 'respondWithoutAssetCreation' | undefined;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from 'vitest';
|
||||
import { parseStreamingArgs as parseDoneArgs } from '../../tools/communication-tools/done-tool';
|
||||
import { parseStreamingArgs as parseRespondWithoutAnalysisArgs } from '../../tools/communication-tools/respond-without-analysis';
|
||||
import { parseStreamingArgs as parseRespondWithoutAssetCreationArgs } from '../../tools/communication-tools/respond-without-asset-creation';
|
||||
import { parseStreamingArgs as parseExecuteSqlArgs } from '../../tools/database-tools/execute-sql';
|
||||
import { parseStreamingArgs as parseSequentialArgs } from '../../tools/planning-thinking-tools/sequential-thinking-tool';
|
||||
import { parseStreamingArgs as parseCreateMetricsArgs } from '../../tools/visualization-tools/create-metrics-file-tool';
|
||||
|
@ -8,7 +8,7 @@ import { parseStreamingArgs as parseCreateMetricsArgs } from '../../tools/visual
|
|||
describe('Streaming Parser Error Handling', () => {
|
||||
const parsers = [
|
||||
{ name: 'done-tool', parser: parseDoneArgs },
|
||||
{ name: 'respond-without-analysis', parser: parseRespondWithoutAnalysisArgs },
|
||||
{ name: 'respond-without-asset-creation', parser: parseRespondWithoutAssetCreationArgs },
|
||||
{ name: 'sequential-thinking', parser: parseSequentialArgs },
|
||||
{ name: 'execute-sql', parser: parseExecuteSqlArgs },
|
||||
{ name: 'create-metrics-file', parser: parseCreateMetricsArgs },
|
||||
|
@ -82,9 +82,9 @@ describe('Streaming Parser Error Handling', () => {
|
|||
expect(result).toEqual({ final_response: 'Test response' });
|
||||
});
|
||||
|
||||
test('respond-without-analysis should parse valid complete JSON', () => {
|
||||
test('respond-without-asset-creation should parse valid complete JSON', () => {
|
||||
const validJson = '{"final_response": "Test response"}';
|
||||
const result = parseRespondWithoutAnalysisArgs(validJson);
|
||||
const result = parseRespondWithoutAssetCreationArgs(validJson);
|
||||
expect(result).toEqual({ final_response: 'Test response' });
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue