Skip to main content
This is the monday assistant loop plus one new capability: uploading files in a tool call. It demonstrates the pattern behind every file-accepting tool.

How files work in an agent loop

Gmail’s send-email tool declares its attachments field as a file input ("format": "engini/file" in the tool schema). Two things follow:
  1. The model never produces base64. When Engini wraps the schema for the model, file fields become plain string fields. The model picks a file by name (a reference key), not by content.
  2. You decide what those names resolve to. You hand handle_tool_calls a registry of files; the SDK swaps the key the model chose for the real file and encodes it on the way out.

The recipe

Tell the model what’s available in the system prompt:
The loop is identical to the monday agent, with one changed line - the file registry:
The model decides which file to attach (by name); your code controls what those names resolve to. The model never sees file bytes. An unknown reference key raises EnginiValidationError.

Without an LLM

Outside an agent loop, pass a File straight into the tool call:

Run the original

python/examples/gmail-agent/ - includes a sample attachment; drop your own files into its files/ folder:
More on file handling (constructors, mime types, CLI --file): File inputs.