deterministic
The flag that signals whether a primitive is a pure function. Put a pure primitive next to one that reads the clock to see the difference.
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.