Standard Library
Turn ships a Standard Library written entirely in Turn. Every module is a .tn source file embedded directly in the turn binary at compile time. When you write use "std/net", the VM retrieves the Turn source, compiles it through the normal lexer, parser, and compiler pipeline, and returns a module value you call functions on immediately.
There is no Rust logic in the Standard Library. The modules call the VM's internal kernel traps (__sys_* functions) for actual system I/O, but all validation, capability enforcement, and API shaping happens in Turn code. The Standard Library is a first class demonstration that Turn is expressive enough to build itself.
Architecture
Turn's I/O model follows an operating system kernel design.
- Kernel traps (
__sys_fs_read,__sys_http_get, etc.) live in the Rust VM host. They are the raw system boundary. Agents cannot call them directly. - Standard Library modules (pure Turn) wrap each kernel trap and enforce capability based security. They validate that the caller holds the correct
Identitygrant before forwarding the call. - Agent code imports the Standard Library and passes
grant identitytokens to each function.
This two layer design means a prompt injection attack cannot bypass the Turn level security checks, and the kernel itself validates the Identity type at the Rust boundary as a second line of defense.
std/net
HTTP networking with capability gated access. Every call requires a network identity.
let net = use "std/net";
// Public (unauthenticated) request
let pub_id = grant identity::network("public");
let response = net.get({ "url": "https://api.example.com/data", "identity": pub_id });
// Authenticated request
let auth = grant identity::oauth("stripe");
let customers = net.get({
"url": "https://api.stripe.com/v1/customers",
"identity": auth
});
// POST request
let result = net.post({
"url": "https://api.example.com/webhook",
"body": "{\"event\": \"deploy\"}",
"identity": pub_id
});| Function | Signature | Identity |
|---|---|---|
net.get | ({ url: Str, identity: Identity }) -> Str | network(...) |
net.post | ({ url: Str, body: Str, identity: Identity }) -> Str | network(...) |
For public identities the VM sends the request without injecting credentials. For named identities like oauth("stripe") the VM looks up TURN_IDENTITY_STRIPE_TOKEN in the host environment and injects the Authorization: Bearer header automatically.
std/fs
File system access with capability gated security.
let fs = use "std/fs";
let json = use "std/json";
let id = grant identity::filesystem("local");
let content = fs.read({ "path": "./config.json", "identity": id });
let config = json.parse(content);
fs.write({
"path": "./output.json",
"content": json.stringify(config),
"identity": id
});| Function | Signature | Identity |
|---|---|---|
fs.read | ({ path: Str, identity: Identity }) -> Str | filesystem(...) |
fs.write | ({ path: Str, content: Str, identity: Identity }) -> null | filesystem(...) |
std/json
JSON parsing and serialization. No identity required. These are pure data transformations with no I/O.
let json = use "std/json";
let data = json.parse("{\"name\": \"Turn\", \"version\": 1}");
let name = data["name"];
let output = json.stringify({ "status": "ok", "result": name });
call("echo", output);| Function | Signature | Identity |
|---|---|---|
json.parse | (Str) -> Any | none |
json.stringify | (Any) -> Str | none |
std/time
Timestamps and execution pausing.
let time = use "std/time";
let start = time.now();
time.sleep(2.0);
let elapsed = time.now() - start;
call("echo", "Elapsed: " + elapsed + " seconds");| Function | Signature | Identity |
|---|---|---|
time.now | () -> Num | none |
time.sleep | (Num) -> null | none |
time.now() returns the Unix epoch in seconds as a floating point number.
std/env
Environment variable access with capability gated security.
let env = use "std/env";
let id = grant identity::environment("local");
let key = env.get({ "key": "OPENAI_API_KEY", "identity": id });
if key == null {
throw "OPENAI_API_KEY not set";
}
env.set({ "key": "APP_MODE", "value": "production", "identity": id });| Function | Signature | Identity |
|---|---|---|
env.get | ({ key: Str, identity: Identity }) -> Str or null | environment(...) |
env.set | ({ key: Str, value: Str, identity: Identity }) -> null | environment(...) |
std/regex
Regular expression matching and replacement. Pure computation, no identity required.
let re = use "std/regex";
let valid = re.matches("[0-9]+", "order-42");
call("echo", "Has number: " + valid);
let cleaned = re.replace(" ", "Electric bicycle", "_");
call("echo", cleaned);| Function | Signature | Identity |
|---|---|---|
re.matches | (pattern: Str, text: Str) -> Bool | none |
re.replace | (pattern: Str, text: Str, replacement: Str) -> Str | none |
std/math
Basic arithmetic helpers implemented in pure Turn. No kernel traps, no identity.
let math = use "std/math";
let biggest = math.max(42, 17);
let smallest = math.min(42, 17);
let distance = math.abs(-15);
call("echo", "Max: " + biggest);
call("echo", "Min: " + smallest);
call("echo", "Abs: " + distance);| Function | Signature | Identity |
|---|---|---|
math.max | (Num, Num) -> Num | none |
math.min | (Num, Num) -> Num | none |
math.abs | (Num) -> Num | none |