Fixup: allow thinking before fixing

This commit is contained in:
Enrico Ros
2024-09-27 12:43:45 -07:00
parent 3d566aa102
commit cdd08b5df3
3 changed files with 21 additions and 17 deletions
@@ -50,7 +50,7 @@ Analyze the provided content to determine its nature, identify any relationships
fragments: attachmentFragments,
}, {
role: 'user',
fragments: [createTextContentFragment(`Call the function once, filling in order the attachments, the relationships between them, the top ${num_suggestions} orthogonal actions you inferred and the single modst valuable action.`)],
fragments: [createTextContentFragment(`Call the function once, filling in order the attachments, the relationships between them, the top ${num_suggestions} orthogonal actions you inferred and the single most valuable action.`)],
}])).chatSequence,
tools: [
aixFunctionCallTool({
@@ -71,7 +71,7 @@ Analyze the provided content to determine its nature, identify any relationships
);
// extract the function call
const { argsObject } = aixRequireSingleFunctionCallInvocation(fragments, 'propose_user_actions_for_attachments', 'agiAttachmentPrompts');
const { argsObject } = aixRequireSingleFunctionCallInvocation(fragments, 'propose_user_actions_for_attachments', false, 'agiAttachmentPrompts');
const args = inputSchema.parse(argsObject);
if (!args.top_orthogonal_user_actions?.length)
+13 -10
View File
@@ -16,6 +16,7 @@ interface CodeFix {
systemMessage: string;
userInstructionTemplate: string; // Template with placeholders for `codeToFix` and `errorString`
functionName: string;
functionPolicy: 'invoke' | 'think-then-invoke';
outputSchema: ZodObject<any>;
}
@@ -23,21 +24,21 @@ const CodeFixes: Record<string, CodeFix> = {
// See `RenderCodeChartJS`
'chartjs-issue': {
description: 'Provides the corrected ChartJS configuration code.',
systemMessage: `You are an AI assistant that helps fix invalid ChartJS configuration JSON code.
When provided with invalid ChartJS code, you analyze it, identify errors, and output a corrected version in valid JSON format.
Respond only by calling the \`{{functionName}}\` function.`,
userInstructionTemplate: `The following ChartJS configuration code is invalid and cannot be parsed:
description: 'Provides the corrected Chart.js configuration code.',
systemMessage: `You are an AI assistant that fixes invalid Chart.js configuration JSON.
When provided with invalid Chart.js code, you analyze it, identify errors, especially remove all functions if any, and output a corrected version in valid JSON format.
Respond first with a very brief analysis of where the error is and exactly what to change, and then call the \`{{functionName}}\` function.`,
userInstructionTemplate: `The following Chart.js ChartOptions JSON is invalid and cannot be parsed:
\`\`\`json
{{codeToFix}}
\`\`\`
{{errorMessageSection}}
Please analyze the JSON, correct any errors (of course remove functions if any), and provide a valid JSON configuration that can be parsed by ChartJS.
Call the function \`{{functionName}}\` once, providing the corrected code.`,
Please analyze the JSON, correct any errors (REMOVE FUNCTIONS!!!), and provide a valid JSON-only ChartOptions that can be parsed by Chart.js.`,
functionName: 'provide_corrected_chartjs_code',
functionPolicy: 'think-then-invoke',
outputSchema: z.object({
corrected_code: z.string().describe('The corrected ChartJS configuration code in valid JSON format.'),
corrected_code: z.string().describe('The corrected Chart.js ChartOptions in valid JSON format.'),
}),
},
@@ -77,7 +78,9 @@ export async function agiFixupCode(issueType: CodeFixType, codeToFix: string, er
inputSchema: config.outputSchema,
}),
],
toolsPolicy: { type: 'function_call', function_call: { name: config.functionName } },
toolsPolicy:
config.functionPolicy === 'invoke' ? { type: 'function_call', function_call: { name: config.functionName } }
: config.functionPolicy === 'think-then-invoke' ? { type: 'auto' } : undefined,
};
// Invoke the AI model
@@ -90,7 +93,7 @@ export async function agiFixupCode(issueType: CodeFixType, codeToFix: string, er
);
// Validate and parse the AI's response
const { argsObject } = aixRequireSingleFunctionCallInvocation(fragments, config.functionName, issueType);
const { argsObject } = aixRequireSingleFunctionCallInvocation(fragments, config.functionName, config.functionPolicy === 'think-then-invoke', issueType);
const argsZod = config.outputSchema.parse(argsObject);
// Return the corrected code
@@ -62,24 +62,25 @@ function _recursiveObjectSchemaCleanup(obj: Record<string, any>, thisKey?: strin
/** Extract the function name from the Aix FunctionCall Tool Definition */
export function aixRequireSingleFunctionCallInvocation(fragments: DMessageContentFragment[], expectedFunctionName: string, debugLabel: string): {
export function aixRequireSingleFunctionCallInvocation(fragments: DMessageContentFragment[], expectedFunctionName: string, allowThinkPart: boolean, debugLabel: string): {
invocation: Extract<DMessageToolInvocationPart['invocation'], { type: 'function_call' }>;
argsObject: object;
} {
if (!Array.isArray(fragments) || fragments.length !== 1) {
if (!Array.isArray(fragments) || !(fragments.length >= 1)) {
if (AIX_DEBUG_CLIENT_TOOLS)
console.error('[DEV] single-function-call: invalid fragments:', fragments, 'for', debugLabel);
throw new Error('AIX: Unexpected response.');
}
if (!isContentFragment(fragments[0]) || fragments[0].part.pt !== 'tool_invocation') {
const toolIdx = allowThinkPart ? fragments.length - 1 : 0;
if (!isContentFragment(fragments[toolIdx]) || fragments[toolIdx].part.pt !== 'tool_invocation') {
if (AIX_DEBUG_CLIENT_TOOLS)
console.error('[DEV] single-function-call: invalid fragment part:', fragments[0].part, 'for', debugLabel);
console.error('[DEV] single-function-call: invalid fragment part:', fragments[toolIdx].part, 'for', debugLabel);
throw new Error('AIX: Missing tool invocation.');
}
const { invocation } = fragments[0].part;
const { invocation } = fragments[toolIdx].part;
if (invocation.type !== 'function_call' || invocation.name !== expectedFunctionName) {
if (AIX_DEBUG_CLIENT_TOOLS)