diff --git a/docs/src/content/docs/blog/drafts/makeitbetter.md b/docs/src/content/docs/blog/drafts/makeitbetter.md new file mode 100644 index 0000000000..df5085d892 --- /dev/null +++ b/docs/src/content/docs/blog/drafts/makeitbetter.md @@ -0,0 +1,57 @@ +--- +title: "Improve Your Code Twice with GenAI 🛠️" +authors: genaiscript +date: 2025-01-28 +draft: true +tags: ["genai", "code improvement", "automation"] +canonical_url: https://microsoft.github.io/genaiscript/blog/improve-your-code-twice-with-genai +--- + +## Introduction + +Have you ever wished to improve your code automatically? This script uses GenAI to enhance your code by running a specific function twice. You can view the script [here](https://github.com/microsoft/genaiscript/blob/main/packages/sample/genaisrc/makeitbetter.genai.mjs). + +## Motivation + +The goal of this script is to leverage artificial intelligence to analyze and enhance your code without manual intervention. It's like having a smart assistant that can refine your work effortlessly. + +## Code Explanation + +Let's walk through the script line by line: + +```js +import { makeItBetter } from "genaiscript/runtime" +``` +This line imports the `makeItBetter` function from the GenAIScript runtime. This function is used to improve code by repeating a set of instructions multiple times. + +```js +def("CODE", env.files) +``` +This line defines a constant named "CODE" that represents the files in the environment. It essentially sets up the context for the code that needs improvement. + +```js +$`Analyze and improve the code.` +``` +This line is a prompt for the AI model. It instructs the system to analyze and enhance the code. The `$` is used to denote that this is a special instruction, not a regular code command. + +```js +// tell the LLM to 'make it better' 2 times +``` +This comment explains the upcoming line of code, making it clear that the `makeItBetter` function will be called twice. + +```js +makeItBetter({ repeat: 2 }) +``` +This line calls the `makeItBetter` function with an option to repeat the improvement process twice. It triggers the enhancement process. + +## How to Run the Script + +To run this script using the GenAIScript CLI, you need to execute the following command in your terminal: + +```bash +genaiscript run makeitbetter +``` + +For detailed instructions on installing and setting up the GenAIScript CLI, check out the [GenAIScript documentation](https://microsoft.github.io/genaiscript/getting-started). + +By following these simple steps, you can harness AI to make your code better with ease! 🌟 diff --git a/docs/src/content/docs/guides/make-it-better.mdx b/docs/src/content/docs/guides/make-it-better.mdx new file mode 100644 index 0000000000..738c3c5c6c --- /dev/null +++ b/docs/src/content/docs/guides/make-it-better.mdx @@ -0,0 +1,54 @@ +--- +title: "Make It Better" +sidebar: + order: 100 +--- + +Surprising results happen when you repeatidely ask the LLM to "make it better" (see [blog post](https://minimaxir.com/2025/01/write-better-code/)). + +In this sample, we use the `makeItBetter` function from the `genaiscript/runtime` +to acheive exaclty that: asking the LLM to make it better for a few rounds. + +## Code Explanation + +Let's walk through the script line by line: + +```js +import { makeItBetter } from "genaiscript/runtime" +``` + +This line imports the `makeItBetter` function from the GenAIScript runtime. This function is used to improve code by repeating a set of instructions multiple times. + +```js +def("CODE", env.files) +``` + +This line defines a constant named "CODE" that represents the files in the environment. It essentially sets up the context for the code that needs improvement. + +```js +$`Analyze and improve the code.` +``` + +This line is a prompt for the AI model. It instructs the system to analyze and enhance the code. The `$` is used to denote that this is a special instruction, not a regular code command. + +```js +makeItBetter({ repeat: 2 }) +``` + +This line calls the `makeItBetter` function with an option to repeat the improvement process twice. It registers a [chat participant](/genaiscript/reference/scripts/chat-participants) +that injects messages in the chat conversation loop. + +The `makeItBetter` rouhgly looks like this. It registers a callback function that gets called +on every chat turn. + +```js +export function makeItBetter(options?: { repeat: ... }) { + let round = 0 + defChatParticipant((cctx) => { + if (round++ < repeat) { + cctx.console.log(`make it better (round ${round})`) + cctx.$`make it better` + } + }) +} +``` diff --git a/packages/cli/src/runtime.ts b/packages/cli/src/runtime.ts index 02791c90be..35f3937abe 100644 --- a/packages/cli/src/runtime.ts +++ b/packages/cli/src/runtime.ts @@ -10,6 +10,13 @@ import { pipeline } from "@huggingface/transformers" // symbols exported as is export { delay, uniq, uniqBy, z, pipeline, chunk, groupBy } +/** + * Options for classifying data. + * + * @property {boolean} [other] - Inject a 'other' label. + * @property {boolean} [explanations] - Explain answers before returning token. + * @property {ChatGenerationContext} [ctx] - Options runPrompt context. + */ export type ClassifyOptions = { /** * Inject a 'other' label @@ -141,3 +148,29 @@ no logprobs, } } + + +/** + * Enhances the provided context by repeating a set of instructions a specified number of times. + * + * @param options - Configuration options for the function. + * @param options.ctx - The chat generation context to be used. If not provided, defaults to `env.generator`. + * @param options.repeat - The number of times to repeat the instructions. Defaults to 1. + * @param options.instructions - The instructions to be executed in each round. Defaults to "Make it better!". + */ +export function makeItBetter(options?: { + ctx?: ChatGenerationContext + repeat?: number + instructions?: string +}) { + const { repeat = 1, instructions = "Make it better!" } = options || {} + const ctx = options?.ctx || env.generator + + let round = 0 + ctx.defChatParticipant((cctx) => { + if (round++ < repeat) { + cctx.console.log(`make it better (round ${round})`) + cctx.$`${instructions}` + } + }) +} diff --git a/packages/core/src/genaisrc/system.files.genai.js b/packages/core/src/genaisrc/system.files.genai.js index 9d3d1e26e2..ada1501b34 100644 --- a/packages/core/src/genaisrc/system.files.genai.js +++ b/packages/core/src/genaisrc/system.files.genai.js @@ -9,26 +9,26 @@ $`## FILE file format When generating, saving or updating files you should use the FILE file syntax preferably: File ${folder}/file1.ts: -\`\`\`typescript +\`\`\`\`typescript What goes in\n${folder}/file1.ts. -\`\`\` +\`\`\`\` File ${folder}/file1.js: -\`\`\`javascript +\`\`\`\`javascript What goes in\n${folder}/file1.js. -\`\`\` +\`\`\`\` File ${folder}/file1.py: -\`\`\`python +\`\`\`\`python What goes in\n${folder}/file1.py. -\`\`\` +\`\`\`\` File /path/to/file/file2.md: -\`\`\`markdown +\`\`\`\`markdown What goes in\n/path/to/file/file2.md. -\`\`\` +\`\`\`\` ` $`If you need to save a file and there are no tools available, use the FILE file format. The output of the LLM will parsed @@ -36,18 +36,18 @@ and saved. It is important to use the proper syntax.` $`You MUST specify a start_line and end_line to only update a specific part of a file: FILE ${folder}/file1.py: -\`\`\`python start_line=15 end_line=20 +\`\`\`\`python start_line=15 end_line=20 Replace line range 15-20 in \n${folder}/file1.py -\`\`\` +\`\`\`\` FILE ${folder}/file1.py: -\`\`\`python start_line=30 end_line=35 +\`\`\`\`python start_line=30 end_line=35 Replace line range 30-35 in \n${folder}/file1.py -\`\`\` +\`\`\`\` ` -$`- Make sure to use precisely \`\`\` to guard file code sections. +$`- Make sure to use precisely \`\`\`\` to guard file code sections. - Always sure to use precisely \`\`\`\`\` to guard file markdown sections. - Use full path of filename in code section header. - Use start_line, end_line for large files with small updates` diff --git a/packages/sample/genaisrc/blogify-sample.genai.mjs b/packages/sample/genaisrc/blogify-sample.genai.mjs index bf5ff0f9b6..02bc50174d 100644 --- a/packages/sample/genaisrc/blogify-sample.genai.mjs +++ b/packages/sample/genaisrc/blogify-sample.genai.mjs @@ -22,6 +22,7 @@ $`Create a blog post file that explains the GenAIScript source code in FILE. - explain the script code line by line as if you were writing the script from scratch. Assume the reader is a beginner. Show the code being explained. Also explain prompts ($\`...\` line by line) - explain all the code, don't skip any line. this is important - add a section that explains how to run the script with the genaiscript cli. Do not explain how to install the cli, link to the documentation instead. +- be minimalistic, avoid jargon, use simple words # Format @@ -41,13 +42,16 @@ $`Create a blog post file that explains the GenAIScript source code in FILE. - do NOT repeat page title in markdown content - save generate text to blog post drafts folder - ignore existing blog posts -- avoid using "delve" +- avoid using "delve", "streamline" - do not repeat or explain the script file top comment - include canonical_url to genaiscript blog at https://microsoft.github.io/genaiscript/blog/ - use language "ts" for mts snippets and "js" for mjs snippets - use markdown headers starting from level 2 - use lowercase characters, dashes for filenames - when invoking the CLI, prefer using the script filename instead of the full path : "genaiscript run " +- if the script imports code from "genaiscript/runtime", explain what those imports do. The source is in file packages/cli/src/runtime.ts +- make sure to generate a filename for the blog post. The filename should be the same as the script filename without the "genai" extension. For example, if the script filename is "makeitbetter.genai.mjs", the blog post filename should be "makeitbetter.md" + # File information diff --git a/packages/sample/genaisrc/makeitbetter.genai.mjs b/packages/sample/genaisrc/makeitbetter.genai.mjs index 5e4776f19e..dda8e7c92d 100644 --- a/packages/sample/genaisrc/makeitbetter.genai.mjs +++ b/packages/sample/genaisrc/makeitbetter.genai.mjs @@ -1,15 +1,5 @@ -script({ - files: "src/fib.ts", - model: "small", - tests: { - files: "src/fib.ts", - }, -}) +import { makeItBetter } from "genaiscript/runtime" def("CODE", env.files) $`Analyze and improve the code.` -defChatParticipant((ctx, messages) => { - if (messages.length < 6) - ctx.$`Make it better. - If you cannot make it better, - respond with DONE and the final version of the code.` -}) +// tell the LLM to 'make it better' 2 times +makeItBetter({ repeat: 2 })