Skip to content

Containerized Tools

This guide shows how to create a tool that call an executable in a container. This is a flexible and secure way to run tools that may have dependencies or security concerns.

This is typically done by creating a container with a particular image (gcc here)

// start a fresh container
const container = await host.container({
image: "gcc",
})

then reusing the container in the tool invocations. You can return the result of container.exec from the tool and it will be handled by the runtime.

defTool(..., async (args) => {
...
// use container in tool
const res = await container.exec("gcc", ["main.c"])
return res
})

Example: GCC as a Tool

This sample uses the official GCC docker image to compile a C program as tool. The LLM engine will invoke the tool to validate the syntax of the generated code.

script({
model: "large",
})
let container = undefined
let sourceIndex = 0
defTool(
"gcc",
"GNU Compiler Collection (GCC), C/C++ compiler",
{
source: "",
},
async (args) => {
const { source } = args
if (!container) // lazy allocation of container
container = await host.container({
image: "gcc",
})
const fn = `tmp/${sourceIndex++}/main.c`
await container.writeText(fn, source)
const res = await container.exec("gcc", [fn])
return res
}
)
$`Generate a valid C program that prints "Hello, World!"`
👤 user
Generate a valid C program that prints "Hello, World!"
🤖 assistant
📠 tool call gcc (call_IH693jAqZaC7i3AkUa3eIFXi)
source: |-
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
🛠️ tool output call_IH693jAqZaC7i3AkUa3eIFXi
exitCode: 0
stdout: ""
stderr: ""
failed: false
🤖 assistant
File ./file1.c:
```c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
```