feat: add a calculator tool, so a number is calculated rather than predicted #926

Merged
coilysiren merged 1 commit from issue-916-calculator-tool into main 2026-08-17 19:43:54 +00:00
Member

calculate, in process, exact.

Done means, one at a time

  • A tool that evaluates arithmetic and returns the result, expression echoed. + - * / ^, parentheses, and a trailing %. The result text is <expression> = <value>, so a trace is checkable against what was asked rather than against what the reply claimed.
  • Bounded input and a refusal path. CALCULATOR_RUNES, CALCULATOR_DIGITS, CALCULATOR_EXPONENT, CALCULATOR_PLACES, all knobs in config.go. Bad input comes back as IsError the model can read and correct, matching fetch_url and the scratch tools, and only an unserved tool name fails the turn.
  • A prompt rule. "Calculate rather than estimate. Every number in a reply that no tool produced goes through the calculate tool."

Exact, not floating point

Values are big.Rat, so 0.1 + 0.2 is 0.3 and a recipe scaled across three multiplications does not drift. A result that is not a decimal says it was rounded and prints the exact fraction beside it, because a rounded number presented as exact is the failure this tool exists to stop.

Not a language

No identifiers, no calls, nothing to evaluate but numbers and those operators. total * 2, exec(1), and rm -rf / all refuse with "that is not arithmetic". #179 puts code execution across the blast-radius line and this does not approach it.

Registered unconditionally

It needs no configuration. A tool behind an unset switch is a tool nobody has, which is what #885 found after SIRENS_ECHO_DISCORD_COMMANDS sat dark.

Three things worth a reviewer's eye

  • Both prompt budgets rise 203 bytes, recorded in docs/sirens-echo-prompt.md with its cause as that file requires. The rule is what makes the tool used rather than merely offered, so the raise is the point rather than a side effect.
  • Deep's board citations move. The new prompt section shifted line numbers, and boardcitation_test.go caught it. agents/deep/packs/board.yaml is updated to 88-89, 91-92, and 101-109.
  • Units are not included. The issue lists them beside arithmetic and percentages. They need a conversion table rather than a parser, none of Echo's questions are physical-unit questions, and a half-built table would be worse than none. Say the word and it is a separate change.

Tests

Arithmetic including right-associative ^ and thousands separators, exactness on 0.1 + 0.2, the rounding disclosure on 1/3, the echoed expression, ten refusal cases, and the tool surface.

just gate PASS.

closes #916

`calculate`, in process, exact. ## Done means, one at a time * **A tool that evaluates arithmetic and returns the result, expression echoed.** `+ - * / ^`, parentheses, and a trailing `%`. The result text is `<expression> = <value>`, so a trace is checkable against what was asked rather than against what the reply claimed. * **Bounded input and a refusal path.** `CALCULATOR_RUNES`, `CALCULATOR_DIGITS`, `CALCULATOR_EXPONENT`, `CALCULATOR_PLACES`, all knobs in `config.go`. Bad input comes back as `IsError` the model can read and correct, matching `fetch_url` and the scratch tools, and only an unserved tool name fails the turn. * **A prompt rule.** "Calculate rather than estimate. Every number in a reply that no tool produced goes through the calculate tool." ## Exact, not floating point Values are `big.Rat`, so `0.1 + 0.2` is `0.3` and a recipe scaled across three multiplications does not drift. **A result that is not a decimal says it was rounded** and prints the exact fraction beside it, because a rounded number presented as exact is the failure this tool exists to stop. ## Not a language No identifiers, no calls, nothing to evaluate but numbers and those operators. `total * 2`, `exec(1)`, and `rm -rf /` all refuse with "that is not arithmetic". #179 puts code execution across the blast-radius line and this does not approach it. ## Registered unconditionally It needs no configuration. A tool behind an unset switch is a tool nobody has, which is what #885 found after `SIRENS_ECHO_DISCORD_COMMANDS` sat dark. ## Three things worth a reviewer's eye * **Both prompt budgets rise 203 bytes**, recorded in `docs/sirens-echo-prompt.md` with its cause as that file requires. The rule is what makes the tool used rather than merely offered, so the raise is the point rather than a side effect. * **Deep's board citations move.** The new prompt section shifted line numbers, and `boardcitation_test.go` caught it. `agents/deep/packs/board.yaml` is updated to 88-89, 91-92, and 101-109. * **Units are not included.** The issue lists them beside arithmetic and percentages. They need a conversion table rather than a parser, none of Echo's questions are physical-unit questions, and a half-built table would be worse than none. Say the word and it is a separate change. ## Tests Arithmetic including right-associative `^` and thousands separators, exactness on `0.1 + 0.2`, the rounding disclosure on `1/3`, the echoed expression, ten refusal cases, and the tool surface. `just gate` PASS. closes #916
feat: add a calculator tool, so a number is calculated rather than predicted
All checks were successful
ci / image-build (pull_request) Successful in 32s
ci / test (pull_request) Successful in 58s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
915e3d9496
There was no arithmetic anywhere in Echo's executable surface. Every number
that did not arrive inside a tool result was a language model predicting
plausible digits, which is fine for "roughly a third" and not for a total, a
rate, or a unit price in a community that asks what things cost.

calculate evaluates + - * / ^, parentheses, and a trailing % meaning per cent.
The grammar has no identifiers and no calls, so an expression reaches nothing:
#179 puts code execution across the blast-radius line and a calculator has no
business approaching it.

Exact rather than floating point. Values are rationals, so 0.1 + 0.2 is 0.3.
A result that is not a decimal is reported rounded and says that it was, with
the exact fraction beside it, because a rounded number presented as exact is
the failure the tool exists to stop. The expression is echoed with the answer
so a trace can be checked against what was asked.

In process beside FetchProvider and ScratchProvider rather than a twelfth
roster server, as the issue scoped it. Registered unconditionally: it needs no
configuration, and a tool behind an unset switch is a tool nobody has, which is
what #127 spent months discovering.

Bounds are knobs: CALCULATOR_RUNES, CALCULATOR_DIGITS, CALCULATOR_EXPONENT and
CALCULATOR_PLACES. Bad input refuses as a readable result rather than failing
the turn, matching fetch_url and the scratch tools.

Both prompt budgets rise 203 bytes for the rule routing arithmetic through it,
recorded in docs/sirens-echo-prompt.md. Deep's board citations move with the
line numbers the new section shifted.

Units are not included. The issue lists them beside arithmetic and percentages,
but they need a conversion table rather than a parser, and a half-built one
would be worse than none. Filed as a follow-up rather than guessed at.

closes #916

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo!926
No description provided.