From 3d857d93f1bdbcfe4142a30230ccc4d0e47b80e6 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Tue, 15 Oct 2024 19:50:19 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Refactor=20DIFF=20format=20and?= =?UTF-8?q?=20add=20credit=20card=20gen=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/docs/reference/scripts/system.mdx | 39 +++++++++--- .../core/src/genaisrc/system.diff.genai.js | 39 +++++++++--- packages/core/src/promptrunner.ts | 6 ++ packages/sample/src/edits/bigfibs/fib.js | 59 +++++++++++++++++++ packages/sample/src/edits/bigfibs/fib.py | 51 ++++++++++++++++ packages/sample/src/edits/bigfibs/fib.ts | 59 +++++++++++++++++++ .../sample/src/edits/edits_diff.genai.mts | 11 +++- .../sample/src/edits/edits_files.genai.mts | 11 +++- .../src/edits/edits_files_diff.genai.mts | 11 +++- packages/sample/src/edits/editsgen.genai.mjs | 2 +- packages/sample/src/edits/fileedittest.mts | 7 ++- 11 files changed, 267 insertions(+), 28 deletions(-) create mode 100644 packages/sample/src/edits/bigfibs/fib.js create mode 100644 packages/sample/src/edits/bigfibs/fib.py create mode 100644 packages/sample/src/edits/bigfibs/fib.ts diff --git a/docs/src/content/docs/reference/scripts/system.mdx b/docs/src/content/docs/reference/scripts/system.mdx index 7b249670a7..19e9c897fb 100644 --- a/docs/src/content/docs/reference/scripts/system.mdx +++ b/docs/src/content/docs/reference/scripts/system.mdx @@ -588,13 +588,19 @@ system({ lineNumbers: true, }) -$`The DIFF format should be used to generate diff changes on files: +$`## DIFF file format -- added lines MUST start with + -- deleted lines MUST start with - +The DIFF format should be used to generate diff changes on large files: + +- existing lines must start with their original line number: [] +- deleted lines MUST start with - followed by the line number: - [] +- added lines MUST start with +, no line number: + - deleted lines MUST exist in the original file (do not invent deleted lines) - added lines MUST not exist in the original file +### Guidance: + +- each line in the source starts with a line number: [line] - preserve indentation - use relative file path name - emit original line numbers from existing lines and deleted lines @@ -602,20 +608,24 @@ $`The DIFF format should be used to generate diff changes on files: - only emit a couple unmodified lines before and after the changes - keep the diffs AS SMALL AS POSSIBLE - when reading files, ask for line numbers - +- minimize the number of unmodified lines - do NOT generate diff for files that have no changes - do NOT emit diff if lines are the same - do NOT emit the whole file content - do NOT emit line numbers for added lines +- do NOT use <, > or --- in the diff syntax +- Use one DIFF section per change. + +### Examples: + +FOLLOW THE SYNTAX PRECISLY. THIS IS IMPORTANT. DIFF ./file.ts: \`\`\`diff [original line number] <2 lines before changes (not the whole file)> - [original line number] -- [original line number] + -+ [original line number] <2 lines after changes (not the whole file)> \`\`\` @@ -628,9 +638,22 @@ DIFF ./file2.ts: + [original line number] <2 lines after changes (not the whole file)> \`\`\` -` -$`Do not generate anything else than DIFF sections. Use one DIFF section per change.` +DIFF ./file3.ts: +\`\`\`diff +[original line number] <2 lines before changes (not the whole file)> ++ +[original line number] <2 lines after changes (not the whole file)> +\`\`\` + +DIFF ./file4.ts: +\`\`\`diff +[original line number] <2 lines before changes (not the whole file)> +- [original line number] +[original line number] <2 lines after changes (not the whole file)> +\`\`\` + +` ````` diff --git a/packages/core/src/genaisrc/system.diff.genai.js b/packages/core/src/genaisrc/system.diff.genai.js index 5ea4781ce1..1fd11966ca 100644 --- a/packages/core/src/genaisrc/system.diff.genai.js +++ b/packages/core/src/genaisrc/system.diff.genai.js @@ -3,13 +3,19 @@ system({ lineNumbers: true, }) -$`The DIFF format should be used to generate diff changes on files: +$`## DIFF file format -- added lines MUST start with + -- deleted lines MUST start with - +The DIFF format should be used to generate diff changes on large files: + +- existing lines must start with their original line number: [] +- deleted lines MUST start with - followed by the line number: - [] +- added lines MUST start with +, no line number: + - deleted lines MUST exist in the original file (do not invent deleted lines) - added lines MUST not exist in the original file +### Guidance: + +- each line in the source starts with a line number: [line] - preserve indentation - use relative file path name - emit original line numbers from existing lines and deleted lines @@ -17,20 +23,24 @@ $`The DIFF format should be used to generate diff changes on files: - only emit a couple unmodified lines before and after the changes - keep the diffs AS SMALL AS POSSIBLE - when reading files, ask for line numbers - +- minimize the number of unmodified lines - do NOT generate diff for files that have no changes - do NOT emit diff if lines are the same - do NOT emit the whole file content - do NOT emit line numbers for added lines +- do NOT use <, > or --- in the diff syntax +- Use one DIFF section per change. + +### Examples: + +FOLLOW THE SYNTAX PRECISLY. THIS IS IMPORTANT. DIFF ./file.ts: \`\`\`diff [original line number] <2 lines before changes (not the whole file)> - [original line number] -- [original line number] + -+ [original line number] <2 lines after changes (not the whole file)> \`\`\` @@ -43,6 +53,19 @@ DIFF ./file2.ts: + [original line number] <2 lines after changes (not the whole file)> \`\`\` -` -$`Do not generate anything else than DIFF sections. Use one DIFF section per change.` +DIFF ./file3.ts: +\`\`\`diff +[original line number] <2 lines before changes (not the whole file)> ++ +[original line number] <2 lines after changes (not the whole file)> +\`\`\` + +DIFF ./file4.ts: +\`\`\`diff +[original line number] <2 lines before changes (not the whole file)> +- [original line number] +[original line number] <2 lines after changes (not the whole file)> +\`\`\` + +` diff --git a/packages/core/src/promptrunner.ts b/packages/core/src/promptrunner.ts index 9326041501..bcd14478d1 100644 --- a/packages/core/src/promptrunner.ts +++ b/packages/core/src/promptrunner.ts @@ -229,6 +229,12 @@ export async function runTemplate( // Reporting and tracing output if (fences?.length) trace.details("📩 code regions", renderFencedVariables(fences)) + if (fileEdits && Object.keys(fileEdits).length) { + trace.startDetails("📝 file edits") + for (const [f, e] of Object.entries(fileEdits)) + trace.detailsFenced(f, e.after) + trace.endDetails() + } if (annotations?.length) trace.details( "⚠️ annotations", diff --git a/packages/sample/src/edits/bigfibs/fib.js b/packages/sample/src/edits/bigfibs/fib.js new file mode 100644 index 0000000000..04ba80bf7f --- /dev/null +++ b/packages/sample/src/edits/bigfibs/fib.js @@ -0,0 +1,59 @@ +// Function to generate a credit card number +function generateCreditCardNumber() { + // Define the prefix for Visa cards + const prefix = "400000" + // Define the total length of the credit card number + const length = 16 + // Initialize the card number with the prefix + let cardNumber = prefix + + // Loop until the card number reaches the desired length minus the check digit + while (cardNumber.length < length - 1) { + // Append a random digit to the card number + cardNumber += Math.floor(Math.random() * 10).toString() + } + + // Append the check digit to the card number + cardNumber += getCheckDigit(cardNumber) + // Return the complete card number + return cardNumber +} + +// Function to calculate the check digit using the Luhn algorithm +function getCheckDigit(cardNumber) { + // Initialize the sum to 0 + let sum = 0 + // Flag to determine whether to double the digit or not + let shouldDouble = true + + // Loop through the card number digits from right to left + for (let i = cardNumber.length - 1; i >= 0; i--) { + // Parse the current digit + let digit = parseInt(cardNumber.charAt(i)) + + // If the flag is set, double the digit + if (shouldDouble) { + digit *= 2 + // If the doubled digit is greater than 9, subtract 9 + if (digit > 9) { + digit -= 9 + } + } + + // Add the digit to the sum + sum += digit + // Toggle the flag for the next digit + shouldDouble = !shouldDouble + } + + // Calculate the check digit + const checkDigit = newFunction(sum) + // Return the check digit as a string + return checkDigit.toString() +} + +function newFunction(sum) { + // TODO + return 0 + // return (10 - (sum % 10)) % 10; +} diff --git a/packages/sample/src/edits/bigfibs/fib.py b/packages/sample/src/edits/bigfibs/fib.py new file mode 100644 index 0000000000..df182b68b2 --- /dev/null +++ b/packages/sample/src/edits/bigfibs/fib.py @@ -0,0 +1,51 @@ +# Function to generate a credit card number +def generate_credit_card_number(): + # Define the prefix for Visa cards + prefix = "400000" + # Define the total length of the credit card number + length = 16 + # Initialize the card number with the prefix + card_number = prefix + + # Loop until the card number reaches the desired length minus the check digit + while len(card_number) < length - 1: + # Append a random digit to the card number + card_number += str(random.randint(0, 9)) + + # Append the check digit to the card number + card_number += get_check_digit(card_number) + # Return the complete card number + return card_number + +# Function to calculate the check digit using the Luhn algorithm +def get_check_digit(card_number): + # Initialize the sum to 0 + sum = 0 + # Flag to determine whether to double the digit or not + should_double = True + + # Loop through the card number digits from right to left + for digit in reversed(card_number): + digit = int(digit) + + # If the flag is set, double the digit + if should_double: + digit *= 2 + # If the doubled digit is greater than 9, subtract 9 + if digit > 9: + digit -= 9 + + # Add the digit to the sum + sum += digit + # Toggle the flag for the next digit + should_double = not should_double + + # Calculate the check digit + check_digit = new_function(sum) + # Return the check digit as a string + return str(check_digit) + +def new_function(sum): + # TODO + return 0 + # return (10 - (sum % 10)) % 10; diff --git a/packages/sample/src/edits/bigfibs/fib.ts b/packages/sample/src/edits/bigfibs/fib.ts new file mode 100644 index 0000000000..bac2a9ff59 --- /dev/null +++ b/packages/sample/src/edits/bigfibs/fib.ts @@ -0,0 +1,59 @@ +// Function to generate a credit card number +function generateCreditCardNumber(): string { + // Define the prefix for Visa cards + const prefix = "400000" + // Define the total length of the credit card number + const length = 16 + // Initialize the card number with the prefix + let cardNumber = prefix + + // Loop until the card number reaches the desired length minus the check digit + while (cardNumber.length < length - 1) { + // Append a random digit to the card number + cardNumber += Math.floor(Math.random() * 10).toString() + } + + // Append the check digit to the card number + cardNumber += getCheckDigit(cardNumber) + // Return the complete card number + return cardNumber +} + +// Function to calculate the check digit using the Luhn algorithm +function getCheckDigit(cardNumber: string): string { + // Initialize the sum to 0 + let sum = 0 + // Flag to determine whether to double the digit or not + let shouldDouble = true + + // Loop through the card number digits from right to left + for (let i = cardNumber.length - 1; i >= 0; i--) { + // Parse the current digit + let digit = parseInt(cardNumber.charAt(i)) + + // If the flag is set, double the digit + if (shouldDouble) { + digit *= 2 + // If the doubled digit is greater than 9, subtract 9 + if (digit > 9) { + digit -= 9 + } + } + + // Add the digit to the sum + sum += digit + // Toggle the flag for the next digit + shouldDouble = !shouldDouble + } + + // Calculate the check digit + const checkDigit = newFunction(sum) + // Return the check digit as a string + return checkDigit.toString() +} + +function newFunction(sum: number) { + // TODO + return 0 + // return (10 - (sum % 10)) % 10; +} diff --git a/packages/sample/src/edits/edits_diff.genai.mts b/packages/sample/src/edits/edits_diff.genai.mts index 50196289da..9cf192582d 100644 --- a/packages/sample/src/edits/edits_diff.genai.mts +++ b/packages/sample/src/edits/edits_diff.genai.mts @@ -4,9 +4,14 @@ script({ title: "system.diff test", files: "src/edits/fibs/fib.*", system: ["system", "system.diff"], - tests: { - files: "src/edits/fibs/fib.*", - }, + tests: [ + { + files: "src/edits/fibs/fib.*", + }, + { + files: "src/edits/bigfibs/fib.*", + }, + ], }) editTest() diff --git a/packages/sample/src/edits/edits_files.genai.mts b/packages/sample/src/edits/edits_files.genai.mts index 3e42d92cb1..f39e03dac5 100644 --- a/packages/sample/src/edits/edits_files.genai.mts +++ b/packages/sample/src/edits/edits_files.genai.mts @@ -3,9 +3,14 @@ script({ title: "system.files test", files: "src/edits/fibs/fib.*", system: ["system", "system.files"], - tests: { - files: "src/edits/fibs/fib.*", - }, + tests: [ + { + files: "src/edits/fibs/fib.*", + }, + { + files: "src/edits/bigfibs/fib.*", + }, + ], }) import { editTest } from "./fileedittest.mts" editTest() diff --git a/packages/sample/src/edits/edits_files_diff.genai.mts b/packages/sample/src/edits/edits_files_diff.genai.mts index da2db01e9f..485ad00163 100644 --- a/packages/sample/src/edits/edits_files_diff.genai.mts +++ b/packages/sample/src/edits/edits_files_diff.genai.mts @@ -3,9 +3,14 @@ script({ title: "system.files test", files: "src/edits/fibs/fib.*", system: ["system", "system.files", "system.diff"], - tests: { - files: "src/edits/fibs/fib.*", - }, + tests: [ + { + files: "src/edits/fibs/fib.*", + }, + { + files: "src/edits/bigfibs/fib.*", + }, + ], }) import { editTest } from "./fileedittest.mts" editTest() diff --git a/packages/sample/src/edits/editsgen.genai.mjs b/packages/sample/src/edits/editsgen.genai.mjs index 6b45b27d75..cfd7f872e5 100644 --- a/packages/sample/src/edits/editsgen.genai.mjs +++ b/packages/sample/src/edits/editsgen.genai.mjs @@ -7,4 +7,4 @@ $`Generation 1 variations of the SNIPPET in various programming languages and sa - there should be a function with a TODO comment and a BODY comment ` def("FILE", env.files) -defFileOutput("src/edits/*") +defFileOutput("src/edits/**") diff --git a/packages/sample/src/edits/fileedittest.mts b/packages/sample/src/edits/fileedittest.mts index 44d3d0965e..23eeced6f9 100644 --- a/packages/sample/src/edits/fileedittest.mts +++ b/packages/sample/src/edits/fileedittest.mts @@ -2,7 +2,8 @@ export function editTest() { def("FILE", env.files) $`- Implement the functions with TODO. -- Remove all comments. +- Delete all comments +- Delete all empty lines ` defOutputProcessor((output) => { @@ -11,8 +12,10 @@ export function editTest() { throw new Error("no file edits") for (const [fn, fe] of Object.entries(fileEdits)) { const res = fe.after - if (/^\s*(#|\/\/).*$/.test(res)) + if (/^\s*(#|\/\/).*$/m.test(res)) { + console.log(res) throw new Error(fn + " some comments were not removed") + } if (res.includes("// BODY")) throw new Error(fn + " the // BODY comment was not removed") }