Before you start
Every primitive also carries a deterministic flag. It signals one thing: is
this primitive a pure function (same inputs always giving the same output)? This
track puts a pure primitive next to one that reads the clock.
1. Two primitives, one flag apart
The agent finds the next Monday. One primitive computes it from a given date; the other reads today's date off the system clock.
# dates.py
from datetime import date, timedelta
from opensymbolicai.blueprints import PlanExecute
from opensymbolicai.core import primitive
class Calendar(PlanExecute):
@primitive(read_only=True, deterministic=False) # depends on the clock
def today(self) -> date:
"""Return today's date."""
return date.today()
@primitive(read_only=True) # deterministic defaults to True: a pure function
def next_monday(self, d: date) -> date:
"""Return the date of the first Monday after `d`."""
days_ahead = (0 - d.weekday()) % 7
if days_ahead == 0:
days_ahead = 7
return d + timedelta(days=days_ahead)next_monday is pure: hand it 2026-06-02 and it always returns 2026-06-08,
today or next year. today is not pure: its result depends on when it runs.
That is what deterministic=False declares.
Both are also read_only=True. The two flags are independent.
2. Run it
# main.py
from dates import Calendar
from opensymbolicai.llm import LLMConfig
llm = LLMConfig(provider="ollama", model="qwen2.5-coder:7b")
agent = Calendar(llm=llm)
result = agent.run("calculate the date of the next Monday from the current date")
print(result.result) # e.g. 2026-06-08uv run main.pyRun it next week and the answer changes, because today reads a new date.
next_monday did not change at all. That split is exactly what the
deterministic flag records.
Why the flag matters, and what it does not do
On its own, deterministic changes nothing about this run. Both primitives
execute for real, and the flag is metadata.
The flag matters in tooling that leans on purity. A deterministic primitive's
result can be cached: compute next_monday(2026-06-02) once and reuse
2026-06-08 on every later call with that date. today cannot be cached that
way, so the flag also keeps it out of such a cache.