Puras has one primitive — the skill — and one knob that changes everything
about how it runs: the entrypoint field in skill.yaml.
entrypoint: SKILL.md # → agentic loop
entrypoint: main.py:run # → deterministic pipeline
Same submission API, same billing, same observability. They feel similar from the outside, but the trade-offs inside are different.
Agentic skills
When the entrypoint is a .md file, the worker treats the file as a system
prompt and starts an LLM tool-use loop. The model gets the platform
tools (bash, media, web_search, web_fetch, file_read, …) plus any
Python tools: you declared in skill.yaml, and it reasons its way to an
answer.
Reach for an agentic skill when:
- The task involves planning, retries, or judgement.
- You don't know in advance how many steps it takes.
- You want the agent to call a generic capability like image generation or web search.
Deterministic skills
When the entrypoint is <file>.py:<func>, the worker imports the module and
calls the function in an isolated subprocess. You write Python, you get a
result. No model loop, no tools — unless your code calls one explicitly via
from puras import media.
Reach for a deterministic skill when:
- The logic is well-specified.
- You want predictable cost and latency.
- You're orchestrating side-effects (database writes, third-party APIs, image processing).
Mixing the two
The common pattern: an agentic skill whose tools: list points at small
deterministic Python helpers in the same folder. The agent stays in charge of
planning; your code stays in charge of side-effects.
# skills/ad-creative/skill.yaml
description: Compose an ad creative from a product photo and a brief.
entrypoint: SKILL.md
tools:
- name: render_storyboard
entrypoint: tools/storyboard.py:run
input_schema: { ... }
output_schema: { ... }
One folder, one skill, two shapes of code living together. That's the whole mental model.