Skip to content

Code execution with file outputs

Enable hosted code execution, ask the model to plot a chart and save it as a file, and read the produced file from response.files — one shape across every supporting provider.

Server-side tools run code and return a text answer. But code execution can also produce files — a matplotlib chart, an exported CSV, generated data. Each provider surfaces those files in a completely different place; ORXA unifies them on response.files.

Step 1 — Ask for a file, read response.files

Section titled “Step 1 — Ask for a file, read response.files”
import { complete } from '@combycode/llm-sdk';
const { response } = await complete({
model: process.env.LLM_MODEL!, // openai/… , anthropic/… , or google/…
apiKey: process.env.LLM_API_KEY,
prompt:
'With matplotlib, plot y = x**2 for x in 1..5 and save the figure to a PNG file. ' +
'Produce the image as a downloadable file.',
tools: [{ type: 'code_interpreter' }],
maxTokens: 8000,
});
for (const f of response.files ?? []) {
console.log(f.source, f.id ?? f.url ?? `${(f.data ?? '').length} inline bytes`);
}

The identical code runs against OpenAI, Anthropic, and Google — you never touch a provider-specific result block.

response.files is unified, but the bytes arrive by different fields:

ProviderFields setHow to get the bytes
Anthropic{ id, source }Fetch via the Files API using id.
OpenAI{ url, source } (images) or { id, name, source } (container files)Fetch url, or the container file by id.
Google{ data, mimeType, source }data is base64 — decode directly.

FileOutput shape (response.files: FileOutput[]):

interface FileOutput {
id?: string; // provider file id — fetch via files API
name?: string; // filename, when provided
mimeType?: string; // when known
data?: string; // inline base64 (Google)
url?: string; // fetchable URL (OpenAI code-interpreter images)
source?: string; // 'code_execution'
}
import { complete } from '@combycode/llm-sdk';

// Same task as every official cell — but ONE file across all providers. Hosted
// code-execution file outputs surface uniformly on `response.files`; no per-provider
// block digging (container_file_citation vs bash_code_execution_output vs inlineData).
const t0 = performance.now();
const { response } = await complete({
  model: process.env.LLM_MODEL!,
  apiKey: process.env.LLM_API_KEY,
  prompt:
    'Use code execution: with matplotlib, plot y = x**2 for x in 1..5 and save the figure to ' +
    'a PNG file. Produce the image as a downloadable file and give me a link to it.',
  tools: [{ type: 'code_interpreter' }],
  maxTokens: 8000,
});

console.log(
  JSON.stringify({ result: `files:${response.files?.length ?? 0}`, ms: Math.round(performance.now() - t0) }),
);

The official cells each dig into a different structure — OpenAI reads code_interpreter_call image outputs plus container_file_citation annotations, Anthropic walks bash_code_execution_tool_resultbash_code_execution_output.file_id (on the beta endpoint), Google collects inlineData blobs. ORXA reads all three from one field: response.files.

  • Produce a real file to get a file. Providers return a downloadable file only when the code writes one (e.g. saving a chart). Code that prints to stdout yields text, not a FileOutput.
  • Anthropic beta routing is automatic — the SDK routes code-execution requests to the beta endpoint required for file outputs; you do nothing.
  • Files propagate through agent runs (createAgent / AgentLoop) too.

Next steps: