Skip to Content
We are live but in Staging πŸŽ‰
Scriptum LanguageStepsCore Action Steps

Core Action Steps

The core steps do the actual work: do calls a tool, and let computes a value. This page covers both, then walks through the three kinds of capability you can invoke with do β€” native tools, K3 / Ignite tools, and the built-in model capabilities (llm, embed, rerank, transcribe, infer).

do β€” call a tool

do is the workhorse. It names the action, picks a tool with with, passes named inputs, and binds the result.

do "Search the web" with web_search query = topic max_results = 20 -> results
  • The string is the step label.
  • with web_search selects the tool (which must be in the tools block β€” except for the internal model capabilities below, which need no declaration).
  • Each indented name = expr line is a named input. They are validated against the tool’s input schema: required inputs must be present, and types must match.
  • -> results binds the tool’s full output object.

A short form puts the inputs in braces on one line:

do "Quick search" with web_search { query = topic } -> results

Each do can carry one on error: recovery clause (retry, fallback, or ignore) β€” see Error Handling.

let β€” compute a value

let binds the result of an expression to a name. Unlike do, it calls no tool β€” it is pure computation over values already in scope.

let counter = counter + 1 let is_ready = status == "ready" and retries < 3 let query_vector = [0.5, 0.3, 0.8, 0.1] let cosine_scores = map(raw_scores, item => item.similarity) let resolved_url = transferred.content.url

Use let to reshape data, derive flags for check/decide, build records for a later tool call, or hold a running counter inside repeat.

Invoking native tools

Native tools are built-in Rust functions β€” file operations, search, shell, HTTP, vector-store writes, K3 table writes, and the echo passthrough used for testing. They are always available; import them from native.

import tools file_glob from native echo from native do "Find Rust files" with file_glob pattern = "crates/scriptum-compiler/src/*.rs" -> glob_result do "Tag a file" with echo message = glob_result.matches[0] -> tagged

Invoking K3 / Ignite tools

K3 is where structured data lands. K3 (and other Ignite-backed) tools are imported by name β€” often namespaced and aliased β€” and called exactly like native tools. Below, a transcript is written into a K3 table: first ensure the schema, then insert rows. (Adapted from templates/vision/audio_transcription.scriptum.)

import tools k3_table_ensure_schema from native k3_table_insert from native env K3_GRPC_ENDPOINT = "" K3_SERVICE_ACCOUNT_ID = "" K3_SERVICE_ACCOUNT_SECRET = "" do "Ensure Schema" with k3_table_ensure_schema bucket = bucket table_name = table_name org_id = org_id columns = { input_ref: { type: "text", nullable: false }, transcript: { type: "text", nullable: true }, summary: { type: "text", nullable: true }, created_at: { type: "timestamp", nullable: true, default: "CURRENT_TIMESTAMP()" } } merge_keys = merge_keys k3_endpoint = env(K3_GRPC_ENDPOINT) service_account_id = env(K3_SERVICE_ACCOUNT_ID) service_account_secret = env(K3_SERVICE_ACCOUNT_SECRET) -> ensured do "Write to warehouse" with k3_table_insert bucket = bucket table_name = table_name org_id = org_id rows = [{ input_ref: input_ref, transcript: transcript.text, summary: summary.text }] match_columns = merge_keys assume_schema_ok = true k3_endpoint = env(K3_GRPC_ENDPOINT) service_account_id = env(K3_SERVICE_ACCOUNT_ID) service_account_secret = env(K3_SERVICE_ACCOUNT_SECRET) -> wh_status

The pattern generalizes: Ignite serverless tools (text extraction, chunking, data-source resolution, vector-store operations) are imported under their namespace and aliased for readability:

import tools ignite::public::read_data_source as read_source ignite::public::chunk_text as chunk_text vector_store_insert from native do "Read Source" with read_source source = { provider: "Public" } object = { type: "Url", value: resolved_url } format = "String" -> raw_data

The internal model capabilities

Five capabilities are built into the engine and dispatched to Ignite’s managed model service. You call them with do ... with <name>, just like a tool, but they need no entry in the tools block.

Capabilitydo ... withWhat it does
llmwith llmLLM chat completion
embedwith embedtext / multimodal embeddings
rerankwith rerankdocument reranking against a query
transcribewith transcribeaudio / video β†’ text
inferwith infergeneric model inference (classification, detection, diarization, …)

llm β€” chat completion

Pass a prompt (and optional system, model, temperature, max_tokens). The output has a .text field with the completion. If you do not name a model, the managed LLM is used.

do "Classify" with llm system = "You are a document classification engine. Output valid JSON only." prompt = "Classify this text. Output JSON with document_type, topics, sensitivity.\n\nText:\n{text}" model = llm_model max_tokens = 512 -> classification emit "Done" tags = classification.text

You can run several models in one script just by setting model per call:

do "Deep analysis" with llm prompt = "In 3 bullet points, explain {topic}." model = "kimi-k2.5" -> analysis do "Quick summary" with llm prompt = "Summarize in one sentence: {analysis.text}" model = "moonshot-v1-auto" -> summary

embed β€” embeddings

Pass the texts to embed (and a model, optional dimensions, task_type, encoding_format). The output exposes the vectors under .data.

do "Embed text" with embed model = embed_model texts = [test_text, "A second sentence for batch embedding."] -> embed_result do "Log embed" with echo message = "Embed returned {count(embed_result.data)} vectors" -> embed_log

rerank β€” reranking

Pass a query and a list of documents; the output ranks them by relevance.

do "Rerank documents" with rerank model = rerank_model query = test_query documents = ["The fox is a clever animal.", "Dogs are loyal pets.", "The weather is sunny."] -> rerank_result do "Log rerank" with echo message = "Top index: {rerank_result.results[0].index}, score: {rerank_result.results[0].relevance_score}" -> rerank_log

transcribe β€” speech to text

Pass the audio (base64 content or a URL) and a model. The output has a .text field with the transcript.

do "Read audio" with read_source source = { provider: "Public" } object = { type: "Url", value: resolved_url } format = "Base64" -> audio_data do "Transcribe audio" with transcribe model = transcribe_model audio = audio_data.content -> transcript

infer β€” generic inference

infer runs any other model β€” classifiers, detectors, diarization β€” and returns raw model output (logits, labels) that you postprocess with Scriptum expressions.

do "Classify sentiment" with infer model = infer_model text = test_text -> infer_result
do "Audio classification" with infer model = audio_class_model input = { "type": "audio_url", "audio_url": resolved_url } -> cls_raw let probs = softmax(cls_raw.logits) let best_idx = argmax(probs) let label = cls_raw.labels[best_idx]

A worked example: internal models end to end

This script exercises embed, rerank, and infer in sequence and logs each result with echo. (Adapted from examples/test_internal_models.scriptum.)

script "test_internal_models" version "0.1.0" input test_text : text = "The quick brown fox jumps over the lazy dog." test_query : text = "What animal is mentioned?" embed_model : text = "jina-embeddings-v4" rerank_model : text = "jina-reranker-v2" infer_model : text = "distilbert-sst2" output embed_result : object rerank_result : object infer_result : object import tools echo from native ### Test Embed ### do "Embed text" with embed model = embed_model texts = [test_text, "A second sentence for batch embedding."] -> embed_result ### Test Rerank ### do "Rerank documents" with rerank model = rerank_model query = test_query documents = ["The fox is a clever animal.", "Dogs are loyal pets.", "The weather is sunny."] -> rerank_result ### Test Infer ### do "Classify sentiment" with infer model = infer_model text = test_text -> infer_result emit "Test Results" embed_result = embed_result rerank_result = rerank_result infer_result = infer_result

Next: orchestrate these actions with loops, branches, and parallelism in Control Flow & Concurrency.