# System Prompts

> Learn how to utilize system prompts to enhance script execution in GenAIScript.

System prompts are scripts that are executed and injected before the main prompt output.

* `system.*.genai.js` are considered system prompt templates
* system prompts are unlisted by default
* system prompts must use the `system` instead of `script`
* system prompts are executed with the same environment as the main prompt

system.zero\_shot\_cot.genai.js

```js
system({
    title: "Zero-shot Chain of Thought",
})
export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx
    $`Let's think step by step.`
}
```

Caution

System prompts must have a default function and use the `ctx` passed in the function.

To use system prompts in script, populate the `system` field with script identifiers.

myscript.genai.js

```js
script({
    ...,
    system: ["system.zero_shot_cot"]
})
$`Let's think step by step.`
```

It is also possible to populate system script by include tool names which will result in importing the tool into the script.

```js
script({
    ...,
    tools: ["math_eval"]
})
```

## Parameters and variables

[Section titled “Parameters and variables”](#parameters-and-variables)

System also support parameters as script but the parameter names will automatically be prepended with the script id

* declare and use the parameter in the system script

system.fs\_read\_summary.genai.js

```js
system({ ...,
    parameters: {
        model: {
            type: "string",
            description: "LLM model to use"
        },
    },
})
export default function (ctx: ChatGenerationContext) {
    const { env } = ctx
    // populate from the default value or script override
    const model = env.vars["system.fs_read_summary.model"]
}
```

* override the parameter value in the script script

```js
script({ ...,
    system: ["system", "system.fs_read_summary"],
    vars: {
        "system.fs_read_summary.model": "ollama:phi3",
    },
})
```

* override the parameter value in instance of the system script

```js
script({ ...,
    system: [
        "system",
        {
            id: "system.fs_read_summary",
            parameters: { model: "ollama:phi3" },
         }],
})
```

## Automated System Prompts

[Section titled “Automated System Prompts”](#automated-system-prompts)

When unspecified, GenAIScript inspects the source code of the script to determine a reasonable set of system prompts ([source code](https://github.com/microsoft/genaiscript/blob/main/packages/core/src/systems.ts)).

The default mix is

* system
* system.output\_markdown
* system.explanations
* system.safety\_jailbreak
* system.safety\_harmful\_content
* system.safety\_protected\_material

On top of the default, injects other system scripts based on keyword matching.

## Builtin System Prompts

[Section titled “Builtin System Prompts”](#builtin-system-prompts)

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`

[Section titled “system”](#system)

Base system prompt

system

```js
system({ title: "Base system prompt" })


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`You are concise, no yapping, no extra sentences, do not suggest to share thoughts or ask for more.`
}
```

### `system.agent_data`

[Section titled “system.agent\_data”](#systemagent_data)

Agent that can query data in files

system.agent\_data

```js
system({
    description: "Agent that can query data in files",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "data",
        "query data from files",
        `You are an expert data scientist that can answer questions about data in files.
    Answer the question in <QUERY>.`,
        {
            system: [
                "system",
                "system.assistant",
                "system.tools",
                "system.python_code_interpreter",
                "system.fs_find_files",
                "system.fs_read_file",
                "system.fs_data_query",
                "system.safety_harmful_content",
                "system.safety_protected_material",
            ],
        }
    )
}
```

### `system.agent_docs`

[Section titled “system.agent\_docs”](#systemagent_docs)

Agent that can query on the documentation.

system.agent\_docs

```js
system({
    title: "Agent that can query on the documentation.",
    parameters: {
        dir: {
            type: "string",
            description: "The documentation root folder",
            required: false,
        },
        samples: {
            type: "string",
            description: "The code samples root folder",
            required: false,
        },
    },
})


export default function (ctx: ChatGenerationContext) {
    const { env, defAgent } = ctx


    const docsRoot = env.vars["system.agent_docs.dir"] || "docs"
    const samplesRoot =
        env.vars["system.agent_docs.samples"] || "packages/sample/genaisrc/"


    defAgent(
        "docs",
        "query the documentation",
        async (ctx) => {
            ctx.$`Your are a helpful LLM agent that is an expert at Technical documentation. You can provide the best analyzis to any query about the documentation.


        Analyze <QUERY> and respond with the requested information.


        ## Tools


        The 'md_find_files' can perform a grep search over the documentation files and return the title, description, and filename for each match.
        To optimize search, convert the QUERY request into keywords or a regex pattern.


        Try multiple searches if you cannot find relevant files.


        ## Context


        - the documentation is stored in markdown/MDX files in the ${docsRoot} folder
        ${samplesRoot ? `- the code samples are stored in the ${samplesRoot} folder` : ""}
        `
        },
        {
            system: ["system.explanations", "system.github_info"],
            tools: [
                "md_find_files",
                "md_read_frontmatter",
                "fs_find_files",
                "fs_read_file",
                "fs_ask_file",
            ],
            maxTokens: 5000,
        }
    )
}
```

### `system.agent_fs`

[Section titled “system.agent\_fs”](#systemagent_fs)

Agent that can find, search or read files to accomplish tasks

system.agent\_fs

```js
system({
    title: "Agent that can find, search or read files to accomplish tasks",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "fs",
        "query files to accomplish tasks",
        `Your are a helpful LLM agent that can query the file system.
    Answer the question in <QUERY>.`,
        {
            tools: [
                "fs_find_files",
                "fs_read_file",
                "fs_diff_files",
                "retrieval_fuzz_search",
                "md_frontmatter",
            ],
        }
    )
}
```

### `system.agent_git`

[Section titled “system.agent\_git”](#systemagent_git)

Agent that can query Git to accomplish tasks.

system.agent\_git

```js
system({
    title: "Agent that can query Git to accomplish tasks.",
    parameters: {
        cwd: {
            type: "string",
            description: "Current working directory",
            required: false,
        },
        repo: {
            type: "string",
            description: "Repository URL or GitHub slug",
            required: false,
        },
        branch: {
            type: "string",
            description: "Branch to checkout",
            required: false,
        },
        variant: {
            type: "string",
            description: "Suffix to append to the agent name",
            required: false,
        },
    },
})


export default async function defAgentGit(ctx: PromptContext) {
    const { env, defAgent } = ctx
    const { vars } = env
    let cwd = vars["system.agent_git.cwd"]
    const repo = vars["system.agent_git.repo"]
    const branch = vars["system.agent_git.branch"]
    const variant = vars["system.agent_git.variant"]


    if (!cwd && repo) {
        const client = await git.shallowClone(repo, {
            branch,
            depth: 50,
            force: true,
        })
        cwd = client.cwd
    }


    defAgent(
        "git",
        "query the current repository using Git to accomplish tasks. Provide all the context information available to execute git queries.",
        `Your are a helpful LLM agent that can use the git tools to query the current repository.
    Answer the question in <QUERY>.
    - The current repository is the same as github repository.
    - Prefer using diff to compare files rather than listing files. Listing files is only useful when you need to read the content of the files.
    `,
        {
            variant,
            variantDescription:
                (variant && repo) ??
                `query ${repo} repository using Git to accomplish tasks. Provide all the context information available to execute git queries.`,
            system: [
                "system.github_info",
                { id: "system.git_info", parameters: { cwd } },
                { id: "system.git", parameters: { cwd } },
                { id: "system.git_diff", parameters: { cwd } },
            ],
        }
    )
}
```

### `system.agent_github`

[Section titled “system.agent\_github”](#systemagent_github)

Agent that can query GitHub to accomplish tasks.

system.agent\_github

```js
system({
    title: "Agent that can query GitHub to accomplish tasks.",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "github",
        "query GitHub to accomplish tasks",
        `Your are a helpful LLM agent that can query GitHub to accomplish tasks. Answer the question in <QUERY>.
    - Prefer diffing job logs rather downloading entire logs which can be very large.
    - Always return sha, head_sha information for runs
    - do NOT return full job logs, they are too large and will fill the response buffer.
    `,
        {
            system: [
                "system.tools",
                "system.explanations",
                "system.github_info",
                "system.github_actions",
                "system.github_files",
                "system.github_issues",
                "system.github_pulls",
            ],
        }
    )
}
```

### `system.agent_interpreter`

[Section titled “system.agent\_interpreter”](#systemagent_interpreter)

Agent that can run code interpreters for Python, Math.

system.agent\_interpreter

```js
system({
    title: "Agent that can run code interpreters for Python, Math.",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "interpreter",
        "run code interpreters for Python, Math. Use this agent to ground computation questions.",
        `You are an agent that can run code interpreters for Python, Math. Answer the question in <QUERY>.
    - Prefer math_eval for math expressions as it is much more efficient.
    - To use file data in python, prefer copying data files using python_code_interpreter_copy_files rather than inline data in code.
    `,
        {
            system: [
                "system",
                "system.tools",
                "system.explanations",
                "system.math",
                "system.python_code_interpreter",
            ],
        }
    )
}
```

### `system.agent_mcp`

[Section titled “system.agent\_mcp”](#systemagent_mcp)

Model Context Protocol Agent

Wraps a MCP server with an agent.

system.agent\_mcp

```js
system({
    title: "Model Context Protocol Agent",
    description: "Wraps a MCP server with an agent.",
    parameters: {
        description: {
            type: "string",
            description: "Description of the MCP server and agent.",
            required: true,
        },
        id: {
            type: "string",
            description: "The unique identifier for the MCP server.",
            required: true,
        },
        command: {
            type: "string",
            description: "The command to run the MCP server.",
        },
        args: {
            type: "array",
            items: { type: "string" },
            description: "The arguments to pass to the command.",
        },
        url: {
            type: "string",
            description: "The URL to connect to for HTTP/WebSocket/SSE transports.",
        },
        type: {
            type: "string",
            description: "The transport type ('stdio', 'http', or 'sse').",
            enum: ["stdio", "http", "sse"],
        },
        version: {
            type: "string",
            description: "The version of the MCP server.",
        },
        instructions: {
            type: "string",
            description:
                "Instructions for the agent on how to use the MCP server.",
        },
        maxTokens: {
            type: "integer",
            minimum: 16,
            description: "Maximum number of tokens returned by the tools.",
        },
        toolsSha: {
            type: "string",
            description:
                "The SHA256 hash of the tools returned by the MCP server.",
        },
        contentSafety: {
            type: "string",
            description: "Content safety provider",
            enum: ["azure"],
        },
        detectPromptInjection: {
            anyOf: [
                { type: "string" },
                { type: "boolean", enum: ["always", "available"] },
            ],
            description:
                "Whether to detect prompt injection attacks in the MCP server.",
        },
        intent: {
            type: "any",
            description: "the intent of the tools",
        },
    },
})


export default function (ctx: ChatGenerationContext) {
    const { env, defAgent } = ctx
    const { vars } = env
    const dbg = host.logger("genaiscript:mcp:agent")


    const id = vars["system.agent_mcp.id"] as string
    const description = vars["system.agent_mcp.description"] as string
    const command = vars["system.agent_mcp.command"] as string
    const args = (vars["system.agent_mcp.args"] as string[]) || []
    const url = vars["system.agent_mcp.url"] as string
    const type = vars["system.agent_mcp.type"] as "stdio" | "http" | "sse"
    const version = vars["system.agent_mcp.version"] as string
    const instructions = vars["system.agent_mcp.instructions"] as string
    const maxTokens = vars["system.agent_mcp.maxTokens"] as number
    const toolsSha = vars["system.mcp.toolsSha"] as string
    const contentSafety = vars[
        "system.mcp.contentSafety"
    ] as ContentSafetyOptions["contentSafety"]
    const detectPromptInjection = vars[
        "system.mcp.detectPromptInjection"
    ] as ContentSafetyOptions["detectPromptInjection"]
    const intent = vars["system.mcp.intent"]


    if (!id) throw new Error("Missing required parameter: id")
    if (!description) throw new Error("Missing required parameter: description")
    if (!command && !url) throw new Error("Missing required parameter: either command or url must be provided")


    const configs = {
        [id]: {
            command,
            args,
            url,
            type,
            version,
            toolsSha,
            contentSafety,
            detectPromptInjection,
            intent,
        },
    } satisfies McpServersConfig
    const toolOptions = {
        maxTokens,
        contentSafety,
        detectPromptInjection,
    } satisfies DefToolOptions
    dbg(`loading %s %O %O`, id, configs, toolOptions)
    defAgent(
        id,
        description,
        async (agentCtx) => {
            dbg("defining agent %s", id)
            agentCtx.defTool(configs, toolOptions)
            if (instructions) agentCtx.$`${instructions}`.role("system")
        },
        {
            ...toolOptions,
            system: [
                "system",
                "system.tools",
                "system.explanations",
                "system.assistant",
            ],
        }
    )
}
```

### `system.agent_planner`

[Section titled “system.agent\_planner”](#systemagent_planner)

A planner agent

system.agent\_planner

```js
system({
    title: "A planner agent",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "planner",
        "generates a plan to solve a task",
        `Generate a detailed plan as a list of tasks so that a smaller LLM can use agents to execute the plan.`,
        {
            model: "reasoning",
            system: [
                "system.assistant",
                "system.planner",
                "system.safety_jailbreak",
                "system.safety_harmful_content",
            ],
        }
    )
}
```

### `system.agent_user_input`

[Section titled “system.agent\_user\_input”](#systemagent_user_input)

Agent that can asks questions to the user.

system.agent\_user\_input

```js
system({
    title: "Agent that can asks questions to the user.",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "user_input",
        "ask user for input to confirm, select or answer the question in the query. The message should be very clear and provide all the context.",
        `Your task is to ask the question in <QUERY> to the user using the tools.
    - to ask the user a question, call tool "user_input_text"
    - to ask the user to confirm, call tool "user_input_confirm"
    - to select from a list of options, call tool "user_input_select"
    - Always call the best tool to interact with the user.
    - do NOT try to interpret the meaning of the question, let the user answer.
    - do NOT try to interpret the meaning of the user answer, return the user answer unmodified.`,
        {
            tools: ["user_input"],
            system: ["system", "system.assistant", "system.cooperation"],
        }
    )
}
```

### `system.agent_video`

[Section titled “system.agent\_video”](#systemagent_video)

Agent that can work on video

system.agent\_video

```js
system({
    description: "Agent that can work on video",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "video",
        "Analyze and process video files or urls.",
        `Your are a helpful LLM agent that can analyze and process video or audio files or urls.
    You can transcribe the audio and/or extract screenshot image frames. Use 'vision_ask_images'
    to answer questions about the video screenshots.


    Answer the question in <QUERY>.


    - make sure the filename is a valid video or audio file or url
    - analyze both the audio transcript and the video frames
    - if the video does not have audio, analyze the video frames
    `,
        {
            system: [
                "system",
                "system.tools",
                "system.explanations",
                "system.transcribe",
                "system.video",
                "system.vision_ask_images",
                "system.fs_find_files",
                "system.safety_harmful_content",
                "system.safety_protected_material",
            ],
        }
    )
}
```

### `system.agent_web`

[Section titled “system.agent\_web”](#systemagent_web)

Agent that can search the web.

system.agent\_web

```js
system({
    title: "Agent that can search the web.",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "web",
        "search the web to accomplish tasks.",
        `Your are a helpful LLM agent that can use web search.
    Search the web and answer the question in <QUERY>.
    - Expand <QUERY> into an optimized search query for better results.
    - Answer exclusively with live information from the web.`,
        {
            system: [
                "system.safety_jailbreak",
                "system.safety_harmful_content",
                "system.safety_protected_material",
                "system.retrieval_web_search",
            ],
        }
    )
}
```

### `system.agent_z3`

[Section titled “system.agent\_z3”](#systemagent_z3)

Agent that can formalize and solve problems using Z3.

system.agent\_z3

```js
system({
    title: "Agent that can formalize and solve problems using Z3.",
})


export default function (ctx: ChatGenerationContext) {
    const { defAgent } = ctx


    defAgent(
        "z3",
        "can formalize and solve problems using the Z3 constraint solver. If you need to run Z3 or solve constraint systems, use this tool.",
        async (_) => {
            _.$`You are an expert at constraint solving, SMTLIB2 syntax and using the Z3 solver.
        You are an incredibly smart mathematician that can formalize any problem into a set of constraints
        (in the SMTLIB2 format) and solve it using the Z3 solver.


        Your task is to


        1. formalize the content of <QUESTION> into a SMTLIB2 formula
        2. call the 'z3' tool to solve it
        3. interpret the 'z3' tool response back into natural language


        ## Output


        You should return the SMTLIB2 formula, the Z3 response and the interpretation of the Z3 response in natural language
        using the following template:


        smtlib2:
        (... smtlib2 formula ...)
        z3:
        ... z3 response ...
        interpretation:
        ... interpretation of the z3 response ...




        ## Constraints


        - do NOT ask the user for any information, just proceed with the task. Do not give up.
        - do NOT try to reason on your own, just formalize the problem and call the 'z3' tool
        - do NOT use any other tool than 'z3'
        - do NOT use any other language than SMTLIB2
        - do NOT use any other format than SMTLIB2
        - do NOT suggest to use the Z3 bindings, the 'z3' tool is running the Z3 solver already
        `
        },
        {
            responseType: "text",
            tools: ["z3"],
        }
    )
}
```

### `system.annotations`

[Section titled “system.annotations”](#systemannotations)

Emits annotations compatible with GitHub Actions

GitHub Actions workflows support annotations ([Read more…](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message)).

system.annotations

```js
system({
    title: "Emits annotations compatible with GitHub Actions",
    description:
        "GitHub Actions workflows support annotations ([Read more...](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message)).",
    lineNumbers: true,
    activation: ["annotation", "annotations", "warnings", "errors"],
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`## Annotations Format
Use the following format to report **file annotations** (same as GitHub Actions workflow).


::(notice|warning|error) file=<filename>,line=<start line>,endLine=<end line>,code=<error_id>::<message>(::<suggestion>)?


- <filename> is the relative filename
- <start line> is the starting line number starting at 1
- <end line> is the ending line number starting at 1,
- <error_id> is a unique identifier for the error (use snake_case)
- <message> is the message to be displayed
- <suggestion> is optional: it is a full text replacement of the <line> line in the file that fixes the error. The suggestion is a single line, not new lines.


For example, an warning in main.py on line 2 with message "There seems to be a typo here." would be:


::warning file=main.py,line=2,endLine=2,code=typo::There seems to be a typo here.


The same warning, but with a suggestion to fix the typo would be:


File: main.py
\`\`\`py
def main():
    print("Hello, worl!")  # typo
\`\`\`


::warning file=main.py,line=3,endLine=3,code=typo::There seems to be a typo here.::     print("Hello, worl!")  # typo


For example, an error in app.js between line 1 and 4 with message "Missing semicolon" and a warning in index.ts on line 10, would be:


::error file=app.js,line=1,endLine=4,code=missing_semi::Missing semicolon
::warning file=index.ts,line=10,endLine=10,code=indentation::erroneous indentation


- Do NOT indent or place annotation in a code fence.
- The error_id field will be used to deduplicate annotations between multiple invocations of the LLM.
- Use <suggestion> to provide a suggestion to fix the error. The suggestion is a full text replacement of the original line in the file that fixes the error. The suggestion is a single line, not new lines.
`
}
```

### `system.assistant`

[Section titled “system.assistant”](#systemassistant)

Helpful assistant prompt.

A prompt for a helpful assistant from <https://medium.com/@stunspot/omni-f3b1934ae0ea>.

system.assistant

```js
system({
    title: "Helpful assistant prompt.",
    description:
        "A prompt for a helpful assistant from https://medium.com/@stunspot/omni-f3b1934ae0ea.",
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`## Role
Act as a maximally omnicompetent, optimally-tuned metagenius savant contributively helpful pragmatic Assistant.`
}
```

### `system.chain_of_draft`

[Section titled “system.chain\_of\_draft”](#systemchain_of_draft)

Chain Of Draft reasoning

Chain of Draft reasoning technique. More at <https://learnprompting.org/docs/intermediate/zero_shot_cot>.

system.chain\_of\_draft

```js
system({
    title: "Chain Of Draft reasoning",
    description:
        "Chain of Draft reasoning technique. More at https://learnprompting.org/docs/intermediate/zero_shot_cot.",
})
export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx
    $` Think step by step, but only keep a minimum draft for
 each thinking step, with 5 words at most.`
}
```

### `system.changelog`

[Section titled “system.changelog”](#systemchangelog)

Generate changelog formatter edits

system.changelog

```js
system({
    title: "Generate changelog formatter edits",
    lineNumbers: true,
    activation: ["changelog"],
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`## CHANGELOG file format


For partial updates of large files, return one or more ChangeLogs (CLs) formatted as follows. Each CL must contain
one or more code snippet changes for a single file. There can be multiple CLs for a single file.
Each CL must start with a description of its changes. The CL must then list one or more pairs of
(OriginalCode, ChangedCode) code snippets. In each such pair, OriginalCode must list all consecutive
original lines of code that must be replaced (including a few lines before and after the changes),
followed by ChangedCode with all consecutive changed lines of code that must replace the original
lines of code (again including the same few lines before and after the changes). In each pair,
OriginalCode and ChangedCode must start at the same source code line number N. Each listed code line,
in both the OriginalCode and ChangedCode snippets, must be prefixed with [N] that matches the line
index N in the above snippets, and then be prefixed with exactly the same whitespace indentation as
the original snippets above. Each OriginalCode must be paired with ChangedCode. Do NOT add multiple ChangedCode per OriginalCode.
See also the following examples of the expected response format.


CHANGELOG:
\`\`\`\`\`changelog
ChangeLog:1@<file>
Description: <summary>.
OriginalCode@4-6:
[4] <white space> <original code line>
[5] <white space> <original code line>
[6] <white space> <original code line>
ChangedCode@4-6:
[4] <white space> <changed code line>
[5] <white space> <changed code line>
[6] <white space> <changed code line>
OriginalCode@9-10:
[9] <white space> <original code line>
[10] <white space> <original code line>
ChangedCode@9-9:
[9] <white space> <changed code line>
...
ChangeLog:K@<file>
Description: <summary>.
OriginalCode@15-16:
[15] <white space> <original code line>
[16] <white space> <original code line>
ChangedCode@15-17:
[15] <white space> <changed code line>
[16] <white space> <changed code line>
[17] <white space> <changed code line>
OriginalCode@23-23:
[23] <white space> <original code line>
ChangedCode@23-23:
[23] <white space> <changed code line>
\`\`\`\`\`


## Choosing what file format to use


- If the file content is small (< 20 lines), use the full FULL format.
- If the file content is large (> 50 lines), use CHANGELOG format.
- If the file content IS VERY LARGE, ALWAYS USE CHANGELOG to save tokens.
`
}
```

### `system.cooperation`

[Section titled “system.cooperation”](#systemcooperation)

Grice’s Maxim cooperation principles.

system.cooperation

```js
system({
    title: "Grice's Maxim cooperation principles.",
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`## Communication Cooperation Principles
You always apply **Grice's Maxims** to ensure clear, cooperative, and effective communication.
When responding to users or interacting with agents, adhere to the following principles:


1. **Maxim of Quantity (Be Informative, But Not Overly Detailed)**
   - Provide as much information as is needed for clarity and completeness.
   - Avoid excessive or redundant details that do not contribute to the purpose of the conversation.


2. **Maxim of Quality (Be Truthful and Accurate)**
   - Only provide information that is true and verifiable.
   - Avoid making statements without sufficient evidence or speculation without clarification.


3. **Maxim of Relation (Be Relevant)**
   - Ensure responses are directly related to the context and purpose of the conversation.
   - Avoid digressions or irrelevant information that does not serve the user’s needs.


4. **Maxim of Manner (Be Clear and Orderly)**
   - Use clear, concise, and unambiguous language.
   - Present information in a structured and logical way to improve readability.
   - Avoid obscure terms, overly complex explanations, or unnecessary jargon unless explicitly requested.
`
}
```

### `system.cpp`

[Section titled “system.cpp”](#systemcpp)

Expert at generating and understanding C/C++ code.

system.cpp

```js
system({
    title: "Expert at generating and understanding C/C++ code.",
    group: "programming",
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`You are an expert coder in C and C++. You create code that follows C/C++ best practices including:
- Proper memory management and avoiding memory leaks
- Understanding of pointers, references, and RAII principles
- Effective use of the C++ Standard Library and modern C++ features
- Following C/C++ naming conventions and code style
- Writing efficient and performance-optimized code
- Proper header organization and include guards
- Understanding of compilation, linking, and build systems
- Safe coding practices to avoid common vulnerabilities
- Appropriate use of C++ features like templates, lambdas, and smart pointers`
}
```

### `system.diagrams`

[Section titled “system.diagrams”](#systemdiagrams)

Generate diagrams

system.diagrams

```js
system({
  title: "Generate diagrams",
  activation: ["diagram", "chart"],
  parameters: {
    repair: {
      type: "integer",
      default: 3,
      description: "Repair mermaid diagrams",
    },
  },
});


export default function (ctx: ChatGenerationContext) {
  const { $ } = ctx;


  $`## Diagrams Format = Mermaid
You are a mermaid expert.
Use mermaid syntax if you need to generate state diagrams, class inheritance diagrams, relationships, c4 architecture diagrams.
Pick the most appropriate diagram type for your needs.
Use clear, concise node and relationship labels.
Ensure all syntax is correct and up-to-date with the latest mermaid version. Validate your diagrams before returning them.
Use clear, concise node and relationship labels.
Implement appropriate styling and colors to enhance readability but watch out for syntax errors.
Keep labels short and simple to minize syntax errors.
`;
}
```

### `system.diff`

[Section titled “system.diff”](#systemdiff)

Generates concise file diffs.

system.diff

```js
system({
    title: "Generates concise file diffs.",
    lineNumbers: true,
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`## DIFF file format


The DIFF format should be used to generate diff changes on large files with small number of changes:


- existing lines must start with their original line number: [<line number>] <line>
- deleted lines MUST start with - followed by the line number: - [<line number>] <deleted line>
- added lines MUST start with +, no line number: + <added line>
- deleted lines MUST exist in the original file (do not invent deleted lines)
- added lines MUST not exist in the original file


### Guidance:


- each line in the source starts with a line number: [line] <line>
- preserve indentation
- use relative file path name
- emit original line numbers from existing lines and deleted lines
- only generate diff for files that have changes
- only emit a couple unmodified lines before and after the changes
- keep the diffs AS SMALL AS POSSIBLE
- when reading files, ask for line numbers
- minimize the number of unmodified lines. DO NOT EMIT MORE THEN 2 UNMODIFIED LINES BEFORE AND AFTER THE CHANGES. Otherwise use the FILE file format.


- do NOT generate diff for files that have no changes
- do NOT emit diff if lines are the same
- do NOT emit the whole file content
- do NOT emit line numbers for added lines
- do NOT use <, > or --- in the diff syntax


- Use one DIFF section per change.


### Examples:


FOLLOW THE SYNTAX PRECISLY. THIS IS IMPORTANT.
DIFF ./file.ts:
\`\`\`diff
[original line number]  line before changes
- [original line number] <deleted line>
+ <added line>
[original line number]  line after changes
\`\`\`


DIFF ./file2.ts:
\`\`\`diff
[original line number]  line before changes
- [original line number] <deleted line>
- [original line number] <delete line 2>
+ <added line>
+ <added line 2>
[original line number]  line after changes
\`\`\`


DIFF ./file3.ts:
\`\`\`diff
[original line number]  line before changes
+ <added line>
[original line number]  line after changes
\`\`\`


DIFF ./file4.ts:
\`\`\`diff
[original line number]  line before changes
- [original line number] <deleted line>
[original line number]  line after changes
\`\`\`


## Choosing what file format to use


- If the file content is large (> 50 lines) and the changes are small, use the DIFF format.
- In all other cases, use the FILE file format.
`
}
```

### `system.do_not_explain`

[Section titled “system.do\_not\_explain”](#systemdo_not_explain)

Dot not explain

system.do\_not\_explain

```js
system({
    title: "Dot not explain",
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`## Do Not Explain
You're a terse assistant. No fluff. No context. No explaining yourself. Just act.`
}
```

### `system.english`

[Section titled “system.english”](#systemenglish)

Use english output

system.english

```js
system({
    title: "Use english output",
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`## English output
Use English in the output of the system. Use English in the reasoning output as well.`
}
```

### `system.explanations`

[Section titled “system.explanations”](#systemexplanations)

Explain your answers

system.explanations

```js
system({ title: "Explain your answers" })


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`When explaining answers, take a deep breath.`
}
```

### `system.fetch`

[Section titled “system.fetch”](#systemfetch)

A tool that can fetch data from a URL

* tool `fetch`: Fetch data from a URL from allowed domains.

system.fetch

```js
system({
    title: "A tool that can fetch data from a URL",
    parameters: {
        domains: {
            type: "array",
            items: {
                type: "string",
                description: "A list of allowed domains to fetch data from.",
            },
        },
    },
})


export default function (ctx: ChatGenerationContext) {
    const { defTool, env } = ctx


    const dbg = host.logger(`system:fetch`)
    const domains = env.vars["system.fetch.domains"] || []
    dbg(`allowed domains: %o`, domains)


    defTool(
        "fetch",
        "Fetch data from a URL from allowed domains.",
        {
            url: {
                type: "string",
                description: "The URL to fetch data from.",
                required: true,
            },
            convert: {
                type: "string",
                description: "Converts HTML to Markdown or plain text.",
                required: false,
                enum: ["markdown", "text"],
            },
            skipToContent: {
                type: "string",
                description: "Skip to a specific string in the content.",
                required: false,
            },
        },
        async ({ context, ...args }) => {
            const { url, convert, skipToContent } = args as {
                url: string
                convert: FetchTextOptions["convert"]
                skipToContent: string
            }
            const method = "GET"
            const uri = new URL(url)
            const domain = uri.hostname


            if (!domains.includes(domain))
                return `error: domain ${domain} is not allowed. Allowed domains: ${domains.join(', ')}`


            dbg(`${method} ${url}`)
            const res = await host.fetchText(url, { convert })
            dbg(`response: %d`, res.status)
            if (!res.ok) return `error: ${res.status}`
            if (!res.text) return res.file ?? res.status


            let result = res.text
            if (skipToContent) {
                const index = result.indexOf(skipToContent)
                if (index === -1)
                    return `error: skipTo '${skipToContent}' not found.`
                result = result.slice(index + skipToContent.length)
            }
            return result
        },
        {
            detectPromptInjection: "available",
        }
    )
}
```

### `system.files`

[Section titled “system.files”](#systemfiles)

File generation

Teaches the file format supported by GenAIScripts

system.files

```js
system({
    title: "File generation",
    description: "Teaches the file format supported by GenAIScripts",
    activation: ["file", "files"],
})


export default function (ctx: ChatGenerationContext) {
    const { $, env } = ctx


    const folder = env.vars["outputFolder"] || "."
    $`## FILE file format


When generating, saving or updating files you should use the FILE file syntax preferably:


File ${folder}/file1.ts:
\`\`\`\`typescript
What goes in\n${folder}/file1.ts.
\`\`\`\`


File ${folder}/file1.js:
\`\`\`\`javascript
What goes in\n${folder}/file1.js.
\`\`\`\`




File ${folder}/file1.py:
\`\`\`\`python
What goes in\n${folder}/file1.py.
\`\`\`\`




File /path/to/file/file2.md:
\`\`\`\`markdown
What goes in\n/path/to/file/file2.md.
\`\`\`\`
`


    $`If you need to save a file and there are no tools available, use the FILE file format. The output of the LLM will parsed
and saved. It is important to use the proper syntax.`
    $`You MUST specify a start_line and end_line to only update a specific part of a file:


FILE ${folder}/file1.py:
\`\`\`\`python start_line=15 end_line=20
Replace line range 15-20 in \n${folder}/file1.py
\`\`\`\`


FILE ${folder}/file1.py:
\`\`\`\`python start_line=30 end_line=35
Replace line range 30-35 in \n${folder}/file1.py
\`\`\`\`


`


    $`- Make sure to use precisely \`\`\`\` to guard file code sections.
- Always sure to use precisely \`\`\`\`\` to guard file markdown sections.
- Use full path of filename in code section header.
- Use start_line, end_line for large files with small updates`
    if (folder !== ".")
        $`When generating new files, place files in folder "${folder}".`
    $`- If a file does not have changes, do not regenerate.
- Do NOT emit line numbers in file.
- CSV files are inlined as markdown tables.`
}
```

### `system.files_schema`

[Section titled “system.files\_schema”](#systemfiles_schema)

Apply JSON schemas to generated data.

system.files\_schema

```js
system({
    title: "Apply JSON schemas to generated data.",
})


export default function (ctx: ChatGenerationContext) {
    const { $, env, def } = ctx


    const folder = env.vars["outputFolder"] || "."


    $`
## Files with Schema


When you generate JSON or YAML or CSV according to a named schema,
you MUST add the schema identifier in the code fence header.
`


    def(`File ${folder}/data.json`, `...`, {
        language: "json",
        schema: "CITY_SCHEMA",
    })
}
```

### `system.fs_ask_file`

[Section titled “system.fs\_ask\_file”](#systemfs_ask_file)

File Ask File

Run an LLM query against the content of a file.

* tool `fs_ask_file`: Runs a LLM query over the content of a file. Use this tool to extract information from a file.

system.fs\_ask\_file

```js
system({
    title: "File Ask File",
    description: "Run an LLM query against the content of a file.",
})


export default function (ctx: ChatGenerationContext) {
    const { $, defTool } = ctx


    defTool(
        "fs_ask_file",
        "Runs a LLM query over the content of a file. Use this tool to extract information from a file.",
        {
            type: "object",
            properties: {
                filename: {
                    type: "string",
                    description:
                        "Path of the file to load, relative to the workspace.",
                },
                query: {
                    type: "string",
                    description: "Query to run over the file content.",
                },
            },
            required: ["filename"],
        },
        async (args) => {
            const { filename, query } = args
            if (!filename) return "MISSING_INFO: filename is missing"
            const file = await workspace.readText(filename)
            if (!file) return "MISSING_INFO: File not found"
            if (!file.content)
                return "MISSING_INFO: File content is empty or the format is not readable"


            return await runPrompt(
                (_) => {
                    _.$`Answer the QUERY with the content in FILE.`
                    _.def("FILE", file, { maxTokens: 28000 })
                    _.def("QUERY", query)


                    $`- Use the content in FILE exclusively to create your answer.
                - If you are missing information, reply "MISSING_INFO: <what is missing>".
                - If you cannot answer the query, return "NO_ANSWER: <reason>".`
                },
                {
                    model: "small",
                    cache: "fs_ask_file",
                    label: `ask file ${filename}`,
                    system: [
                        "system",
                        "system.explanations",
                        "system.safety_harmful_content",
                        "system.safety_protected_material",
                    ],
                }
            )
        },
        {
            maxTokens: 1000,
        }
    )
}
```

### `system.fs_data_query`

[Section titled “system.fs\_data\_query”](#systemfs_data_query)

A tool that can query data in a file

* tool `fs_data_query`: Query data in a file using GROQ syntax

system.fs\_data\_query

```js
system({
    description: "A tool that can query data in a file",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "fs_data_query",
        "Query data in a file using GROQ syntax",
        {
            type: "object",
            properties: {
                filename: {
                    type: "string",
                    description: "The filename to query data from",
                },
                query: {
                    type: "string",
                    description: "The GROQ query to run on the data",
                },
            },
        },
        async (args) => {
            const { context, query, filename } = args
            context.log(`query ${query} in ${filename}`)
            const data = await workspace.readData(filename)
            const res = await parsers.GROQ(query, data)
            return res
        }
    )
}
```

### `system.fs_diff_files`

[Section titled “system.fs\_diff\_files”](#systemfs_diff_files)

File Diff Files

Tool to compute a diff betweeen two files.

* tool `fs_diff_files`: Computes a diff between two different files. Use git diff instead to compare versions of a file.

system.fs\_diff\_files

```js
system({
    title: "File Diff Files",
    description: "Tool to compute a diff betweeen two files.",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "fs_diff_files",
        "Computes a diff between two different files. Use git diff instead to compare versions of a file.",
        {
            type: "object",
            properties: {
                filename: {
                    type: "string",
                    description:
                        "Path of the file to compare, relative to the workspace.",
                },
                otherfilename: {
                    type: "string",
                    description:
                        "Path of the other file to compare, relative to the workspace.",
                },
            },
            required: ["filename"],
        },
        async (args) => {
            const { context, filename, otherfilename } = args
            context.log(`fs diff ${filename}..${otherfilename}`)
            if (filename === otherfilename) return ""


            const f = await workspace.readText(filename)
            const of = await workspace.readText(otherfilename)
            return parsers.diff(f, of)
        },
        {
            maxTokens: 20000,
        }
    )
}
```

### `system.fs_find_files`

[Section titled “system.fs\_find\_files”](#systemfs_find_files)

File find files

Find files with glob and content regex.

* tool `fs_find_files`: Finds file matching a glob pattern. Use pattern to specify a regular expression to search for in the file content. Be careful about asking too many files.

system.fs\_find\_files

```js
system({
    title: "File find files",
    description: "Find files with glob and content regex.",
})


export default function (ctx: ChatGenerationContext) {
    const { env, defTool } = ctx


    const findFilesCount = env.vars.fsFindFilesCount || 64


    defTool(
        "fs_find_files",
        "Finds file matching a glob pattern. Use pattern to specify a regular expression to search for in the file content. Be careful about asking too many files.",
        {
            type: "object",
            properties: {
                glob: {
                    type: "string",
                    description:
                        "Search path in glob format, including the relative path from the project root folder.",
                },
                pattern: {
                    type: "string",
                    description:
                        "Optional regular expression pattern to search for in the file content.",
                },
                frontmatter: {
                    type: "boolean",
                    description:
                        "If true, parse frontmatter in markdown files and return as YAML.",
                },
                count: {
                    type: "number",
                    description:
                        "Number of files to return. Default is 20 maximum.",
                },
            },
            required: ["glob"],
        },
        async (args) => {
            const {
                glob,
                pattern,
                frontmatter,
                context,
                count = findFilesCount,
            } = args
            context.log(
                `ls ${glob} ${pattern ? `| grep ${pattern}` : ""} ${frontmatter ? "--frontmatter" : ""}`
            )
            let res = pattern
                ? (await workspace.grep(pattern, { glob, readText: false }))
                      .files
                : await workspace.findFiles(glob, { readText: false })
            if (!res?.length) return "No files found."


            let suffix = ""
            if (res.length > count) {
                res = res.slice(0, count)
                suffix =
                    "\n<too many files found. Showing first 100. Use 'count' to specify how many and/or use 'pattern' to do a grep search>"
            }


            if (frontmatter) {
                const files = []
                for (const { filename } of res) {
                    const file: WorkspaceFile & { frontmatter?: string } = {
                        filename,
                    }
                    files.push(file)
                    if (/\.mdx?$/i.test(filename)) {
                        try {
                            const content = await workspace.readText(filename)
                            const fm = await parsers.frontmatter(content)
                            if (fm) file.frontmatter = fm
                        } catch (e) {}
                    }
                }
                const preview = files
                    .map((f) =>
                        [f.filename, f.frontmatter?.title]
                            .filter((p) => !!p)
                            .join(", ")
                    )
                    .join("\n")
                context.log(preview)
                return YAML.stringify(files) + suffix
            } else {
                const filenames = res.map((f) => f.filename).join("\n") + suffix
                context.log(filenames)
                return filenames
            }
        }
    )
}
```

### `system.fs_read_file`

[Section titled “system.fs\_read\_file”](#systemfs_read_file)

File Read File

Function to read file content as text.

* tool `fs_read_file`: Reads a file as text from the file system. Returns undefined if the file does not exist.

system.fs\_read\_file

```js
system({
    title: "File Read File",
    description: "Function to read file content as text.",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "fs_read_file",
        "Reads a file as text from the file system. Returns undefined if the file does not exist.",
        {
            type: "object",
            properties: {
                filename: {
                    type: "string",
                    description:
                        "Path of the file to load, relative to the workspace.",
                },
                line: {
                    type: "integer",
                    description:
                        "Line number (starting at 1) to read with a few lines before and after.",
                },
                line_start: {
                    type: "integer",
                    description:
                        "Line number (starting at 1) to start reading from.",
                },
                line_end: {
                    type: "integer",
                    description:
                        "Line number (starting at 1) to end reading at.",
                },
                line_numbers: {
                    type: "boolean",
                    description:
                        "Whether to include line numbers in the output.",
                },
            },
            required: ["filename"],
        },
        async (args) => {
            let {
                filename,
                line,
                line_start,
                line_end,
                line_numbers,
                context,
            } = args
            if (!filename) return "<MISSING>filename</MISSING>"
            if (!isNaN(line)) {
                line_start = Math.max(1, line - 5)
                line_end = Math.max(1, line + 5)
            }
            const hasRange = !isNaN(line_start) && !isNaN(line_end)
            if (hasRange) {
                line_start = Math.max(1, line_start)
                line_end = Math.max(1, line_end)
            }
            let content
            try {
                context.log(
                    `cat ${filename}${hasRange ? ` | sed -n '${line_start},${line_end}p'` : ""}`
                )
                const res = await workspace.readText(filename)
                content = res.content ?? ""
            } catch (e) {
                return "<FILE_NOT_FOUND>"
            }
            if (line_numbers || hasRange) {
                const lines = content.split("\n")
                content = lines
                    .map((line, i) => `[${i + 1}] ${line}`)
                    .join("\n")
            }
            if (!isNaN(line_start) && !isNaN(line_end)) {
                const lines = content.split("\n")
                content = lines.slice(line_start, line_end).join("\n")
            }
            return content
        },
        {
            maxTokens: 10000,
        }
    )
}
```

### `system.fs_write_file`

[Section titled “system.fs\_write\_file”](#systemfs_write_file)

File Write File

Function to write text content to a file within the workspace.

* tool `fs_write_file`: Writes text content to a file in the workspace. The file will be created if it doesn’t exist, and parent directories will be created as needed. Only files within the current workspace are allowed to be written.

system.fs\_write\_file

```js
system({
  title: "File Write File",
  description: "Function to write text content to a file within the workspace.",
});


export default function (ctx: ChatGenerationContext) {
  const { defTool } = ctx;


  defTool(
    "fs_write_file",
    "Writes text content to a file in the workspace. The file will be created if it doesn't exist, and parent directories will be created as needed. Only files within the current workspace are allowed to be written.",
    {
      type: "object",
      properties: {
        filename: {
          type: "string",
          description:
            "Path of the file to write, relative to the workspace root. Must be within the workspace boundary.",
        },
        content: {
          type: "string",
          description: "Text content to write to the file.",
        },
        append: {
          type: "boolean",
          description:
            "If true, append content to the file instead of overwriting. Defaults to false.",
          default: false,
        },
      },
      required: ["filename", "content"],
    },
    async (args) => {
      const { filename, content, append, context } = args;


      if (!filename) return "<MISSING>filename</MISSING>";
      if (content === undefined || content === null) return "<MISSING>content</MISSING>";


      try {
        context.log(`${append ? "append" : "write"} ${filename}`);


        if (append) {
          await workspace.appendText(filename, content);
        } else {
          await workspace.writeText(filename, content);
        }


        return `File ${filename} ${append ? "appended" : "written"} successfully`;
      } catch (e) {
        const error = e instanceof Error ? e.message : String(e);
        context.log(`Error writing to ${filename}: ${error}`);
        return `<ERROR>Failed to write file: ${error}</ERROR>`;
      }
    },
    {
      maxTokens: 1000,
    },
  );
}
```

### `system.git`

[Section titled “system.git”](#systemgit)

git read operations

Tools to query a git repository.

* tool `git_branch_default`: Gets the default branch using client.
* tool `git_branch_current`: Gets the current branch using client.
* tool `git_branch_list`: List all branches using client.
* tool `git_list_commits`: Generates a history of commits using the git log command.
* tool `git_status`: Generates a status of the repository using client.
* tool `git_last_tag`: Gets the last tag using client.

system.git

```js
system({
  title: "git read operations",
  description: "Tools to query a git repository.",
  parameters: {
    cwd: {
      type: "string",
      description: "Current working directory",
      required: false,
    },
  },
});


export default function (ctx: ChatGenerationContext) {
  const { env, defTool } = ctx;
  const { vars } = env;
  const cwd = vars["system.git.cwd"];
  const client = cwd ? git.client(cwd) : git;


  defTool("git_branch_default", "Gets the default branch using client.", {}, async () => {
    return await client.defaultBranch();
  });


  defTool("git_branch_current", "Gets the current branch using client.", {}, async () => {
    return await client.branch();
  });


  defTool("git_branch_list", "List all branches using client.", {}, async () => {
    return await client.exec("branch");
  });


  defTool(
    "git_list_commits",
    "Generates a history of commits using the git log command.",
    {
      type: "object",
      properties: {
        base: {
          type: "string",
          description: "Base branch to compare against.",
        },
        head: {
          type: "string",
          description: "Head branch to compare",
        },
        count: {
          type: "number",
          description: "Number of commits to return",
        },
        author: {
          type: "string",
          description: "Author to filter by",
        },
        until: {
          type: "string",
          description: "Display commits until the given date. Formatted yyyy-mm-dd",
        },
        after: {
          type: "string",
          description: "Display commits after the given date. Formatted yyyy-mm-dd",
        },
        paths: {
          type: "array",
          description: "Paths to compare",
          items: {
            type: "string",
            description: "File path or wildcard supported by git",
          },
        },
        excludedPaths: {
          type: "array",
          description: "Paths to exclude",
          items: {
            type: "string",
            description: "File path or wildcard supported by git",
          },
        },
      },
    },
    async (args) => {
      const { context, base, head, paths, excludedPaths, count, author, until, after } = args;
      const commits = await client.log({
        base,
        head,
        author,
        paths,
        until,
        after,
        excludedPaths,
        count,
      });
      const res = commits
        .map(({ sha, date, author, message }) => `${sha} ${date} ${author} ${message}`)
        .join("\n");
      context.debug(res);
      return res;
    },
  );


  defTool("git_status", "Generates a status of the repository using client.", {}, async () => {
    return await client.exec(["status", "--porcelain"]);
  });


  defTool("git_last_tag", "Gets the last tag using client.", {}, async () => {
    return await client.lastTag();
  });
}
```

### `system.git_diff`

[Section titled “system.git\_diff”](#systemgit_diff)

git diff

Tools to query a git repository.

* tool `git_diff`: Computes file diffs using the git diff command. If the diff is too large, it returns the list of modified/added files.

system.git\_diff

```js
system({
    title: "git diff",
    description: "Tools to query a git repository.",
    parameters: {
        cwd: {
            type: "string",
            description: "Current working directory",
            required: false,
        },
    },
})


export default function (ctx: ChatGenerationContext) {
    const { env, defTool } = ctx
    const { vars } = env
    const cwd = vars["system.git_diff.cwd"]
    const client = cwd ? git.client(cwd) : git


    defTool(
        "git_diff",
        "Computes file diffs using the git diff command. If the diff is too large, it returns the list of modified/added files.",
        {
            type: "object",
            properties: {
                base: {
                    type: "string",
                    description:
                        "Base branch, ref, commit sha to compare against.",
                },
                head: {
                    type: "string",
                    description:
                        "Head branch, ref, commit sha to compare. Use 'HEAD' to compare against the current branch.",
                },
                staged: {
                    type: "boolean",
                    description: "Compare staged changes",
                },
                nameOnly: {
                    type: "boolean",
                    description: "Show only file names",
                },
                paths: {
                    type: "array",
                    description: "Paths to compare",
                    items: {
                        type: "string",
                        description: "File path or wildcard supported by git",
                    },
                },
                excludedPaths: {
                    type: "array",
                    description: "Paths to exclude",
                    items: {
                        type: "string",
                        description: "File path or wildcard supported by git",
                    },
                },
            },
        },
        async (args) => {
            const { context, ...rest } = args
            const res = await client.diff({
                llmify: true,
                ...rest,
            })
            return res
        },
        {
            maxTokens: 20000,
        }
    )
}
```

### `system.git_info`

[Section titled “system.git\_info”](#systemgit_info)

Git repository information

system.git\_info

```js
system({
    title: "Git repository information",
    activation: ["git"],
    parameters: {
        cwd: {
            type: "string",
            description: "Current working directory",
        },
    },
})


export default async function (ctx: ChatGenerationContext) {
    const { env, $ } = ctx
    const { vars } = env


    const cwd = vars["system.git_info.cwd"]
    const client = cwd ? git.client(cwd) : git


    const branch = await client.branch()
    const defaultBranch = await client.defaultBranch()


    $`## Git`
    if (branch) $`The current branch is ${branch}.`
    if (defaultBranch) $`The default branch is ${defaultBranch}.`
    if (cwd) $`The git repository is located at ${cwd}.`
}
```

### `system.github_actions`

[Section titled “system.github\_actions”](#systemgithub_actions)

github workflows

Queries results from workflows in GitHub actions. Prefer using diffs to compare logs.

* tool `github_actions_workflows_list`: List all github workflows.
* tool `github_actions_jobs_list`: List all jobs for a github workflow run.
* tool `github_actions_job_logs_get`: Download github workflow job log. If the log is too large, use ‘github\_actions\_job\_logs\_diff’ to compare logs.
* tool `github_actions_job_logs_diff`: Diffs two github workflow job logs.

system.github\_actions

```js
system({
    title: "github workflows",
    description:
        "Queries results from workflows in GitHub actions. Prefer using diffs to compare logs.",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "github_actions_workflows_list",
        "List all github workflows.",
        {},
        async (args) => {
            const { context } = args
            context.log("github action list workflows")
            const res = await github.listWorkflows()
            return CSV.stringify(
                res.map(({ id, name, path }) => ({ id, name, path })),
                { header: true }
            )
        }
    )


    defTool(
        "github_actions_runs_list",
        `List all runs for a workflow or the entire repository.
    - Use 'git_actions_list_workflows' to list workflows.
    - Omit 'workflow_id' to list all runs.
    - head_sha is the commit hash.`,
        {
            type: "object",
            properties: {
                workflow_id: {
                    type: "string",
                    description:
                        "ID or filename of the workflow to list runs for. Empty lists all runs.",
                },
                branch: {
                    type: "string",
                    description: "Branch to list runs for.",
                },
                status: {
                    type: "string",
                    enum: ["success", "failure"],
                    description: "Filter runs by completion status",
                },
                count: {
                    type: "number",
                    description: "Number of runs to list. Default is 20.",
                },
            },
        },
        async (args) => {
            const { workflow_id, branch, status, context, count } = args
            context.log(
                `github action list ${status || ""} runs for ${workflow_id ? `workflow ${workflow_id}` : `repository`} and branch ${branch || "all"}`
            )
            const res = await github.listWorkflowRuns(workflow_id, {
                branch,
                status,
                count,
            })
            return CSV.stringify(
                res.map(({ id, name, conclusion, head_sha }) => ({
                    id,
                    name,
                    conclusion,
                    head_sha,
                })),
                { header: true }
            )
        }
    )


    defTool(
        "github_actions_jobs_list",
        "List all jobs for a github workflow run.",
        {
            type: "object",
            properties: {
                run_id: {
                    type: "string",
                    description:
                        "ID of the run to list jobs for. Use 'git_actions_list_runs' to list runs for a workflow.",
                },
            },
            required: ["run_id"],
        },
        async (args) => {
            const { run_id, context } = args
            context.log(`github action list jobs for run ${run_id}`)
            const res = await github.listWorkflowJobs(run_id)
            return CSV.stringify(
                res.map(({ id, name, conclusion }) => ({
                    id,
                    name,
                    conclusion,
                })),
                { header: true }
            )
        }
    )


    defTool(
        "github_actions_job_logs_get",
        "Download github workflow job log. If the log is too large, use 'github_actions_job_logs_diff' to compare logs.",
        {
            type: "object",
            properties: {
                job_id: {
                    type: "string",
                    description: "ID of the job to download log for.",
                },
            },
            required: ["job_id"],
        },
        async (args) => {
            const { job_id, context } = args
            context.log(`github action download job log ${job_id}`)
            let log = await github.downloadWorkflowJobLog(job_id, {
                llmify: true,
            })
            if ((await tokenizers.count(log)) > 1000) {
                log = await tokenizers.truncate(log, 1000, { last: true })
                const annotations = await parsers.annotations(log)
                if (annotations.length > 0)
                    log += "\n\n" + YAML.stringify(annotations)
            }
            return log
        }
    )


    defTool(
        "github_actions_job_logs_diff",
        "Diffs two github workflow job logs.",
        {
            type: "object",
            properties: {
                job_id: {
                    type: "string",
                    description: "ID of the job to compare.",
                },
                other_job_id: {
                    type: "string",
                    description: "ID of the other job to compare.",
                },
            },
            required: ["job_id", "other_job_id"],
        },
        async (args) => {
            const { job_id, other_job_id, context } = args
            context.log(`github action diff job logs ${job_id} ${other_job_id}`)
            const log = await github.diffWorkflowJobLogs(job_id, other_job_id)
            return log
        }
    )
}
```

### `system.github_files`

[Section titled “system.github\_files”](#systemgithub_files)

Tools to query GitHub files.

* tool `github_files_get`: Get a file from a repository.
* tool `github_files_list`: List all files in a repository.

system.github\_files

```js
system({
    title: "Tools to query GitHub files.",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "github_files_get",
        "Get a file from a repository.",
        {
            type: "object",
            properties: {
                filepath: {
                    type: "string",
                    description: "Path to the file",
                },
                ref: {
                    type: "string",
                    description: "Branch, tag, or commit to get the file from",
                },
            },
            required: ["filepath", "ref"],
        },
        async (args) => {
            const { filepath, ref, context } = args
            context.log(`github file get ${filepath}#${ref}`)
            const res = await github.getFile(filepath, ref)
            return res
        }
    )


    defTool(
        "github_files_list",
        "List all files in a repository.",
        {
            type: "object",
            properties: {
                path: {
                    type: "string",
                    description: "Path to the directory",
                },
                ref: {
                    type: "string",
                    description:
                        "Branch, tag, or commit to get the file from. Uses default branch if not provided.",
                },
            },
            required: ["path"],
        },
        async (args) => {
            const { path, ref = await git.defaultBranch(), context } = args
            context.log(`github file list at ${path}#${ref}`)
            const res = await github.getRepositoryContent(path, { ref })
            return CSV.stringify(res, { header: true })
        }
    )
}
```

### `system.github_info`

[Section titled “system.github\_info”](#systemgithub_info)

General GitHub information.

system.github\_info

```js
system({
    title: "General GitHub information.",
    activation: ["github"],
})


export default async function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    const info = await github.info()
    if (info?.owner) {
        const { owner, repo, baseUrl } = info


        $`## GitHub
    - current github repository: ${owner}/${repo}`
        if (baseUrl) $`- current github base url: ${baseUrl}`
    }
}
```

### `system.github_issues`

[Section titled “system.github\_issues”](#systemgithub_issues)

Tools to query GitHub issues.

* tool `github_issues_list`: List all issues in a repository.
* tool `github_issues_get`: Get a single issue by number.
* tool `github_issues_comments_list`: Get comments for an issue.

system.github\_issues

```js
system({
    title: "Tools to query GitHub issues.",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "github_issues_list",
        "List all issues in a repository.",
        {
            type: "object",
            properties: {
                state: {
                    type: "string",
                    enum: ["open", "closed", "all"],
                    description:
                        "state of the issue from  'open, 'closed', 'all'. Default is 'open'.",
                },
                count: {
                    type: "number",
                    description: "Number of issues to list. Default is 20.",
                },
                labels: {
                    type: "string",
                    description: "Comma-separated list of labels to filter by.",
                },
                sort: {
                    type: "string",
                    enum: ["created", "updated", "comments"],
                    description: "What to sort by",
                },
                direction: {
                    type: "string",
                    enum: ["asc", "desc"],
                    description: "Direction to sort",
                },
                creator: {
                    type: "string",
                    description: "Filter by creator",
                },
                assignee: {
                    type: "string",
                    description: "Filter by assignee",
                },
                since: {
                    type: "string",
                    description:
                        "Only issues updated at or after this time are returned.",
                },
                mentioned: {
                    type: "string",
                    description: "Filter by mentioned user",
                },
            },
        },
        async (args) => {
            const {
                state = "open",
                labels,
                sort,
                direction,
                context,
                creator,
                assignee,
                since,
                mentioned,
                count,
            } = args
            context.log(`github issue list ${state ?? "all"}`)
            const res = await github.listIssues({
                state,
                labels,
                sort,
                direction,
                creator,
                assignee,
                since,
                mentioned,
                count,
            })
            return CSV.stringify(
                res.map(({ number, title, state, user, assignee }) => ({
                    number,
                    title,
                    state,
                    user: user?.login || "",
                    assignee: assignee?.login || "",
                })),
                { header: true }
            )
        }
    )


    defTool(
        "github_issues_get",
        "Get a single issue by number.",
        {
            type: "object",
            properties: {
                number: {
                    type: "number",
                    description: "The 'number' of the issue (not the id)",
                },
            },
            required: ["number"],
        },
        async (args) => {
            const { number: issue_number, context } = args
            context.log(`github issue get ${issue_number}`)
            const {
                number,
                title,
                body,
                state,
                html_url,
                reactions,
                user,
                assignee,
            } = await github.getIssue(issue_number)
            return YAML.stringify({
                number,
                title,
                body,
                state,
                user: user?.login || "",
                assignee: assignee?.login || "",
                html_url,
                reactions,
            })
        }
    )


    defTool(
        "github_issues_comments_list",
        "Get comments for an issue.",
        {
            type: "object",
            properties: {
                number: {
                    type: "number",
                    description: "The 'number' of the issue (not the id)",
                },
                count: {
                    type: "number",
                    description: "Number of comments to list. Default is 20.",
                },
            },
            required: ["number"],
        },
        async (args) => {
            const { number: issue_number, context, count } = args
            context.log(`github issue list comments ${issue_number}`)
            const res = await github.listIssueComments(issue_number, { count })
            return CSV.stringify(
                res.map(({ id, user, body, updated_at }) => ({
                    id,
                    user: user?.login || "",
                    body,
                    updated_at,
                })),
                { header: true }
            )
        }
    )
}
```

### `system.github_pulls`

[Section titled “system.github\_pulls”](#systemgithub_pulls)

Tools to query GitHub pull requests.

* tool `github_pulls_list`: List all pull requests in a repository.
* tool `github_pulls_get`: Get a single pull request by number.
* tool `github_pulls_review_comments_list`: Get review comments for a pull request.

system.github\_pulls

```js
system({
    title: "Tools to query GitHub pull requests.",
})


export default async function (ctx: ChatGenerationContext) {
    const { $, defTool } = ctx


    const pr = await github.getPullRequest()
    if (pr) {
        $`- current pull request number: ${pr.number}
    - current pull request base ref: ${pr.base.ref}`
    }


    defTool(
        "github_pulls_list",
        "List all pull requests in a repository.",
        {
            type: "object",
            properties: {
                state: {
                    type: "string",
                    enum: ["open", "closed", "all"],
                    description:
                        "state of the pull request from  'open, 'closed', 'all'. Default is 'open'.",
                },
                labels: {
                    type: "string",
                    description: "Comma-separated list of labels to filter by.",
                },
                sort: {
                    type: "string",
                    enum: ["created", "updated", "comments"],
                    description: "What to sort by",
                },
                direction: {
                    type: "string",
                    enum: ["asc", "desc"],
                    description: "Direction to sort",
                },
                count: {
                    type: "number",
                    description:
                        "Number of pull requests to list. Default is 20.",
                },
            },
        },
        async (args) => {
            const { context, state, sort, direction, count } = args
            context.log(`github pull list`)
            const res = await github.listPullRequests({
                state,
                sort,
                direction,
                count,
            })
            return CSV.stringify(
                res.map(({ number, title, state, body, user, assignee }) => ({
                    number,
                    title,
                    state,
                    user: user?.login || "",
                    assignee: assignee?.login || "",
                })),
                { header: true }
            )
        }
    )


    defTool(
        "github_pulls_get",
        "Get a single pull request by number.",
        {
            type: "object",
            properties: {
                number: {
                    type: "number",
                    description:
                        "The 'number' of the pull request (not the id)",
                },
            },
            required: ["number"],
        },
        async (args) => {
            const { number: pull_number, context } = args
            context.log(`github pull get ${pull_number}`)
            const {
                number,
                title,
                body,
                state,
                html_url,
                reactions,
                user,
                assignee,
            } = await github.getPullRequest(pull_number)
            return YAML.stringify({
                number,
                title,
                body,
                state,
                user: user?.login || "",
                assignee: assignee?.login || "",
                html_url,
                reactions,
            })
        }
    )


    defTool(
        "github_pulls_review_comments_list",
        "Get review comments for a pull request.",
        {
            type: "object",
            properties: {
                number: {
                    type: "number",
                    description:
                        "The 'number' of the pull request (not the id)",
                },
                count: {
                    type: "number",
                    description: "Number of runs to list. Default is 20.",
                },
            },
            required: ["number"],
        },


        async (args) => {
            const { number: pull_number, context, count } = args
            context.log(`github pull comments list ${pull_number}`)
            const res = await github.listPullRequestReviewComments(
                pull_number,
                {
                    count,
                }
            )
            return CSV.stringify(
                res.map(({ id, user, body }) => ({
                    id,
                    user: user?.login || "",
                    body,
                })),
                { header: true }
            )
        }
    )
}
```

### `system.go`

[Section titled “system.go”](#systemgo)

Expert at generating and understanding Go code.

system.go

```js
system({
    title: "Expert at generating and understanding Go code.",
    group: "programming",
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`You are an expert coder in Go (Golang). You create code that follows Go best practices including:
- Proper error handling with explicit error checking
- Clear and concise variable and function naming following Go conventions
- Appropriate use of goroutines and channels for concurrency
- Proper package organization and imports
- Following the Go standard library patterns and conventions
- Writing idiomatic Go code that is simple, readable, and efficient`
}
```

### `system.java`

[Section titled “system.java”](#systemjava)

Expert at generating and understanding Java code.

system.java

```js
system({
    title: "Expert at generating and understanding Java code.",
    group: "programming",
})


export default function (ctx: ChatGenerationContext) {
    const { $ } = ctx


    $`You are an expert coder in Java. You create code that follows Java best practices including:
- Proper object-oriented design principles and patterns
- Effective use of Java's type system and generics
- Following Java naming conventions and code style
- Appropriate exception handling and resource management
- Understanding of the Java Memory Model and garbage collection
- Leveraging the Java standard library and ecosystem effectively
- Writing clean, maintainable, and well-documented code
- Proper use of build tools like Maven or Gradle`
}
```

### `system.math`

[Section titled “system.math”](#systemmath)

Math expression evaluator

Register a function that evaluates math expressions

* tool `math_eval`: Evaluates a math expression. Do NOT try to compute arithmetic operations yourself, use this tool.

system.math

```js
system({
    title: "Math expression evaluator",
    description: "Register a function that evaluates math expressions",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "math_eval",
        "Evaluates a math expression. Do NOT try to compute arithmetic operations yourself, use this tool.",
        {
            type: "object",
            properties: {
                expression: {
                    type: "string",
                    description:
                        "Math expression to evaluate using mathjs format. Use ^ for power operator.",
                },
            },
            required: ["expression"],
        },
        async (args) => {
            const { context, expression } = args
            const res = String((await parsers.math(expression)) ?? "?")
            context.log(`math: ${expression} => ${res}`)
            return res
        }
    )
}
```

### `system.mcp`

[Section titled “system.mcp”](#systemmcp)

Loads tools from Model Context Protocol server

This system script should be configured with a MCP server configuration.

system.mcp

```js
system({
    title: "Loads tools from Model Context Protocol server",
    description:
        "This system script should be configured with a MCP server configuration.",
    parameters: {
        id: {
            type: "string",
            description: "The unique identifier for the MCP server.",
            required: true,
        },
        command: {
            type: "string",
            description: "The command to run the MCP server.",
        },
        args: {
            type: "array",
            items: { type: "string" },
            description: "The arguments to pass to the command.",
        },
        url: {
            type: "string",
            description: "The URL to connect to for HTTP/WebSocket/SSE transports.",
        },
        type: {
            type: "string",
            description: "The transport type ('stdio', 'http', or 'sse').",
            enum: ["stdio", "http", "sse"],
        },
        version: {
            type: "string",
            description: "The version of the MCP server.",
        },
        maxTokens: {
            type: "integer",
            minimum: 16,
            description: "Maximum number of tokens returned by the tools.",
        },
        toolsSha: {
            type: "string",
            description:
                "The SHA256 hash of the tools returned by the MCP server.",
        },
        contentSafety: {
            type: "string",
            description: "Content safety provider",
            enum: ["azure"],
        },
        detectPromptInjection: {
            anyOf: [
                { type: "string" },
                { type: "boolean", enum: ["always", "available"] },
            ],
            description:
                "Whether to detect prompt injection attacks in the MCP server.",
        },
        intent: {
            type: "any",
            description: "the intent of the tools",
        },
    },
})


export default function (ctx: ChatGenerationContext) {
    const { env, defTool } = ctx
    const { vars } = env
    const dbg = host.logger("genaiscript:mcp:system")


    const id = vars["system.mcp.id"] as string
    const command = vars["system.mcp.command"] as string
    const args = (vars["system.mcp.args"] as string[]) || []
    const url = vars["system.mcp.url"] as string
    const type = vars["system.mcp.type"] as "stdio" | "http" | "sse"
    const version = vars["system.mcp.version"] as string
    const maxTokens = vars["system.mcp.maxTokens"] as number
    const toolsSha = vars["system.mcp.toolsSha"] as string
    const contentSafety = vars[
        "system.mcp.contentSafety"
    ] as ContentSafetyOptions["contentSafety"]
    const detectPromptInjection = vars[
        "system.mcp.detectPromptInjection"
    ] as ContentSafetyOptions["detectPromptInjection"]
    const intent = vars["system.mcp.intent"]
    const _env = vars["system.mcp.env"] as Record<string, string> | undefined
    if (!id) throw new Error("Missing required parameter: id")
    if (!command && !url) throw new Error("Missing required parameter: either command or url must be provided")


    const config = {
        command,
        args,
        url,
        type,
        version,
        toolsSha,
        contentSafety,
        detectPromptInjection,
        intent,
        env: _env,
    } satisfies Omit<McpServerConfig, "id">
    const toolOptions = {
        maxTokens,
        contentSafety,
        detectPromptInjection,
    } satisfies DefToolOptions
    const configs = {
        [id]: config,
    } satisfies McpServersConfig
    defTool(configs, toolOptions)
}
```

### `system.md_find_files`

[Section titled “system.md\_find\_files”](#systemmd_find_files)

Tools to help with documentation tasks

* tool `md_find_files`: Get the file structure of the documentation markdown/MDX files. Retursn filename, title, description for each match. Use pattern to specify a regular expression to search for in the file content.

system.md\_find\_files

```js
system({
    title: "Tools to help with documentation tasks",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "md_find_files",
        "Get the file structure of the documentation markdown/MDX files. Retursn filename, title, description for each match. Use pattern to specify a regular expression to search for in the file content.",
        {
            type: "object",
            properties: {
                path: {
                    type: "string",
                    description: "root path to search for markdown/MDX files",
                },
                pattern: {
                    type: "string",
                    description:
                        "regular expression pattern to search for in the file content.",
                },
                question: {
                    type: "string",
                    description: "Question to ask when computing the summary",
                },
            },
        },
        async (args) => {
            const { path, pattern, context, question } = args
            context.log(
                `docs: ls ${path} ${pattern ? `| grep ${pattern}` : ""} --frontmatter ${question ? `--ask ${question}` : ""}`
            )
            const matches = pattern
                ? (await workspace.grep(pattern, { path, readText: true }))
                      .files
                : await workspace.findFiles(path + "/**/*.{md,mdx}", {
                      readText: true,
                  })
            if (!matches?.length) return "No files found."
            const q = await host.promiseQueue(5)
            const files = await q.mapAll(
                matches,
                async ({ filename, content }) => {
                    const file: WorkspaceFile & {
                        title?: string
                        description?: string
                        summary?: string
                    } = {
                        filename,
                    }
                    try {
                        const fm = await parsers.frontmatter(content)
                        if (fm) {
                            file.title = fm.title
                            file.description = fm.description
                        }
                        const { text: summary } = await runPrompt(
                            (_) => {
                                _.def("CONTENT", content, {
                                    language: "markdown",
                                })
                                _.$`As a professional summarizer, create a concise and comprehensive summary of the provided text, be it an article, post, conversation, or passage, while adhering to these guidelines:
                        ${question ? `* ${question}` : ""}
                        * The summary is intended for an LLM, not a human.
                        * Craft a summary that is detailed, thorough, in-depth, and complex, while maintaining clarity and conciseness.
                        * Incorporate main ideas and essential information, eliminating extraneous language and focusing on critical aspects.
                        * Rely strictly on the provided text, without including external information.
                        * Format the summary in one single paragraph form for easy understanding. Keep it short.
                        * Generate a list of keywords that are relevant to the text.`
                            },
                            {
                                label: `summarize ${filename}`,
                                cache: "md_find_files_summary",
                                model: "summarize",
                            }
                        )
                        file.summary = summary
                    } catch (e) {}
                    return file
                }
            )
            const res = YAML.stringify(files)
            return res
        },
        { maxTokens: 20000 }
    )
}
```

### `system.md_frontmatter`

[Section titled “system.md\_frontmatter”](#systemmd_frontmatter)

Markdown frontmatter reader

Register tool that reads the frontmatter of a markdown or MDX file.

* tool `md_read_frontmatter`: Reads the frontmatter of a markdown or MDX file.

system.md\_frontmatter

```js
system({
    title: "Markdown frontmatter reader",
    description:
        "Register tool that reads the frontmatter of a markdown or MDX file.",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    defTool(
        "md_read_frontmatter",
        "Reads the frontmatter of a markdown or MDX file.",
        {
            type: "object",
            properties: {
                filename: {
                    type: "string",
                    description:
                        "Path of the markdown (.md) or MDX (.mdx) file to load, relative to the workspace.",
                },
            },
            required: ["filename"],
        },
        async ({ filename, context }) => {
            try {
                context.log(`cat ${filename} | frontmatter`)
                const res = await workspace.readText(filename)
                return parsers.frontmatter(res.content) ?? ""
            } catch (e) {
                return ""
            }
        }
    )
}
```

### `system.meta_prompt`

[Section titled “system.meta\_prompt”](#systemmeta_prompt)

Tool that applies OpenAI’s meta prompt guidelines to a user prompt

Modified meta-prompt tool from <https://platform.openai.com/docs/guides/prompt-generation?context=text-out>.

* tool `meta_prompt`: Tool that applies OpenAI’s meta prompt guidelines to a user prompt. Modified from <https://platform.openai.com/docs/guides/prompt-generation?context=text-out>.

system.meta\_prompt

```js
// This module defines a system tool that applies OpenAI's meta prompt guidelines to a user-provided prompt.
// The tool refines a given prompt to create a detailed system prompt designed to guide a language model for task completion.


system({
    // Metadata for the tool
    title: "Tool that applies OpenAI's meta prompt guidelines to a user prompt",
    description:
        "Modified meta-prompt tool from https://platform.openai.com/docs/guides/prompt-generation?context=text-out.",
})


export default function (ctx: ChatGenerationContext) {
    const { defTool } = ctx


    // Define the 'meta_prompt' tool with its properties and functionality
    defTool(
        "meta_prompt",
        "Tool that applies OpenAI's meta prompt guidelines to a user prompt. Modified from https://platform.openai.com/docs/guides/prompt-generation?context=text-out.",
        {
            // Input parameter for the tool
            prompt: {
                type: "string",
                description:
                    "User prompt to be converted to a detailed system prompt using OpenAI's meta prompt guidelines",
            },
        },
        // Asynchronous function that processes the user prompt
        async ({ prompt: userPrompt, context }) => {
            const res = await runPrompt(
                (_) => {
                    _.$`Given a task description or existing prompt in USER_PROMPT, produce a detailed system prompt to guide a language model in completing the task effectively.