Install the extension
Install the Visual Studio Code +Extension to get started.
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/404.html b/404.html new file mode 100644 index 0000000000..5a4a4ee5f7 --- /dev/null +++ b/404.html @@ -0,0 +1,38 @@ +
Azure Bicep is a Domain Specific Language (DSL) for deploying Azure resources declaratively. +It is a language that is designed to be a more readable +and maintainable way to define Azure resources.
+Bicep comes with a linter that detects various faults, but also comes with +online best practices which are not completely covered by the linter.
+The following is a Bicep file that deploys a web app with a Linux app service plan. +It is the microsoft.web/webapp-basic-linux/main.bicep +sample template in the bicep playground.
+ +The file is linter
clean, but some improvements could be made with best practices.
+The following script will apply best practices to the Bicep file.
#disable-next-line genaiscript
+commentThe LLM generates 3 annotations for the Bicep file. The annotations are surfaced +as squiggly lines in VSCode.
+This is another instance of using the LLM to produce translation of natural strings with an embedded DSL, similarly to the Documentation Translation guide.
+MakeCode uses a microformat to define the shape of coding blocks. +When translating the format strings, it is critical to converse the properties of the blocks, such as the number of arguments, +their types, and the order of the arguments.
+The localization strings for the buzzer library are:
+ +For example, the string for the Jacdac buzzer play tone block
+contains reference to variables (%music
) that should be maintained in the translated string.
and Bing Translate gives us the following translation
+ +As one can see, bing translated the %variable
name which will break the block definition.
The GenAIScript translation is correct.
+ +If you look closely in the script source, you will find guidance in the prompt to properly +handle the variables.
+ +Another challenge with translations is that the localized string often
+contain escaped characters that break formats like JSON or YAML.
+Therefore, we use a custom simple key=value
format
+to encode the strings, to avoid encoding issues.
+We use the defFileMerge
feature to convert the parse key-value file, and merge them with the existing translations.
The language code langCode
is pulled from variables env.vars
or defaulted to de
.
This technique allows to reconfigure these variables from the command line
+using the --vars lang=fr
argument.
The full script is show below.
+ +The result from this script can be inspected +in this pull request.
Microsoft MakeCode is a web-based platform +for creating engaging computer science learning experiences. +It provides a block-based programming environment that allows students +to create games, animations, and interactive stories.
+The MakeCode documentation and tutorials uses markdown with many additional macros +and micro syntaxes +to create rich-rendered tutorials and documentations, like the Rock Paper Scissors tutorial.
+One major challenge in localizing the MakeCode resource is that +tools like Bing Translator or Google Translate had the tendency to destroy the custom macro +annotation; thus breaking the rich rendering of the documentation.
+Let’s illustrate this with the Step 6 of the Rock Paper Scissors tutorial:
+ +In this content, it is critical to keep the ||variables:hand||
+and ||logic:0 = 0||
annotations as they are. And also the blocks
macro should be left untouched.
++Unfortunately, traditional translation system do not have a way to “teach” the syntax or emphasize +the importance of these annotations.
+
For example, when translated to French in Bing Translate, a number of errors are introduced:
+``
becomes '
, extra whitespaces, logic
becomes logique
, and so forth.
GenAIScript allowed to develop and automate a script that create high-quality LLM-based translations +for the MakeCode documentation.
+A (simplified) version of the script is shown below and annotated with comments.
+ +Using this script, the translation of Step 6
to French is as follows, and
+you’ll notice that all the errors have been solved.
Note that we use env.vargs.lang
variable which allows to modify this value through the command line.
Using the genaiscript CLI, we can run the script for each desired language in a GitHub Action.
+ +The CLI can be automated using your favorite bash/script runtime. +For example, using zx, we automate for a number of locales:
+It is a best practice to provide an alt
attribute for images.
+This attribute is used to describe the image to users who are unable to see it.
+It is also used by search engines to understand the content of the image.
However, this task can be tedious and developer are often tempted to skip it, or provide a generic alt
text like “image”.
To solve this issue, we created a script that uses the OpenAI Vision model to analyze the documentation +images and generate a description alt text.
+To start, we assume that the script is run on a single image file +and we use defImage to add it to the prompt context.
+ +Then we give a task to the LLM to generate a good alt text and save in a file.
+ +The GenAIScript documentation uses Astro, which allows to author pages in MDX. +The code below shows how the generate alt text, stored in a separate text file, is injected in the final HTML.
+ +The debugger.png
image shows the screenshot of a debugging session and the generate alt text file contents.
Using the batch command, we can apply the script to all images in the docs +in a single command.
+ +To avoid regenerating the alt text, we also detect if a file exists in the script and cancel accordingly.
+ +The full source looks like this:
+There are plenty of automated release notes
generator
+that inspect the list of commits since the last release and generate a list of changes.
+The release notes are typically exclusively based on the commit messages.
In the GenAIScript projet, we create a release notes generator that uses +both commit history and the diff of the changes.
+You can see one of the first prototype generated +release notes for v1.41.6.
+ +We start our script by calling git
a few times to retreive the previous release tag,
+the list of commits, the diff since the tag.
+(This magic was mostly found using a GitHub Copilot Chat session).
We use the def
function with maxTokens
to inline this information without exceeding the content window
+of the model (32k input).
The rest of the script follows a typical pattern with a role and a task.
+ +The full script as it is running in GenAIScript is as follows:
+ +GenAIScript uses release-it
+to automate the release process. We configured release-it to run the script using the cli
+by adding a github.releaseNotes
field in the release-it
configuration.
Generating and maintaining good SEO front matter fields can be a tedious task. +GenAIScript can help you automate this process.
+The script below will generate SEO information +and update the existing file. The script uses a custom merge strategy +to merge the new front matter with the existing front matter.
+ +Once the script has been tuned on a few files, you can automate using +the CLI. The CLI has a —apply-edits flag to apply the changes to the file.
+ +You can run this command in your CI/CD pipeline to keep your SEO front matter up to date.
+TLA+ is a high-level language for modeling programs and systems—especially +concurrent and distributed ones. It’s based on the idea that the best way to describe things precisely is with simple mathematics.
+TLA+ does not come with a traditional linter or formatter. The TLA+ AI Linter is a GenAI script that uses LLMs to lint TLA+ files.
+The following is a TLA+ spec that models a seminal solution to the termination detection problem in distributed systems.
+ +The following GenAI script will lint the TLA+ spec above. More specifically, it will check if the prose comments in the spec are consistent with the TLA+ definitions.
+ +after cloning the repository and installing dependencies such as node.js, the GenAI script is run to lint the TLA+ specs that were added or modified in the PR.
+the script’s output, i.e., the annotations generated by the LLM, are formatted as a SARIF report and upload to the PR.
+The linter generated annotations for each prose comment in the spec, and one comment is found to be inconsistent with the TLA+ definitions. A corresponding warning is added to the PR.
+What is GenAIScript and how does it work? +GenAIScript is a framework that allows users to create AI-enhanced scripts to automate tasks. It uses simple commands and integrates with AI models to execute tasks based on user-written prompts.
+Who can use GenAIScript and do I need to be a developer? +Anyone can use GenAIScript, including non-developers. It’s designed to be user-friendly, but some basic understanding of scripting or programming can be helpful.
+What are the prerequisites for using GenAIScript? +You’ll need to have VS Code installed to use the GenAIScript extension, and some familiarity with programming concepts is beneficial but not necessary.
+How do I install the GenAIScript framework and its VS Code extension? +The specific installation steps are documented here: Installation
+Do I need to install Node.JS? +Some features like the Command Line or vector databases use Node.JS. To install it, follow the installation instructions.
+Can I use GenAIScript in IDEs other than VS Code? +Currently, GenAIScript is integrated with VS Code, but it can be written in any IDE. The VS Code extension, however, provides additional support for creating and debugging scripts.
+What are foundation models and LLMs in the context of GenAIScript? +Foundation models and LLMs (Large Language Models) are AI models that GenAIScript can interact with to perform tasks like generating text or processing information.
+How do I write my first GenAIScript? +Start by learning the basics of JavaScript and the GenAIScript framework, then use the VS Code extension to create a script that defines the task, calls the LLM, and processes the output. More informatoin is available here: Getting Started
+How do I debug a GenAIScript in VS Code? +Use the GenAIScript extension in VS Code, which provides tools for running, debugging, and tracing the execution of your script. Directions for debugging are here: Debugging
+What are the best practices for authoring effective prompts in GenAIScript? +See Best Practices
+How can I integrate calls to multiple LLM models within a single GenAIScript? +The framework allows you to parameterize calls to different models, so you can include multiple model invocations within your script and manage them accordingly using the runPrompt function documented here: Inline Prompts
+Can GenAIScript generate outputs in formats other than JSON? +Yes, GenAIScript supports multiple output formats, including file edits, JSON, and user-defined schema. More information here: Schemas
+How do I execute a GenAIScript from the command line? +Once you have a GenAIScript packaged, you can run it from the command line like any other script. More information here: Command Line
+Can GenAIScripts take input from files in multiple formats, such as .pdf or .docx? +Yes, the GenAIScript framework has built-in support for reading .pdf and .docx formats. See the documentation pages PDF and DOCX for more information.
+How can I use GenAIScript to automate document translation? +One of our case studies illustrates the use of GenAIScript for translating document fragments between languages: Translation Case Study
+Can I use GenAIScript to summarize documents or create dialogues from monologues? +Yes, LLMs are good at summarizing and can be used within GenAIScript to summarize documents or convert monologues into dialogues.
+What should I do if I encounter errors while running a GenAIScript? +Check the error messages, consult the documentation, and use the debugging tools in the VS Code extension to identify and resolve issues.
+How can I troubleshoot issues with the LLM output parsing in GenAIScript? +Review the prompt and output, ensure your script correctly handles the LLM’s response, and adjust your parsing logic as needed.
+Where can I find examples of GenAIScript to understand its capabilities better? +Visit the GenAIScript GitHub repository for examples and documentation. GenAIScript Documentation
+What are the unintended uses of GenAIScript and how can I avoid them? +Unintended uses include any malicious applications. To avoid them, follow Responsible AI practices and use recommended models with safety features.
+How does GenAIScript align with Responsible AI practices? +GenAIScript encourages the use of models with robust Responsible AI mitigations and provides guidance on secure and ethical usage. +For more information, see the Transparency Note
+What foundation models and LLMs are recommended for use with GenAIScript? +Services like Azure Open AI with updated safety and Responsible AI features are recommended. GenAIScript can also be used with existing open-source LLMs.
+Where can I find the GenAIScript community for discussions and support? +The GenAIScript GitHub repository is a good place to start for community discussions and support. GenAIScript GitHub
+How can I contribute to the GenAIScript project? +Check the repository for contribution guidelines and consider providing feedback, submitting issues, or contributing code. Visit the Contributing page for more information.
+Who can I contact for feedback or questions about GenAIScript? +You can email the provided contacts in the Transparency Note document for feedback or questions.
+How often is GenAIScript updated and how can I stay informed about new features? +You can follow the GitHub repository for updates and announcements.
+Is there a roadmap available for GenAIScript’s development? +The GitHub repository will provide information on future development plans.
+Once you have a script that you are happy with, you can automate it using the command line interface.
+The basic usage of the CLI is to run a script with a tool name and a list of files.
+ +The CLI will use the secrets in the .env
file, populate env.files
with <...files>
, run the script
+and emit the output to the standard output.
You can use the CLI to run your scripts in a CI/CD pipeline. +The CLI will return a non-zero exit code if the script fails, which can be used to fail the pipeline.
+Add the --apply-edits
flag to the CLI to automatically write the file edits.
GitHub Actions is a continuous integration and continuous delivery (CI/CD) +platform that allows you to automate your build, test, and deployment pipeline. +This section explains how to integrate your GenAIScript in GitHub Actions workflows and pull requests.
+Configure the secrets +and variables +on your repository or organization so that GenAIScript can connect to your LLM.
+The secrets and variables should match the .env
file in your local environment.
Use the cli to run the script in a GitHub Action.
+--out <path>
flag to store the results in a directory so that you can upload them as an artifact.Use the out-trace
flag to output the trace to the summary file, $GITHUB_STEP_SUMMARY
+(see example).
You can use host.exec
to execute git command to retrieve changes in the current branch.
Note that you’ll need to pull origin/main
branch to make this command work in an action.
Ensure that the directory containing the results is uploaded as an artifact. You can review the trace by opening the res.trace.md
file.
+in the zipped artifact.
If your GitHub Action is triggered by a pull request event, +you can use the following flags to add comments: description, conversation and reviews.
+In order to create comments,
+the workflow must have the pull-requests: write
permission
+and the GITHUB_TOKEN
secret must be passed to the script.
The --pull-request-description
inserts the LLM output into the pull request section (see example).
+The command takes an optional string argument to uniquely identify this comment, it is used to update the comment (default is the script id).
If you want to run this script when the pull request is ready for review, use the ready_for_review
, opened
, reopened
events.
The --pull-request-comment
adds the LLM output as a comment to the pull request conversation (see example).
+The optional argument is an identifier for the comment (default is the script id) so that only one comment appears for the id.
Use the --pull-request-reviews
to convert annotations as review comments
+to the last commit on the pull request (see example).
GenAIScript will automatically try to ignore duplicate review comments and only create new ones.
+To collect the changes of the last commit in the pull request branch (see cool blog post), you can try this git command:
+Getting the most out of using GenAIScript requires rethinking what you expect software can do. +The most important element of using GenAIScript is the innovation that the user brings to +leveraging the power of the LLM for their needs. Here are some general guidelines +for using it most effectively.
+Remember, LLMs in GenAIScript can do things that no other software has been able to do. Think outside the box in the ways that you +use it. LLMs can critically review a document, write poetry, and analyze images, just +as a starting point. They have built-in expertise on many different human endeavors, math, +history, etc. and their knowledge can be easily extended by adding more context to the +script input (see next point).
+The more context you give the LLM
+in completing the task, the more effective it can be in solving it. The prompt
+in the script is one part of the input, but using def
, you can provide the LLM with
+lots of additional information. For example, if you want to use GenAIScript to plan
+a weekend vacation, use the Web Search capability
+to give the model information about things to do or what the weather will be at your
+destination. Input from documents is especially valuable to help the model perform
+well and as a result we define simple ways to extract text from pdf
+and docx files. You can parameterize the
+input context further using env.files
.
Say I wanted to use a GenAIScript to write a novel. Instead of asking the model to +write a whole novel or white paper as one prompt, I would divide the task +into different parts: generate the characters, establish a setting, develop a plot, etc. +and create GenAIScripts for each. By breaking down the problem, you can debug +the script to accomplish the specific task well and then move on. +Once you have one effective script, you can feed its output (like the list +of characters in a novel) into other scripts as part of the context.
+Combining the two points above, you can create a collection of inter-related +scripts that accomplish a more ambitious goal. Depending on your level of +expertise, the combination can be accomplished by using the command line +interface to the scripts CLI and using +traditional software to connect them.
+If you want to +apply a GenAIScript to all the files in a directory, use the command line +invocation of the script CLI +and a non-AI script to iterate over all the files. You can use an GenAIScript to +write code, but the code the LLM generates will not automatically run after you +generate it. You need to run and debug the generated code yourself.
+Consult the documentation for the specific LLM you are using to understand how to write prompts that effectively communicate the task you want the AI to perform. Parameters between LLMs vary, for example, the size of the input context allowed, so make sure +that the content you want to communicate to the LLM fits in its context window size.
You will need to configure the LLM connection and authorizion secrets.
+ +The model used by the script is configured throught the model
field in the script
function.
+The model name is formatted as provider:model-name
, where provider
is the LLM provider
+and the model-name
is provider specific.
The model can also be overriden from the cli run command.
+.env
fileGenAIScript uses a .env
file to store the secrets.
Create or update a .gitignore
file in the root of your project and make it sure it includes .env
.
+This ensures that you do not accidentally commit your secrets to your source control.
Create a .env
file in the root of your project.
Update the .env
file with the configuration information (see below).
This provider, openai
, is the default provider.
+It uses the OPENAI_API_...
environment variables.
Create a new secret key from the OpenAI API Keys +portal.
Update the .env
file with the secret key.
Set the model
field in script
to the model you want to use.
The Azure OpenAI provider, azure
uses the AZURE_OPENAI_...
environment variables.
+You can use a managed identity (recommended) or a API key to authenticate with the Azure OpenAI service.
Open your Azure OpenAI resource
Navigate to Access Control, then View My Access. Make sure your
+user or service principal has the Cognitive Services OpenAI User/Contributor role.
+If you get a 401
error, it’s typically here that you will fix it.
Navigate to Resource Management, then Keys and Endpoint.
Update the .env
file with the endpoint.
Navigate to deployments and make sure that you have your LLM deployed and copy the deployment-id
, you will need it in the script.
Update the model
field in the script
function to match the model deployment name in your Azure resource.
Visual Studio Code will ask you to allow using the Microsoft account +and then will open a browser where you can choose the user or service principal.
+401
errors after a while, try signing out in the user menu (lower left in Visual Studio Code) and back in.Login with Azure CLI +then use the cli as usual.
+ +Open your Azure OpenAI resource and navigate to Resource Management, then Keys and Endpoint.
Update the .env
file with the secret key (Key 1 or Key 2) and the endpoint.
Open Azure AI Studio, select Deployments
+and make sure that you have your LLM deployed and copy the deployment-id
,
+you will need it in the script.
Update the model
field in the script
function to match the model deployment name in your Azure resource.
There are many projects that allow you to run models locally on your machine, +or in a container.
+LocalAI act as a drop-in replacement REST API that’s compatible +with OpenAI API specifications for local inferencing. It uses free Open Source models +and it runs on CPUs.
+LocalAI acts as an OpenAI replacement, you can see the model name mapping
+used in the container, like gpt-4
is mapped to phi-2
.
Install Docker. See the LocalAI documentation for more information.
Update the .env
file and set the api type to localai
.
Ollama is a desktop application that let you download and run model locally.
+Running tools locally may require additional GPU resources depending on the model you are using.
+Use the ollama
provider to access Ollama models.
Start the Ollama application or
Update your script to use the ollama:phi3
model.
https://llamafile.ai/ is a single file desktop application +that allows you to run an LLM locally.
+The provider is llamafile
and the model name is ignored.
Jan, LMStudio, +LLaMA.cpp +also allow running models locally or interfacing with other LLM vendors.
+Update the .env
file with the local server information.
You can provide different environment variables
+for each named model by using the PROVIDER_MODEL_API_...
prefix or PROVIDER_API_...
prefix.
+The model name is capitalized and
+all non-alphanumeric characters are converted to _
.
This allows to have various sources of LLM computations
+for different models. For example, to enable the ollama:phi3
+model running locally, while keeping the default openai
model connection information.
Write your first script.
The GenAIScript script files are executable JavaScript and can be debugged +using the Visual Studio Code Debugger, just like any other JavaScript program.
+ +.genai.js
file to debug and add breakpoints.env.files
.env.files
.files
field in the script
functionThe debugger will launch the cli and run the script in debug mode. +The debugger will stop at the breakpoints you set.
+The JavaScript executes in an external node process. Therefore,
+Keep iterating the script or add tests.
GenAIScript is a scripting language that integrates LLMs into the scripting process using a simplified JavaScript syntax. +It allows users to create, debug, and automate LLM-based scripts.
+GenAIScript brings the flexibility of JavaScript with the convenience of built-in output parsing +to streamline the creation of LLM-based software solutions.
+The following script generates a prompt that +takes files (.txt, .pdf, .docx) as input and +saves the summaries in another files.
+ + +GenAIScript will execute summarize.genai.js
and generate the 👤 user
message that will be sent to the LLM chat. It also populates the env.files
variable with the files selected in the context (from a user UI interaction or CLI arguments).
The LLM responds with the 🤖 assistant
message and GenAIScript parses the output
+to extract structured data.
All the generated prompts are formatted and sent to the LLM server, which can be remote like OpenAI or running locally like ollama (there are many other LLM providers).
+ +The LLM responds with a text which can be parsed for various micro-formats, +like markdown code fences, files or annotations.
+GenAIScript automatically makes sense of the output and exposes it through a Refactoring Preview or directly saved to the file system.
+Of course, things can get more complex - with functions, schemas, … -, but this is the basic flow of a GenAIScript script.
+Let’s start by installing the extension in Visual Studio Code.
GenAiScript is available as a command line or a Visual Studio Code Extension.
+GenAiScript requires Node.JS to run. +We recommend installing the LTS version using a node version manager.
+Install node version manager.
On Linux, MacOS, install nvm. +On Windows, install nvm-windows.
Install the LTS version of Node.JS.
Check installation
The Visual Studio Code Marketplace +contains the latest stable release of the extension.
+Install Visual Studio Code.
Visual Studio Code is a lightweight but powerful source code editor which runs on your desktop and is available for Windows, macOS and Linux.
Open your project folder in Visual Studio Code.
Click on the Extensions view
Search genaiscript and click Install.
If successful, you will see the icon in the Extensions view.
The latest development build of the extension is also available on through the GitHub releases. This allows access +to bug fixes earlier than the marketplace release.
+Open the latest release on GitHub
Download the genaiscript.vsix
into your project root folder
Open your project in Visual Studio Code
Right click on the .vsix
file and select Install Extension VSIX…
The genaiscript command line tool lets you run your GenAIScript +from any terminal.
+ +npx
will automatically install and cache the CLI. You can also add it as a devDependency
to your projec.
Let’s configure the LLM connection information
In Visual Studio Code, the location where you start running a script determines the entries in the env.files
variable.
The env.files
array will contain a single element with the selected file.
The env.files
array will contain all nested files under that folder.
You can specify default file or files to run the script on. +When you run the script from the script file itself, or with the command line without file arguments, +the default files will be used.
+ +Use the run command to execute a script from the command line.
+ +By default, GenAIScript opens the output preview which shows a rendered view of the LLM output (assuming the LLM produces markdown).
+You can also use the Trace to review the each transformation step of the script execution.
+Debug your scripts using the Visual Studio Code Debugger!
It is possible to declare tests in the script
function
+to validate the output of the script.
The tests are added as an array of objects in the tests
key of the script
function.
play
icon button.Run this command from the workspace root.
+ +Currently, promptfoo treats the script source as the prompt text. Therefore, one cannot use assertions
+that also rely on the input text, such as answer_relevance
.
Automate script execution using the command line interface (CLI).
GenAIScript use stylized JavaScript with minimal syntax.
+They are stored as files (genaisrc/*.genai.js
or genaisrc/*.genai.mjs
) in your project.
+The execution of a genaiscript creates the prompt that will be sent to the LLM.
Use the > GenAiScript: Create new script...
command in the command palette
+(Ctrl+Shift+P
on Windows/Linux, ⇧⌘P
on Mac)
+to create a new script.
Run the cli script create
command with the name of the script you want to create.
The resulting file will be placed in the genaisrc
folder in your project.
The execution of the GenAIScript generates a prompt (and more) +that gets sent to the LLM model.
+The $``...``
template string function formats and write the string to the prompt;
+which gets sent to the LLM.
GenAIScript exposes the context through the env
variable. The context is implicitly defined by the location you start executing the script.
env.files
will contain all the files nested in that folder.env.files
will contain only that file.env.files
in the CLI arguments.The $
function is used to build the prompt text, it renders and writes the text to the prompt
+($
is a template literal).
You can add a call to the script
function to provides metadata about the script
+and the model. The metadata is used to display the script in the UI and configure the LLM model.
The title
, description
, and group
properties are used to display the script in the UI
+and can be helpful when the user is searching for a script.
The quick-start guide illustrates how to write a GenAIScript that takes input from an image file.
+Place your image in a directory visible in VS Code Explorer
+Use the > GenAIScript: Create new script...
command in the command palette to create a new script.
Update the model in the script header to refer to a model that understands images:
+ +Use defImages to ingest the image file into the model context:
+ +Replace the text "TELL THE LLM WHAT TO DO..."
with what you want it to do with your image file.
Right click on the image file in VS Code Explorer. Select Run GenAIScript. Select the script you just wrote.
+The Output will be displayed in a new document tab.
+The quick-start guide illustrates how to write a GenAIScript that takes input from a pdf file.
+> GenAIScript: Create new script...
command in the command palette to create a new script."TELL THE LLM WHAT TO DO..."
with what you want it to do with your pdf file. Use the name in the def to refer to the file.
+
+In this example, we will extract text from a pdf that describes the history of Lorem Ipsem.
+ + +This guide shows how to use vision and image variables to scan business card information in a structured format.
+You will need access to a deployment of the OpenAI vision model. In this example, it is identifier by gpt-4-turbo-v
.
+Also set the maxTokens
to 4000 to ensure the model can process the entire business card.
defImage
The defImage function can be used to input multiple files to the script.
+The non-image files will automatically be ignored, so you can typically pass env.files directly to defImages
.
All together the script looks like the following:
+ +We can add data format validation by adding a schema for the business data rows.
+ +And the script above is adapter to use the schema instead of the CSV description.
+This guide shows how to create a tool +that call an executable in a container. +This is a flexible and secure way to run tools that may have dependencies or security concerns.
+This is typically done by creating a container with a particular image (gcc
here)
then reusing the container in the tool invocations. You can return the result of container.exec
+from the tool and it will be handled by the runtime.
This sample uses the official GCC docker image to compile a C program as tool. +The LLM engine will invoke the tool to validate the syntax of the generated code.
+ + +gcc
(call_IH693jAqZaC7i3AkUa3eIFXi
)call_IH693jAqZaC7i3AkUa3eIFXi
Generated Knowledge +is a prompting technique where one first asks the LLM a question to generate facts, +then uses the generated answer to answer a question correctly.
+This technique can be acheived by using runPrompt +to execute an LLM request and use it in the final prompt.
+This example demanstrates this technique to generate a blog post.
+Phi-3 Mini +is a 3.8B parameters, lightweight, state-of-the-art open model by Microsoft. +In this guide, we use Ollama, +a desktop application that let you download and run model locally.
+Start the Ollama application or run the command to launch the server from a terminal.
(optional) Pull your model from the Ollama server (see list of models). +GenAIScript will automatically attempt to pull it if missing.
Update your script to use the ollama:phi3
model.
Apply this script to the files you want to summarize!
Save the script below in your project as genaisrc/slides.genai.js
.
Right click on the code file or folder, select Run GenAIScript… and select Generate Slides.
Apply the refactoring to save the generated slides file.
To visualize the slides, install the vscode-reveal extension. +Open the slides file and click slides in the status bar.
This page is a tutorial on creating prompt with GenAIScript. It is designed to be opened in Visual Studio Code as a Notebook.
+ +The GenAIScript Markdown Notebook will parse the markdown document into a Notebook view and use Visual Studio Code’s support to provide a rich editing experience. It should work with any markdown file as long as the code fence use ”```“.
+GenAIScript lets you write prompts as a JavaScript program. GenAIScript runs your program; generate chat messages; then handles the remaining interaction with the LLM API.
+$
Let’s start with a simple hello world program.
+ + +The $
function formats the strings and write them to the user message. This user message is added to the chat messages and sent to the LLM API. Under the snippet, you can review both the user message (that our program generated) and the assistant (LLM) response.
You can run the code block by clicking the Execute Cell button on the top left corner of the code block. It will be default try to use the openai:gpt-3.5-turbo
LLM. If you need to use a different model, update the model
field in the front matter at the start of the document. There are many options documented in configuration.
Once the execution is done, you will also an additional trace entry that allows you to dive in the internal details of the GenAIScript execution. This is very helpful to diagnose issues with your prompts. The trace can be quite large so it is not serialized in the markdown file.
+You can use the JavaScript for
loop and sequence multiple $
calls to append text to the user message. You can also inner expression to generate dynamic content.
To recap, the GenAIScript runs and generates a user messages; that gets sent to the LLM. You can review the user message (and others) in the trace.
+def
and env.files
The def
function lets you declare and assign LLM variables. The concept of variable is most useful to import context data, in particular files, and refer to them in the rest of the prompt.
In GenAIScript, the env.files
variable contains the list of files in context, which can be determined by a user selection in the UI, CLI arguments, or pre-configured like in this script. You can change the files in env.files
by editing the files
field in the front matter at the start of the document.
When using GenAIScript from the user interface, it is common to apply a script to an entire folder. This means that you’ll get a bunch of files in env.files
including some unneeded ones. The def
function provides various options to filter the files, like the endsWith
option.
def
also provides maxTokens
which will trim the content size to a number of tokens. LLM context is finite!
The pull request reviewer is a GenAIScript that runs in the context of a pull request. +It can be used to review the changes in the pull request and provide feedback to the author. +The reviewer can also suggest changes to the code, documentation, or other files in the pull request.
+The output of the LLM is inserted as a comment in the pull request conversation +(and updated as needed to avoid duplicates).
+Here is an pull request in the GenAIScript repository +with genai-generated description, comments and reviews.
+You can prototype the pull request reviewer script in a branch with known changes so that you can assess +the quality of the results. As you start using it in your build, you will be able to also refine it later on.
+git diff
The script starts by running git diff
to get the changes in the pull request. Since we also know which folder
+to ignore and which file we care about, we can provide additional filters to git to minimize the generated diff.
The diff is then inserted in the prompt using the def function.
+ +The second part of the prompt consists of creating the task and the persona for the LLM.
+ +Since we are reviewing TypeScript, we also pre-load the system prompt that prepares the TypeScript mindset of the LLM.
+ +The diff is a partial view of the files and the LLM needs to access the full content of the files +to provide a meaningful review. To enable this scenario,
+ +Add this step to your Github Actions workflow to automate the pull request review process.
+Suppose we want to plan a weekend trip using a GenAIScript that +will help us plan by using web search to learn about things to do and the expected weather.
+ +Use the > GenAIScript: Create new script...
command in the command palette to create a new script.
Start the script by defining the model and title:
+ +Use the webSearch
function to
+search for information about the destination.
+If you don’t have one, then you can search for the web pages manually and use the URLs directly
+in the call to the fetchText
function.
webSearch
returns a list of URLs. Use fetchText
+to fetch the contents of the 1st URL.
fetchText
returns a lot of formatting HTML tags, etc.
+Use runPrompt
+to call the LLM to clean out the tags and just keep the text.
Repeat to get the latest weather info about your destination.
+ +Replace the text "TELL THE LLM WHAT TO DO..."
with what kind of
+vacation you want to plan.
Press the “Run” button on the upper right corner of the editor to run the script.
+(You can run this script in this way because it takes no other input in env.files
))
The output will be displayed in a new document tab.
+Here’s an example of the output you might get:
+ +Here’s the complete GenAIScript:
+GenAIScript scripts are files and can be shared like any other code file.
+As long as the script file are under the project folder, GenAIScript will look for **/*.genai.js
files and **/*.genai.mjs
.
Here are some ideas to share files.
+If you store your scripts in a git repository, you can use git submodules to share them across multiple projects.
+https://.../shared-scripts
)https://.../shared-scripts
shared-scritps
as a git submoduleGists is a lightweight way to share a couple files.
Suppose I have a directory with multiple .pdf
(or other) files and I want to run a GenAIScript over all of them.
+In this example, I’m generating a catchy tweet for each document and I want to save the tweet in another file.
Use the > GenAIScript: Create new script...
command in the command palette to create a new script.
This is an easy script. Assuming the script will take the file as an argument,
+you can refer to that argument in env.files
and tell the LLM what to do with it:
Right click on the document in VS Code Explorer (it can be a .pdf
, a .docx
, or a .md
file
+because def
knows how to read and parse all these file types).
+Select Run GenAIScript. Select the script gen-tweet
you just wrote.
Assuming we give the GenAIScript a paper describing GenAIScript, the Output will be displayed in a new document tab.
Because we didn’t tell the LLM to write the output to a file, it will by default go to standard out.
We can run the script from the command line:
The output will be displayed in the terminal.
Now that we have the script working for a single file, we can use the command line to apply it to a list of
+files. Let’s assume you start with a file ex1.pdf
you want the output in a new file ex1.tweet.md
.
+How you do this depends on the shell script you prefer. (See batch processing…).
This script requires zx.
Using tools (formerly functions), +you can define a built-in agent that can take decisions +and reasoning based on the tools provided to it.
+Let’s illustrate this concept using the llamaindex sum div sample: +an agent that can sum or divide two numbers and needs to answer basic arithmetic questions.
+By declaring tools (and providing a descriptive description), you provide the opportunity +for the LLM to requests a tool call during the output generation. In the snippet below, +we declare a tool that can sum two numbers. It will be called by the LLM when a sum operation +is required.
+ +The arithmetic question can be declared as a script parameter to be used in the agent script.
+ +The parameter value are populated in the env.vars
object.
Putting it all together, we define another tool to divide two numbers +and inline an arithmetic question.
+ + +divide({"a":15,"b":3})
(call_9p0oWdWpT6vGyxzwq2vJXHrq
)call_9p0oWdWpT6vGyxzwq2vJXHrq
system.math
The system prompt system.math
+wraps the parsers.math
expression parser and evaluator and exposes it as a tool.
This simplifies the agent script as we do not have to define tools anymore.
+Hugging Face Transformer.js +let’s you run local model directly from your browser or a Node.JS process. +We can freely use this library from a GenAIScript.
+You will need to install +the package locally to reference it in your script.
+ +The summarization pipeline +specializes in summarizing text. You typically want to allocate a pipeline once +and reuse it over the lifetime of the script.
+ +The summarizer
object is a locally running model that we can use to summarize each file.
There’s a ton of other transformers that you could also use in your scripts. Happy modeling.
This guide shows how to use TypeScript, a 3rd party search service, and secrets to create +a script that augments documents with information from the web.
+The goal is to create a script that will augment an existing document with information +gathered from the web.
+Tavily is a search service optimized for LLMs that provides a REST API.
+The REST API can be invoked using JavaScript fetch +and requires an API key.
+The script uses the TAVILY_API_KEY
which will have to be declare in the script using this function.
We define a function tavilySearch
in TypeScript that wraps the fetch
call and we add type annotations to provide
+a nice editing experience.
The full source looks like this:
+ +The script is split into 3 phases:
+The secret TAVILY_API_KEY
needed by Tavily is declared in the script
function call.
+Also make sure to add it to your .env
file.
The tavilySearch
function is imported using a dynamic import.
The full source looks like this:
+Install the extension
Install the Visual Studio Code +Extension to get started.
Configure your LLMs
Configure the secrets to access your +LLMs.
Write your first script
Follow Getting +Started to write +your first script.
Read the docs
Learn more about GenAIScript in the Scripting +Reference.
GenAIScript brings essential LLM prompt tooling into a cohesive scripting environment.
+Stylized JavaScript
Build prompts programmatically using JavaScript +or TypeScript.
Fast Development Loop
Edit, Debug, Run, +Test your scripts in Visual Studio Code +or with a command line.
Reuse and Share Scripts
Scripts are files! They can be versioned, shared, forked, …
Data Schemas
Define, validate, repair data using schemas.
Ingest text from PDFs, DOCX, ...
Ingest tables from CSV, XLSX, ..
Generate Files
Extract files and diff from the LLM output. +Preview changes in Refactoring UI.
RAG built-in
Local Models
Run your scripts with Open Source models, +like Phi-3, +using Ollama, LocalAI…
Containerized Code Interpreter
Run code in Docker containers.
LLM Composition
Run LLMs to build your LLM prompts.
Automate
Automate using the CLI, +integrate reports in your CI/CD pipeline.
Tests and Evals
Build reliable prompts using tests and evals +powered by promptfoo.
${i(30)}
+${i(40)}
+A full list of the CLI command and its respective help text.
+run
test
test run
test view
scripts
scripts list
scripts create
scripts fix
scripts compile
scripts model
cache
cache clear
retrieval
retrieval index
retrieval search
retrieval clear
retrieval fuzz
retrieval code
serve
parse
parse fence
parse pdf
parse docx
parse html-to-text
parse code
parse tokens
parse jsonl2json
info
info help
info system
The GenAIScript CLI genaiscript
runs GenAIScript scripts
+outside of Visual Studio and in your automation.
where --yes
skips the confirmation prompt to install the package.
The CLI is a Node.JS package hosted on npm.
+devDependency
in your project.npx
)+++
npx
is installed with Node.JS.
Using npx, +you can run the cli without any prior installation steps. +npx will install the tool on demand. npx also takes care of tricky operating +system issues where the tool is not found in the path.
+ +Add --yes
to skip the confirmation prompt, which is useful in a CI scenario.
You can also lock this call to a particular version.
+ +The CLI will load the secrets from the environment variables or a ./.env
file.
You can override the default .env
file name by adding the --env myother.env
file.
Creates a new script file in the genaisrc
folder.
Runs the TypeScript compiler to find errors in the scripts.
+ +Run a script on file +and streams the LLM output to stdout. Run from the workspace root.
+ +where <script>
is the id or file path of the tool to run, and [files...]
is the name of the spec file to run it on.
Run the script model
command to list the available scripts and their model configuration. This can be useful to diagnose configuration issues in CI/CD environments.
where [script] can be a script id or a file path.
Runs a script on files and streams the LLM output to stdout or a folder from the workspace root.
+ +where <script>
is the id or file path of the tool to run, and [spec]
is the name of the spec file to run it on.
Files can also include glob pattern.
+ +If multiple files are specified, all files are included in env.files
.
The LLM connection configuration is read from environment variables or from a .env
file in the workspace root directory.
See configuration.
+Excludes the specified files from the file set.
+ +Exclude files ignored by the .gitignore
file at the workspace root.
Saves the results in a JSON file, along with markdown files of the output and the trace.
+ +If file
does not end with .json
, the path is treated as a directory path.
Output the entire response as JSON to the stdout.
+Output the entire response as YAML to the stdout.
+Populate values in the env.vars
map that can be used when running the prompt.
Save the markdown trace to the specified file.
+ +In a GitHub Actions workflow, you can use this feature to save the trace as a step summary (GITHUB_STEP_SUMMARY
):
Emit annotations in the specified file as a JSON array, JSON Lines, SARIF or a CSV file if the file ends with .csv
.
Use JSON lines (.jsonl
) to aggregate annotations from multiple runs in a single file.
Emits parsed data as JSON, YAML or JSONL. If a JSON schema is specified +and availabe, the JSON validation result is also stored.
+ +Emit changelogs in the specified file as text.
+ +Skips the LLM invocation and only prints the expanded system and user chat messages.
+Specifies the number of retries when the LLM invocations fails with throttling (429). +Default is 3.
+Minimum delay between retries in milliseconds.
+Adds a run label that will be used in generating the trace title.
+Enables LLM caching in JSONL file under .genaiscript/tmp/openai.genaiscript.cjsonl
. Caching is enabled by default in VSCode
+but not for the CLI.
Overrides the LLM run temperature.
+Overrides the LLM run top_p
value.
Overrides the LLM model identifier.
+Apply file modifications to the file system.
+Generate a source map for the script sources to allow debugging.
Runs the tests in scripts using promptfoo.
+ +You can override which models to use in the tests using --models
:
Run the test view
command to launch the test result viewer:
GenAIScript is a scripting language that makes LLMs a first-class part of the scripting process, easily allowing users to author, debug, and deploy LLM-based scripts that can perform tasks beyond the reach of conventional code. This reference guide provides comprehensive documentation for GenAIScripts, including script syntax, LLM configurations, the VSCode extension, and the CLI.
+Microsoft AICI allows to constrain the output of a LLM using WASM. In particular, it is possible to send JavaScript program to describe the prompt.
+GenAIScript support executing scripts and converting the output into a AICI compatible JavaScript program, which will them generate constrainted output.
+ +Let’s take a look at an example.
+ +The execution of this script is converted into a AICI JavaScript program.
+ +And AICI comes back with the following log.
+ +And the text output is 42
.
An AICI template should set the aici
provider in the model identifier.
gen
The AICI.gen
function creates a constrain in the prompt flow.
AICI uses AICI_API_KEY
, AICI_API_BASE
and AICI_API_VERSION
(default v1
) to compose the API URL.
Annotations are errors, warnings, or notes that can be added to the LLM output. They are extracted and integrated into VSCode or your CI environment.
+ +If you use annotation
in your script text without specifying the system
field, system.annotations
will be added by default.
Utilizing the system.annotations
system prompt enables the LLM to generate errors, warnings, and notes.
To get a pretty rendering in the Markdown preview, try the Markdown Preview for Github Alerts extension.
The system.annotations
prompt automatically enables line number injection for all def
sections. This enhances
+the precision of the LLM’s responses and reduces the likelihood of hallucinations.
By default, the annotations use the GitHub Action Commands syntax. +This means that the annotations will automatically be extracted by GitHub if you run your script in a GitHub Action.
+Use the --pull-request-review-comment
flag on the cli to add annotations as review comments on a pull request.
Annotations are converted into Visual Studio Diagnostics, which are presented to the user +through the Problems panel. These diagnostics also manifest as squiggly lines in the editor.
+GenAIScript converts these annotations into SARIF files, which can be uploaded as security reports, akin to CodeQL reports.
+The SARIF Viewer +extension facilitates the visualization of these reports.
+ +You can use the defOutput function +to filter the annotations.
+LLM requests are cached by default. This means that if a script generates the same prompt for the same model, the cache may be used.
+temperature
is less than 0.5top_p
is less than 0.5seed
is not usedThe cache is stored in the .genaiscript/cache/chat.jsonl
file. You can delete this file to clear the cache.
+This file is excluded from git by default.
You can always disable the cache using the cache
option in script
.
Or using the --no-cache
flag in the CLI.
Use the cacheName
option to specify a custom cache file name.
+The name will be used to create a file in the .genaiscript/cache
directory.
Or using the --cache-name
flag in the CLI.
It is not uncommon that upon executing a script, you may want to cancel the execution of the script. This can be done using the cancel
function. The cancel
function takes an optional reason
argument and will immediately stop the execution of the script.
The defChatParticipant
allows to register a function that can add new user messages in the chat sequence.
+This allows to create multi-turn chat, or to simulate a conversation with multiple participants.
In the example above, the defChatParticipant
function is used to register a function that will be called every time a new message is added to the chat.
The function receives two arguments: the first argument is the Chat
object, and the second argument is the list of messages that have been added to the chat since the last call to the function.
The participant will be called on every turn so it is important to keep track of the turns to avoid infinite loops.
+ +This script uses a multi-turn chat to generate questions, answers and validate the quality of the answers.
+Containers, like Docker, are a way to package software and its dependencies into a standardized unit for software development. Containers are lightweight, standalone, and executable software packages that include everything needed to run an application: code, runtime, system tools, system libraries, and settings.
+ +GenAIScript uses Docker to orchestrate the containers.
+ +Start by creating and starting a new container. GenAIScript will pull the container image on demand +and will remove the container when it is no longer needed.
+ +By default, the container uses the python:alpine
+ image, which provides a minimal python environment. You can change the image using the image
option.
By default, the container is removed when it is no longer needed. You can disable this behavior using the disablePurge
option.
You can run a command in the container using the exec
method. It returns the exit code, standard output and error streams.
The container has a volume mounted in the host file system, which allows to read and write files to the container.
+ +You can also copy files from the host to the container.
+ +The containerized tools guide shows how to use containers in tools to handle untrusted text securely.
The information about the context of the script execution are available in the env
global object.
env
)The env
global object contains properties that provide information about the script execution context.
+env
is populated automatically by the GenAIScript runtime.
env.files
The env.files
array contains all files within the execution context. The context is defined implicitly
+by the user based on:
script
files
optionor multiple paths
+ +the UI location to start the tool
+CLI files arguments.
+Or filtered,
+ +env.vars
The vars
property contains the variables that have been defined in the script execution context.
Read more about variables.
+env.secrets
The secrets
property contains the secrets that have been defined in the script execution context.
Read more about secrets.
+def
)The def("FILE", file)
function is a shorthand for generating a fenced variable output.
+The “meta-variable” (FILE
in this example) name should be all uppercase (but can include
approximately equivalent to:
+ +The def
function can also be used with an array of files, such as env.files
.
The def
function returns a variable name that can be used in the prompt.
+The name might be formatted diferently to accommodate the model’s preference.
Since a script may be executed on a full folder, it is often useful to filter the files based on
+By default, if def
is used with an empty array of files, it will cancel the prompt. You can override this behavior
+by setting ignoreEmpty
to true
.
maxTokens
It is possible to limit the number of tokens that are generated by the def
function. This can be useful when the output is too large and the model has a token limit.
+The maxTokens
option can be set to a number to limit the number of tokens generated for each indivial file.
The def
function treats data files such as CSV and XLSX specially. It will automatically convert the data into a
+markdown table format to improve tokenization.
sliceHead
, keep the top N rowssliceTail
, keep the last N rowssliceSample
, keep a random sample of N rowsdefData
)The defData
function offers additional formatting options for converting a data object into a textual representation. It supports rendering objects as YAML, JSON, or CSV (formatted as a markdown table).
The defData
function also support functions to slice the input rows and columns.
headers
, list of column names to includesliceHead
, number of rows to include from the beginningsliceTail
, number of rows to include from the endsliceSample
, number of rows to pick at randomdistinct
, list of column names to deduplicate the data based onParsing and stringifying of Comma Separated Values (CSV) data.
+The parsers map CSV data to an array of object with field names mapping the header. For example, the CSV data:
+ +maps to the following array of objects:
+ +def
The def function will automatically parse and stringify CSV data to a Markdown table (it also works for XLSX).
+ +def
also support basic row filtering options that easily control how many rows you want to insert in the prompt.
CSV
Similarly to the JSON
class in JavaScript, the CSV
class provides methods to parse and stringify comma separated values (csv) data.
parse
The parse
method converts a CSV string into an array of objects. The first row is used as the header row.
If the CSV file does not have a header row, you can specify the column names as an array of strings. You can also specify a custom data separator.
+ +You can use defData
+to serialize the rows
object to the prompt. defData
also supports
+basic row filtering options like with def
.
markdownify
The markdownify
method converts an array of objects into a markdown table.
+This is an encoding that is somewhat more efficient with LLM tokenizers.
parsers
The parsers also provides merciful parser for CSV.
+Returns undefined
for invalid inputs. It also supports files and parsing options.
The defOutputProcessor
function registers a callback to do custom processing of the LLM output at the end of the generation process. This function allows to create new files or modify the existing ones.
This example clears the fileEdits
object, which contains the parsed file updates.
The def
function will automatically parse DOCX files and extract text from them
The parsers.DOCX
function reads a PDF file and attempts to cleanly convert it into a text format
+that is friendly to the LLM.
The JavaScript fetch
API is available; but we also provide a helper
+fetchText
for issuing requests into a friendly format.
fetchText
Use fetchText
to issue requests and download text from the internet.
fetchText will also resolve the contents of file in the current workspace if the url is a relative path.
+ +If the API you are querying requires an API key, you can use the secrets object to store the key.
The defFileMerge
function allows to register a custom callback to overide the default file merge behavior.
+This can be useful to merge files in a different way than the default one, for example to merge files in a different format than the default one.
The function is called for all files; return the merged content or undefined
is skipped.
You can define multiple file merge callbacks, they will be executed in order of registration.
+The callback below appends the content in generated .txt
files.
The defFileOutput
function lets you declare file output paths and the purpose of those files. This function is used to specify the output files that are generated by the script.
GenAIScript provides access to the file system of workspace and to the selected files in the user interface.
+The file path are rooted to the project workspace folder. In Visual Studio Code, this is the root folder opened (multi-root workspaces are not yet supported). Using the command line, the workspace root is the current working directory when launching the CLI.
+env.files
The variable env.files
contains an array of files that have been
+selected by the user through the user interface or the command line.
You can pass env.files
directly in the def
+function and add additional filters to the files.
Use defFileOutput to specify allow file output paths and the description +of the purpose of those files.
+ +workspace
The workspace
object gives access to file system of the workspace.
findFiles
Performs a search for files under the workspace. glob patterns are supported.
+ +readText
Reads the content of a file as text, relative to the workspace root.
+ +It will automatically convert PDFs and DOCX files to text.
+writeText
Writes text to a file, relative to the workspace root.
+ +The paths
object contains helper methods to manipulate file names.
By default, files are resolved relative to the workspace root. You can use the path
object to resolve paths relative to the current spec, env.spec
.
File path “globs” are patterns used to match file and directory names. They are commonly used in Unix-like operating systems and programming languages to specify sets of filenames with wildcard characters. This tutorial will cover the basics of using globs in file paths with workspace.findFiles.
+Glob patterns can have the following syntax:
+*
to match zero or more characters in a path segment?
to match on one character in a path segment**
to match any number of path segments, including none{}
to group conditions (e.g. **/*.{ts,js}
matches all TypeScript and JavaScript files)[]
to declare a range of characters to match in a path segment (e.g., example.[0-9]
to match on example.0, example.1, …)[!...]
to negate a range of characters to match in a path segment (e.g., example.[!0-9]
to match on example.a, example.b, but not example.0)Note: a backslash (\
“) is not valid within a glob pattern. If you have an existing file path to match against, consider to use the relative pattern support that takes care of converting any backslash into slash. Otherwise, make sure to convert any backslash to slash when creating the glob pattern.
Images can be added to the prompt for models that support this feature (like gpt-4-turbo-v
).
+Use the defImages
function to declare the images. Supported images will vary
+with models but typically include PNG
, JPEG
, WEBP
, and GIF
. Both local files and URLs are supported.
Read more about OpenAI Vision.
Scripts using the .mjs
extension can use static or dynamic imports as any other module file.
+You can rename any .genai.js
file to .genai.mjs
to enable module imports.
You can import node packages installed in your project.
+ +You can also import other local JavaScript files (using static or dynamic imports).
+ +import ... from ...
)async import(...)
)TypeScript module files (.mts
) can be imported using dynamic import only.
async import(...)
)env.generator
The env.generator
references the root prompt generator context, the top level $
, def
functions… It can be used to create function that can be used with those function or also with runPrompt
.
If you set a function as the default export, GenAIScript will call it. +The function can be async.
+GenAIScript are JavaScript files named as *.genai.mjs
+with a prompt creation engine designed by LLM prompting.
*.genai.mjs
, *.genai.js
,
+*.genai.mts
in your workspace.genaisrc
folder by default..genai.mjs
use module JavaScript syntax and support imports..genai.js
are eval-ed and do not support imports..genai.mts
are TypeScript module files and support imports,
+including dynamic imports of other TypeScript files.system.*.genai.mjs
are considered system prompt templates
+and are unlisted by default.Parsing and stringifying of .ini
data.
INI
Similarly to the JSON
class in JavaScript, the INI
class provides methods to parse and stringify .ini
files.
parsers
The parsers also provides merciful parser for .env
.
+Returns undefined
for invalid inputs.
The runPrompt
function allows to build an inner LLM invocation. It returns the output of the prompt.
You can also shortcut the function and pass the prompt text directly
+ + +The snippet below uses gpt-3.5
to summarize files individually before
+adding them to the main prompt.
The snippet below uses Phi-3 +through Ollama to summarize files individually before adding them to the main prompt.
+Some models support forcing the output format to a JSON object, like the JSON Object mode of OpenAI.
+The generated file name will be [spec].[template].json
.
responseSchema
You can specify a responseSchema
in the script metadata which will automatically turn on the JSON mode. The output will be validated against the schema, and GenAIScript will attempt to repair the output is not valid. The script will fail if the output does not match the schema.
responseType
You can also enable this mode without a schema by setting response_type
to json_object
.
You can also specify the schema inline in the script and use a mixed markdown/data that GenAIScript will parse.
Prompts use script({ ... })
function call
+to configure the title and other user interface elements.
The call to script
is optional and can be omitted if you don’t need to configure the prompt.
+However, the script
argument should a valid JSON5 literal as the script is parsed and not executed when mining metadata.
The title
, description
and group
are used in the UI to display the prompt.
title
is used as the prompt name, displayed in the light-bulb UI
description
provides more details and context about the prompt.
Helps organizing your scripts.
+ +Override the system prompts included with the script.
+ +You can specify the LLM model
identifier in the script. The default is gpt-4
.
+The IntelliSense provided by genaiscript.g.ts
will assist in discovering the list of supported models.
You can specify the LLM max tokens
in the script. The default is unspecified.
Limits the amount of allowed function/tool call during a generation. This is useful to prevent infinite loops.
+ +You can specify the LLM temperature
in the script, between 0
and 2
. The default is 0.01
.
You can specify the LLM top_p
in the script. The default is not specified
For some models,You can specify the LLM seed
in the script, for models that support it. The default is not specified.
+For some models, you can specify the LLM seed
in the script, for models that support it. The default is unspecified.
A function that merges the generated content with the original content. The default is to replace the original content with the generated content. This function can be used to implement custom merge strategies.
+unlisted: true
, don’t show it to the user in lists. Template system.*
are automatically unlisted.See genaiscript.d.ts
in the sources for details.
The GenAISCript Markdown Notebook is currently used to author the GenAIScript documentation.
+ +It allows to run script snippets and inline the result in the markdown just like this:
+ + +The first step is to open the markdown file to edit using the GenAIScript notebook.
+.md
) or MDX file (.mdx
)You can run any JavaScript cell by clicking the Run Cell button or pressing Shift+Enter
. It will run the code as if it was a GenAIScript script in the workspace.
You can provide global configuration settings in the front matter. The front matter starts and ends with three dashes ---
and is located at the top of the markdown file.
You can specify the LLM configuration metadata from script
.
You can specify the files to include in the notebook, as a single entry or an array. Globs are supported. +The files are relative to the workspace root.
+ +The env.files
variable is available to reference the files in the notebook.
The parsers
object provide various parers for commomn data formats.
The parsers.json5
function parses the JSON5 format.
+JSON5 is an extension to the popular JSON file format that aims to be easier to write and maintain by hand (e.g. for config files).
In general, parsing a JSON file as JSON5 does not hurt but it might be more merciful +to syntactic errors. In addition to JSON5, JSON repair is applied with the initial parse fails.
+To parse, use parsers.JSON5
. It supports both a text content or a file as input.
The parsers.YAML
function parses for the YAML format.
+YAML is more friendly to the LLM tokenizer than JSON. YAML is commonly used in configuration
+files.
To parse, use parsers.YAML
. It supports both a text content or a file as input.
The parsers.TOML
function parses for the TOML format.
+YAML is more friendly to the LLM tokenizer than JSON. YAML is commonly used in configuration
+files.
To parse, use parsers.TOML
. It supports both a text content or a file as input.
JSONL is a format that stores JSON objects in a line-by-line format. Each line is a valid JSON(5) object (we use the JSON5 parser to be more error resilient).
+ +You can use parsers.JSONL
to parse the JSONL files into an array of object (any[]
).
The parsers.XML
function parses for the XML format.
Front matter is a metadata section at the head of a file, typically formatted as YAML.
+ +You can use the parsers.frontmatter
to parse out the metadata into an object
The parsers.CSV
function parses for the CSV format. If successful, the function returns an array of object where each object represents a row in the CSV file.
The parsers will auto-detect the header names if present; otherwise you should +pass an array of header names in the options.
+ +The parsers.PDF
function reads a PDF file and attempts to cleanly convert it into a text format. Read the /genaiscript/reference/scripts/pdf for more information.
The parsers.DOCX
function reads a .docx file as raw text.
The parsers.INI
parses .ini files, typically
+using for configuration files. This format is similar to the key=value
format.
The parsers.XLSX
function reads a .xlsx file and returns an array of objects where each object represents a row in the spreadsheet.
+The first row is used as headers.
+The function uses the xlsx library.
By default, it reads the first sheet and the first row as headers. You can pass a worksheet name +and/or a range to process as options.
+ +Unpacks the contents of a zip file and returns an array of files.
+ +The parsers.HTMLToText
converts HTML to plain text using html-to-text.
The parsers.code
function parses source code using the Tree Sitter
+library. It returns an AST (Abstract Syntax Tree) that can be used to analyze the code.
The parsers.math
function uses mathjs to parse a math expression.
The parsers.dotEnv
parses .env files, typically
+using for configuration files. This format is similar to the key=value
format.
Parse output of LLM similar to output of genaiscript def() function. +Expect text to look something like this:
+ +Also supported. +…
+ +Returns a list of parsed code sections.
+ +Parses error, warning annotations in various formats +into a list of objects.
+ + +The parsers.tokens
estimates the number of tokens in a string
+for the current model. This is useful for estimating the number of prompts that can be generated from a string.
The parsers.math
function uses mathjs to parse a math expression.
The parsers.validateJSON
function validates a JSON string against a schema.
The def
function will automatically parse PDF files and extract text from them. This is useful for generating prompts from PDF files.
The parsers.PDF
function reads a PDF file and attempts to cleanly convert it into a text format
+that is friendly to the LLM.
Once parse, you can use the file
and pages
to generate prompts. If the parsing fails, file
will be undefined
.
The PDF format was never really meant to allow for clean text extraction. The parsers.PDF
function uses the pdf-parse
package to extract text from the PDF. This package is not perfect and may fail to extract text from some PDFs. If you have access to the original document, it is recommended to use a more text-friendly format such as markdown or plain text.
The $
is a JavaScript tagged template that expands the string into the final prompt.
You can weave expressions in the template using ${...}
. Expression can be promises and will be awaited when rendering the final prompt.
It is possible to provide the start of the LLM response (assistant
message) in the script.
+This allows to steer the answer of the LLM to a specify syntax or format.
Use writeText
with the {assistant: true}
option to provide the assistant text.
Internally when invoking the LLM, an additional message is added to the query as if the LLM had generated this content.
+GenAIScript provides various utilities to retreive content and augment the prompt. This technique is typically referred as RAG (Retrieval-Augmentation-Generation) in the literature. GenAIScript uses llamaindex-ts which supports many vector database vendors.
+The retrieve.fuzzSearch
performs a “traditional” fuzzy search to find the most similar documents to the prompt.
The retrieve.vectorSearch
performs a embeddings search to find the most similar documents to the prompt.
The files
variable contains a list of files, with concatenated fragments, that are most similar to the prompt. The fragments
variable contains a list of fragments from the files that are most similar to the prompt.
By default, the retrieval uses OpenAI text-embedding-ada-002 embeddings. The first search might be slow as the files get indexed for the first time.
+You can index your project using the CLI.
+ + +You can control the chunk size, overlap and model used for index files. You can also create multiple indexes using the indexName
option.
The retrieval.webSearch
performs a web search using a search engine API. You will need to provide API keys for the search engine you want to use.
To enable Bing search, configure the BING_SEARCH_API_KEY
secret in your .env
file. Learn more about configuring the Bing Search API.
It is possible to force the LLM to generate data that conforms to a specific schema. +This technique works reasonably well and GenAIScript also provides automatic validation “just in case”.
+You will notice that the schema supported by GenAIScript is much simpler than the full-blow JSON schema specification. We recommend using simple schemas to avoid confusing the LLM; then port them to your application +specific data format later on.
+defSchema
Use defSchema
to define a JSON/YAML schema for the prompt output.
Following the “All You Need Is Types” approach +from TypeChat, the schema is converted TypeScript types before being injected in the LLM prompt.
+ +You can change this behavior by using the { format: "json" }
option.
Then tell the LLM to use this schema to generate data.
+ +When a JSON/YAML payload is generated with the schema identifier, +GenAIScript automatically validates the payload against the schema.
+ +GenAIScript will automatically try to repair the data by issues additional messages +back to the LLM with the parsing output.
+Use parsers.validateJSON
to validate JSON when running the script.
The env.secrets
object is used to access secrets from the environment. The secrets are typically stored in the .env
file in the root of the project (or in the process.env
for the CLI).
You must declare the list of required secrets in script({ secrets: ... })
+in order to use them in the script.
script
env.secrets
System prompts are scripts that are executed and injected before the main prompt output.
+system.*.genai.js
are considered system prompt templatessystem
instead of script
To use system prompts in script, populate the system
field with script identifiers.
It is also possible to populate system script by include tool names +which will result in importing the tool into the script.
+ +System also support parameters as script but the parameter names will automatically be prepended +with the script id
+GenAIScript comes with a number of system prompt that support features like creating files, extracting diffs or +generating annotations. If unspecified, GenAIScript looks for specific keywords to activate the various system prompts.
+system
Base system prompt
+ +system.annotations
Emits annotations compatible with GitHub Actions
+GitHub Actions workflows support annotations (Read more…).
+ +system.changelog
Generate changelog formatter edits
+ +system.diff
Generates concise file diffs.
+ +system.explanations
Explain your answers
+ +system.files
File generation
+Teaches the file format supported by GenAIScripts
+ +system.files_schema
Apply JSON schemas to generated data.
+ +system.fs_find_files
File Find Files
+Functions to list files.
+fs_find_files
: Finds file matching a glob pattern.system.fs_read_file
File Read File
+Function to read file content as text.
+fs_read_file
: Reads a file as text from the file system.system.fs_read_summary
File Read Summary
+Function to summarize the content of a file.
+fs_read_summary
: Reads a summary of a file from the file system.system.functions
use functions
+ +system.math
Math expression evaluator
+Register a function that evaluates math expressions
+math_eval
: Evaluates a math expressionsystem.python
Expert at generating and understanding Python code.
+ +system.retrieval_fuzz_search
Full Text Fuzzy Search
+Function to do a full text fuzz search.
+retrieval_fuzz_search
: Search for keywords using the full text of files and a fuzzy distance.system.retrieval_vector_search
Embeddings Vector Search
+Function to do a search using embeddings vector similarity distance.
+retrieval_vector_search
: Search files using embeddings and similarity distance.system.retrieval_web_search
Web Search
+Function to do a web search.
+retrieval_web_search
: Search the web for a user query using Bing Search.system.schema
JSON Schema support
+ +system.tasks
Generates tasks
+ +system.technical
Technical Writer
+ +system.typescript
Export TypeScript Developer
+ +system.zero_shot_cot
Zero-shot Chain Of Though
+Zero-shot Chain Of Though technique. More at https://learnprompting.org/docs/intermediate/zero_shot_cot.
+It is possible to define tests for the LLM scripts, to evaluate the output quality of the LLM +over time and model types.
+The tests are executed by promptfoo, a tool +for evaluating LLM output quality.
+The tests are declared in the script
function in your test.
+You may define one or many tests (array).
files
files
takes a list of file path (relative to the workspace) and populate the env.files
+variable while running the test. You can provide multiple files by passing an array of strings.
rubrics
rubrics
checks if the LLM output matches given requirements,
+using a language model to grade the output based on the rubric (see llm-rubric).
+You can specify multiple rubrics by passing an array of strings.
facts
facts
checks a factual consistency (see factuality).
+You can specify multiple facts by passing an array of strings.
++ + +given a completion A and reference answer B evaluates +whether A is a subset of B, A is a superset of B, A and B are equivalent, +A and B disagree, or A and B differ, +but difference don’t matter from the perspective of factuality.
+
asserts
Other assertions on +promptfoo assertions and metrics.
+icontains
(not-icontains"
) output contains substring case insensitiveequals
(not-equals
) output equals stringstarts-with
(not-starts-with
) output starts with stringcontains-all
(not-contains-all
) output contains all substringscontains-any
(not-contains-any
) output contains any substringicontains-all
(not-icontains-all
) output contains all substring case insensitiveBy default, the asserts
are executed on the raw LLM output.
+However, you can use a javascript expression to select a part of the output to test.
You can run tests from Visual Studio Code or using the command line. +In both cases, genaiscript generates a promptfoo configuration file +and execute promptfoo on it.
+Run the test
command with the script file as argument.
You can specify additional models to test against by passing the --models
option.
You can register tools (also known as functions) that the LLM may decide to call as part of assembling the answer. +See OpenAI functions.
+defTool
is used to define a tool that can be called by the LLM.
+It takes a JSON schema to define the input and expects a string output. The LLM decides to call
+this tool on its own!
In the example above, we define a tool called current_weather
+that takes a location as input and returns the weather.
This example uses the current_weather
tool to get the weather for Brussels.
This example uses the math expression evaluator +to evaluate a math expression.
+ +To pick and choose which tools to include in a script,
+you can group them in system scripts. For example,
+the current_weather
tool can be included the system.current_weather.genai.js
script.
then use the script id in the tools
field.
Let’s illustrate how tools come together with a question answering script.
+In the script below, we add the system.retrieval_web_search
which registers the retrieval_web_search
tool. This tool
+will call into retrieval.webSearch
as needed.
We can then apply this script to the questions.md
file blow.
After the first request, the LLM requests to call the web_search
for each questions.
+The web search answers are then added to the LLM message history and the request is made again.
+The second yields the final result which includes the web search results.
TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale. GenAIScript scripts can be authored in TypeScript.
+You can convert any existing script to typescript by changing the file name extension to .genai.mts
.
It is possible to import TypeScript source file +using dynamic imports.
+ +async import(...)
)No.
+GenAIScript converts TypeScript to JavaScript without type checks through tsx.
+Most modern editors, like like Visual Studio Code, will automatically +typecheck TypeScript sources.
The env.vars
object contains a set of variable values. You can use these variables to parameterize your script.
It is possible to declare parameters in the script
function call. The env.vars
object will contain the values of these parameters.
When invoking this script in VS Code, the user will be prompted to provide values for these parameters.
+Use the vars
field in the CLI to override variables. vars takes a sequence of key=value
pairs.
You can specify variables in the tests
object of the script
function. These variables will be available in the test scope.
The retrieval.vectorSearch
indexes the input files using embeddings into a vector database that can be used for similarity search. This is commonly referred to as Retrieval Augmented Generation (RAG).
The returned value is an array of files with the resconstructed content from the matching chunks.
+ +The computation of embeddings is done through the +LLM APIs using the same authorization token as the LLM API.
+The default model is openai:text-embedding-ada-002
but you can override the model using embedModel
.
You can further customize the embedding generation by using chunkSize
and chunkOverlap
.
If you modify the model or chunking configurations, you will want to create separate index databases.
+ +The retrieval uses LLamaindex TS for indexing and searching.
+The llamaindex
package will be automatically installed.
The retrieval.webSearch
executes a web search using the Bing Web Search API.
By default, the API returns the first 10 web pages in the webPages
field
+as an array of files, similarly to env.files
. The content contains
+the summary snippet returned by the search engine.
You can use fetchText
to download the full content of the web page.
The API uses Bing Web Search v7 to search the web. To use the API, you need to create a Bing Web Search resource in the Azure portal and store the API key in the .env
file.
Add the system.retrieval_web_search system script to register a tool that uses retrieval.webSearch
.
Parsing and stringifying of Excel spreadsheet files, xlsx.
+parsers
The parsers also provides merciful parser for XLSX. It returns an array of sheets (name
, rows
)
+where row is an array of objects.
YAML is a human-readable data serialization format that is commonly used for configuration files and data exchange.
+In the context of LLM, YAML is friendlier to the tokenizer algorithm and can generally be preferred to JSON to represent structured data.
+defData
The defData
function renders an object to YAML in the prompt (and other formats if needed).
YAML
Similarly to the JSON
class in JavaScript, the YAML
class in LLM provides methods to parse and stringify YAML data.
parsers
The parsers also provides merciful parser for YAML.
+Returns undefined
for invalid inputs.
JSON schemas defined with defSchema can also be used to validate YAML data.
We discuss various security risks and possible mitigations when using GenAIScript. +GenAISCript inherits the same security risks as running scripts, and adds some new threats due to the nature of the LLM-generated outputs.
+We also recommend reading the Transparency Note +to understand the capabilities and limitations of GenAIScript.
+Since the GenAIScript files .genai.js
are executable JavaScript files and are in fact using a JavaScript runtime (VSCode or Node). It is important to understand that the script can do anything that JavaScript can do. This includes reading and writing files, making network requests, and executing JavaScript arbitrary code.
A trusted script might use malicious files from the context to generate a malicious output. +For example, overriding files in the project with new malicious code.
+ +The extension is disabled when opening a folder in Restricted Mode in Visual Studio Code.
+The output of the LLM and the trace use the built-in markdown preview of Visual Studio Code.
+By default, VS Code restricts the content displayed in the Markdown preview.
+This includes disabling script execution and only allowing resources to be loaded over https
.
GenAIScript will try to find the connection token from various sources:
+.env
file in the root of your project (VSCode and CLI)The extension also supports the following set of variables:
+OPENAI_API_TYPE
, OPENAI_API_BASE
, OPENAI_API_KEY
, OPENAI_API_VERSION
variables.AZURE_OPENAI_API_ENDPOINT
or AZURE_OPENAI_API_BASE
, and AZURE_OPENAI_API_KEY
variables.AZURE_API_BASE
, AZURE_API_KEY
, AZURE_API_VERSION
variables.Additionally,
+OPENAI_API_BASE
can point to a local server, for example, http://localhost:1337/v1
as seen at https://jan.ai/api-reference/.OPENAI_API_TYPE
should be either azure
or local
. If not specified, the system will attempt to infer it based on the OPENAI_API_BASE
value.You can override the default .env
file name by adding the --env myother.env
file.
Run the script model
command to list the available scripts and their model configuration. This can be useful to diagnose configuration issues in CI/CD environments.
where [script] can be a script id or a file path.
GenAIScript is a framework that empowers teams, including +non-developers, to create and use AI-enhanced scripts to support their +workflows. GenAIScript provides support for authoring and debugging +JavaScript scripts that incorporate calls to foundation models and LLMs 1 +in their execution. GenAIScript is a programming framework that +allows its users to author AI scripts (which we call a GenAIScript), +debug those scripts in a development environment that is an extension of +VS Code, and package those scripts in a command-line interface that can +be deployed in many contexts.
+Our VS Code extension supports easy authoring of a GenAIScript by +writing natural language in markdown syntax plus a small amount of +stylized JavaScript programming. Our framework allows users to leverage +multiple LLM models, parameterize the calls to the models, execute and +debug scripts, trace the construction of the LLM prompts and provide a +full trace of execution from prompt construction to LLM generation to +parsing the LLM result. Our framework also supports extracting multiple +forms of output from LLM generations, including output in files of +different types, outputs intended as edits to existing files and outputs +in structured formats, such as JSON.
+GenAIScript A stylized JavaScript program that defines the context +for the LLM call, allows arbitrary JavaScript code execution, packages +the prompt input for the LLM, calls the LLM, and unpacks that LLM output +based on the directions given in the prompt.
+GPVM: A runtime system that given a GenAIScript and an optional +GPSpec, executes the GenAIScript, which involves integrating the context +into a prompt, calling the specified LLM, and extracting content from +the LLM result.
+VS Code GenAIScript extension An add-in to VS Code that provides +users with easy methods for creating, editing, running and debugging +GenAIScript.
+Foundation models and LLMs While GenAIScript currently supports +different LLMs, in the future we anticipate that we will incorporate +additional foundation models beyond large language models.
+GenAIScript is a general-purpose AI-script authoring framework for +seamlessly integrating code execution and foundation model/LLM +invocations. A GenAIScript is a JavaScript program in a stylized format +that allows users to easily specify the LLM context and prompt, invoked +a specified model, and parse the resulting output according to user +specifications. This functionality allows even users who are not +programmers to inspect model results and double check them for +correctness.
+GenAIScript can be written in any IDE but the VS Code GenAIScript add-in +makes creating, executing and debugging GenAIScript especially easy. +GenAIScript users can implement tools that generate and edit multiple +files with a single tool and our integration with VS Code leverages +existing functionality in for refactoring to allow users to easily see +the results of the tool execution. The add-in supports creating a new +GenAIScript, invoking a given GenAIScript, tracing the execution of the GenAIScript in establishing the LLM +context and final prompt, and unparsing the LLM output into the +user-specified elements. Examples of all of these capabilities can be +viewed in the documents in the GenAIScript repository: +microsoft/GenAIScript: Generative AI Scripting +(github.com)
+The goal of GenAIScript is to empower a broad range of potential users +to innovate with building AI-powered scripts and identify new ways to +leverage AI for their daily tasks. We expect that professional +developers, who are familiar with writing and using scripts to enhance +their productivity will be the early adopters of GenAIScript. +GenAIScript will give these users benefit because GenAIScript can do +many things that existing scripts written in traditional scripting +languages like JavaScript and Python cannot do. While developers can +leverage other frameworks, such as langchain and Semantic Kernel, that +integrate calls to LLMs into languages like Python, these +frameworks require more user effort and have less IDE support than +GenAIScript. Ultimately, because our goal is to make GenAIScript easy to +author, modify, debug and run, we anticipate that they will be useful +far beyond professional developers. A major impact of GenAIScript will +be to enable non-developers to innovate and build GenAIScripts that +enhance their productivity. We illustrate this point with examples +below.
+To help users get started with GenAIScript, we include documentation in +our repository that illustrates in code snippets the contents of several +different GenAIScripts. The documentation shows both what the example +GenAIScript looks like as well as what the effect is from the +GenAIScript acting on a particular input. While these examples are +intended to explain the technology, they are not intended to be the +basis for user-written tools.
+GenAIScript can be used in any context where a command line script +written in another programming language might be used but the use cases +are much more ambitious because the LLM can do much more than ordinary +code. Here are some examples:
+Checking for potential inconsistencies in a collection of +configuration files or other content. Using the LLM, a GenAIScript +can inspect configuration files and leverage the LLM’s understanding +of common configuration errors to detect and report them. Before +LLMs, professional developers would write tools, such as lint2, +which are complex programs that detect inconsistencies in the syntax +of their code files. With GenAIScript, checking tools can be written +for much richer scenarios (such as checking for inappropriate +variable names), and by individuals who are not professional +developers.
+Automating document translation: Given documentation in a +repository written in one natural language, a GenAIScript can be +written to translate that documentation into another language. For a +specific example of why GenAIScript is important for this use, +consider the task of maintaining the localization of the +MakeCode3 documentation. MakeCode documentation has nearly 2M +files, which are typically markdown with a mix of code snippets. +Many documents are partially translated (at the paragraph level). To check the correctness of +document translations, there are +3500 registered volunteer translators for 35+ languages. One cannot +just apply Bing translate for this use case, as it typically destroys the code +snippets. With GenAIScript, we can have a script that goes through +every documentation file, pulls the current localized version and +assembles a prompt to ask the LLM to fill in the missing +translations, while leaving the existing ones alone. Because the LLM model we use has already been trained on +MakeCode examples and documentation it is aware of the syntax.
+Generating executable code from a natural language +specification. A GPSpec file can be used to specify the task being +performed and a GenAIScript that specializes in code generation can +translate the spec into code.
+Creating a short version of a longer white paper by summarizing +each chapter. LLMs are quite effective at summarizing documents. A +GenAIScript can be written to take each chapter of a long document +and summarize it in a section of a shorter document.
+Translating a monolog to a dialog. Given a monolog from a video +transcript, a GenAIScript can be written to rewrite the monolog into +a dialog between two individuals (akin to sports announcers talking +to each other) to make the video more interesting and accessible.
+GenAIScript is a general framework for authoring scripts. As a result, +an adversary can use GenAIScript to author adversarial scripts that +could be used for malicious purposes. All of the adversarial uses of +GenAIScript could also be implemented in other LLM language extension +frameworks such as Sematic Kernel, autogen, and langchain, so the danger +from unintended uses of GenAIScript stems from possibility that it might +make it easier to author adversarial scripts. This issue is present in +any infrastructure that makes programming easier, including languages +such as PowerShell, JavaScript, and Python, as well as IDEs such as VS +Code and Visual Studio. While we cannot prevent unintended uses, we will +encourage users to consider Responsible AI practices when they build +GenAIScripts. We provide more details about issues related to security and trust in security and trust.
+We strongly encourage GenAIScript users to use foundation models and +LLMs that support robust Responsible AI mitigations, such as the Azure +Open AI (AOAI) services. Such services continually update the safety and +RAI mitigations to track our up-to-date understanding on how to deploy +and use foundation models most responsibly. Here are resources to help +understand and use best practices when employing foundations models +for scripts and applications:
+GenAIScript is an evolving framework that will improve based on input +from users. Existing limitations in the framework include integration into only one IDE +(VS code), and internal support for OpenAI APIs plus a relatively small +number of other LLMs. We intend to allow users to integrate calls to +external services (such as RAG) in GenAIScript to provide the LLM with +more context. We anticipate adding support for more foundation models as the use cases evolve.
+We also anticipate that the on-ramp to using GenAIScript will evolve. We +have explored supporting invoking the GenAIScript framework as part of a VS +Code Copilot Chat experience (hosted in VS Code Insider’s Edition). We also understand that some developers would prefer to +implement their GenAIScript using Python instead of JavaScript. We +anticipate building a Python binding form authoring GenAIScripts in the +future.
+GenAIScript does not use any AI model in executing the framework itself. +Individuals using GenAIScript to author their own AI scripts will be +subject to the technical limitations, operational factors, and ranges of +the AI LLM their script uses.
+GenAIScript encourages users to consult the best practices for authoring +effective prompts for the specific LLM they are invoking in their tool.
+Microsoft responsible AI +resources
+Microsoft Azure Learning courses on responsible +AI
+Read more about GenAIScript at our GitHub site, microsoft/GenAIScript: GenAI +Scripting (github.com)
+Give us feedback on this document: zorn@microsoft.com, +jhalleux@microsoft.com
+© 2024 Microsoft Corporation. All rights reserved. This document is +provided “as-is” and for informational purposes only. Information and +views expressed in this document, including URL and other Internet Web +site references, may change without notice. You bear the risk of using +it. Some examples are for illustration only and are fictitious. No real +association is intended or inferred.
+This document is not intended to be, and should not be construed as +providing. legal advice. The jurisdiction in which you’re operating may +have various regulatory or legal requirements that apply to your AI +system. Consult a legal specialist if you are uncertain about laws or +regulations that might apply to your system, especially if you think +those might impact these recommendations. Be aware that not all of these +recommendations and resources will be appropriate for every scenario, +and conversely, these recommendations and resources may be insufficient +for some scenarios.
+Published: March 18, 2024
+Last updated: March 18, 2024
+Throughout this document when we refer to LLMs we mean any +foundation model that is compatible with our interfaces. ↩
+${e.children.map(t).join("")}
`:`Unsupported markdown: ${e.type}`}return r.map(t).join("")}function Mr(n){return Intl.Segmenter?[...new Intl.Segmenter().segment(n)].map(r=>r.segment):[...n]}function jr(n,r){const t=Mr(r.content);return gt(n,[],t,r.type)}function gt(n,r,t,e){if(t.length===0)return[{content:r.join(""),type:e},{content:"",type:e}];const[u,...i]=t,l=[...r,u];return n([{content:l.join(""),type:e}])?gt(n,l,i,e):(r.length===0&&u&&(r.push(u),t.shift()),[{content:r.join(""),type:e},{content:t.join(""),type:e}])}function Rr(n,r){if(n.some(({content:t})=>t.includes(` +`)))throw new Error("splitLineToFitWidth does not support newlines in the line");return Bn(n,r)}function Bn(n,r,t=[],e=[]){if(n.length===0)return e.length>0&&t.push(e),t.length>0?t:[];let u="";n[0].content===" "&&(u=" ",n.shift());const i=n.shift()??{content:" ",type:"normal"},l=[...e];if(u!==""&&l.push({content:u,type:"normal"}),l.push(i),r(l))return Bn(n,r,t,l);if(e.length>0)t.push(e),n.unshift(i);else if(i.content){const[a,f]=jr(r,i);t.push([a]),f.content&&n.unshift(f)}return Bn(n,r,t)}function qr(n,r){r&&n.attr("style",r)}function Hr(n,r,t,e,u=!1){const i=n.append("foreignObject"),l=i.append("xhtml:div"),a=r.label,f=r.isNode?"nodeLabel":"edgeLabel";l.html(` + "+a+""),qr(l,r.labelStyle),l.style("display","table-cell"),l.style("white-space","nowrap"),l.style("max-width",t+"px"),l.attr("xmlns","http://www.w3.org/1999/xhtml"),u&&l.attr("class","labelBkg");let c=l.node().getBoundingClientRect();return c.width===t&&(l.style("display","table"),l.style("white-space","break-spaces"),l.style("width",t+"px"),c=l.node().getBoundingClientRect()),i.style("width",c.width),i.style("height",c.height),i.node()}function Pn(n,r,t){return n.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",r*t-.1+"em").attr("dy",t+"em")}function Nr(n,r,t){const e=n.append("text"),u=Pn(e,1,r);_n(u,t);const i=u.node().getComputedTextLength();return e.remove(),i}function Qr(n,r,t){var e;const u=n.append("text"),i=Pn(u,1,r);_n(i,[{content:t,type:"normal"}]);const l=(e=i.node())==null?void 0:e.getBoundingClientRect();return l&&u.remove(),l}function Vr(n,r,t,e=!1){const i=r.append("g"),l=i.insert("rect").attr("class","background"),a=i.append("text").attr("y","-10.1");let f=0;for(const c of t){const p=x=>Nr(i,1.1,x)<=n,m=p(c)?[c]:Rr(c,p);for(const x of m){const h=Pn(a,f,1.1);_n(h,x),f++}}if(e){const c=a.node().getBBox(),p=2;return l.attr("x",-p).attr("y",-p).attr("width",c.width+2*p).attr("height",c.height+2*p),i.node()}else return a.node()}function _n(n,r){n.text(""),r.forEach((t,e)=>{const u=n.append("tspan").attr("font-style",t.type==="emphasis"?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight",t.type==="strong"?"bold":"normal");e===0?u.text(t.content):u.text(" "+t.content)})}const Ur=(n,r="",{style:t="",isTitle:e=!1,classes:u="",useHtmlLabels:i=!0,isNode:l=!0,width:a=200,addSvgBackground:f=!1}={})=>{if(At.info("createText",r,t,e,u,i,l,f),i){const c=_r(r),p={isNode:l,label:zt(c).replace(/fa[blrs]?:fa-[\w-]+/g,x=>``),labelStyle:t.replace("fill:","color:")};return Hr(n,p,a,u,f)}else{const c=Pr(r);return Vr(a,n,c,f)}};export{Qr as a,Ur as c}; diff --git a/slides/default/assets/edges-ce5cfb7c-CM4K0b8N.js b/slides/default/assets/edges-ce5cfb7c-CM4K0b8N.js new file mode 100644 index 0000000000..3fe02c44c3 --- /dev/null +++ b/slides/default/assets/edges-ce5cfb7c-CM4K0b8N.js @@ -0,0 +1,4 @@ +import{o as H,c as b,d as V,ap as q,h as E,l as g,v as j,aq as lt}from"./slidev/Mermaid.vue_vue_type_script_setup_true_lang-DjAPIC6b.js";import{c as st}from"./createText-b70fe78a-CAuaGbFR.js";import{l as ct}from"./line-87f517ef-DbskcX7L.js";const ht=(e,t,a,i)=>{t.forEach(l=>{wt[l](e,a,i)})},ot=(e,t,a)=>{g.trace("Making markers for ",a),e.append("defs").append("marker").attr("id",a+"_"+t+"-extensionStart").attr("class","marker extension "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-extensionEnd").attr("class","marker extension "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},yt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-compositionStart").attr("class","marker composition "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-compositionEnd").attr("class","marker composition "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},pt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-aggregationStart").attr("class","marker aggregation "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-aggregationEnd").attr("class","marker aggregation "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},ft=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-dependencyStart").attr("class","marker dependency "+t).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-dependencyEnd").attr("class","marker dependency "+t).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},xt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-lollipopStart").attr("class","marker lollipop "+t).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),e.append("defs").append("marker").attr("id",a+"_"+t+"-lollipopEnd").attr("class","marker lollipop "+t).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},dt=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-pointEnd").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-pointStart").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},gt=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-circleEnd").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-circleStart").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},ut=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-crossEnd").attr("class","marker cross "+t).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-crossStart").attr("class","marker cross "+t).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},bt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},wt={extension:ot,composition:yt,aggregation:pt,dependency:ft,lollipop:xt,point:dt,circle:gt,cross:ut,barb:bt},hr=ht;function mt(e,t){t&&e.attr("style",t)}function kt(e){const t=E(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),a=t.append("xhtml:div"),i=e.label,l=e.isNode?"nodeLabel":"edgeLabel";return a.html('"+i+""),mt(a,e.labelStyle),a.style("display","inline-block"),a.style("white-space","nowrap"),a.attr("xmlns","http://www.w3.org/1999/xhtml"),t.node()}const vt=(e,t,a,i)=>{let l=e||"";if(typeof l=="object"&&(l=l[0]),H(b().flowchart.htmlLabels)){l=l.replace(/\\n|\n/g,"