diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-26 08:24:02 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-26 08:24:02 +0200 |
| commit | 3b6f56f93c829a741df4ded189a4b8c98ce7fdff (patch) | |
| tree | 1c947731ed3704bdf60d6660f21d10c6ae8b157f | |
| parent | b1816ed443d715d0c706a40fd202d595d4a11926 (diff) | |
| download | desktop-assistant-3b6f56f93c829a741df4ded189a4b8c98ce7fdff.tar.gz desktop-assistant-3b6f56f93c829a741df4ded189a4b8c98ce7fdff.zip | |
Add calc, mail, playing and finance example tools
All read-only: each command is fixed in its tool file, so the model
fills parameters but can never reach mailctl tag or firefly tx add.
qalc reads "17.5% of 240" as a modulo, so the calc hint shows percent
as a factor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| -rw-r--r-- | README.md | 15 | ||||
| -rw-r--r-- | examples/tools/calc.toml | 7 | ||||
| -rwxr-xr-x | examples/tools/finance.sh | 51 | ||||
| -rw-r--r-- | examples/tools/finance.toml | 13 | ||||
| -rwxr-xr-x | examples/tools/mail.sh | 30 | ||||
| -rw-r--r-- | examples/tools/mail.toml | 9 | ||||
| -rwxr-xr-x | examples/tools/playing.sh | 30 | ||||
| -rw-r--r-- | examples/tools/playing.toml | 2 |
8 files changed, 153 insertions, 4 deletions
@@ -75,10 +75,17 @@ type = "string" description = "What the model should pass" ``` -The example tools only read: `now` (date), `calendar` (`agenda.py` over -a vdirsyncer folder), `weather` (OpenWeatherMap, key file in the -conky-theme-udt format), `search` (a SearXNG instance with the JSON -format enabled). +The example tools only read: + +- `now`: date and time +- `calendar`: `agenda.py` over a vdirsyncer folder +- `weather`: OpenWeatherMap, key file in the conky-theme-udt format +- `search`: a SearXNG instance with the JSON format enabled +- `calc`: `qalc` (arithmetic, units, currencies, date math) +- `mail`: unread threads through `mailctl` searches, no tagging or sync +- `playing`: the current track from `playerctl`, or `mpc` +- `finance`: balances, budgets and spending from Firefly III's `firefly` + list commands ## License diff --git a/examples/tools/calc.toml b/examples/tools/calc.toml new file mode 100644 index 0000000..c97ef04 --- /dev/null +++ b/examples/tools/calc.toml @@ -0,0 +1,7 @@ +description = "Calculator: arithmetic, percentages, unit and currency conversion, date math (days between dates). Use it instead of computing yourself." +command = ["qalc", "-t", "{expression}"] +timeout = 10 + +[params.expression] +type = "string" +description = "A qalc expression. Percent as a factor: 240 * 17.5%, 80 - 15% (not \"17.5% of 240\", qalc reads % there as modulo). Also 70 mph to km/h, 100 EUR to USD, days(today; 2026-12-25)." diff --git a/examples/tools/finance.sh b/examples/tools/finance.sh new file mode 100755 index 0000000..3c6f768 --- /dev/null +++ b/examples/tools/finance.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# desktop-assistant tool: personal finance from Firefly III (read-only). +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# finance.sh WHAT [DAYS]: WHAT is balances (active asset accounts), +# budgets (this month, spent against the limit) or spending (withdrawals in +# the last DAYS days, default 30: total and the 10 largest). Only firefly's +# list commands run here: nothing is recorded or edited. + +set -uo pipefail + +ff() { firefly "$@" || { echo "firefly $1 $2 failed" >&2; exit 1; }; } + +case "${1:-}" in +balances) + ff account list --type asset | jq -r '.[] | select(.active) + | "\(.name): \(.current_balance | tonumber * 100 | round / 100) \(.currency_code)"' + ;; +budgets) + ff budget list | jq -r '.[] | select(.active) + | "\(.name): spent \([.spent[].sum | tonumber] | add // 0 | fabs * 100 | round / 100)" + + (if .auto_budget_amount then " of \(.auto_budget_amount | tonumber)" else "" end) + + " \(.currency_code // "")"' + ;; +spending) + days="${2:-30}" + since=$(date -d "$days days ago" +%F) || exit 1 + ff tx list --since "$since" --all --flat 2>/dev/null | jq -r --arg since "$since" ' + [.[] | select(.type == "withdrawal") | .amount |= tonumber] + | "spent since \($since): \(map(.amount) | add // 0 | . * 100 | round / 100) in \(length) payments", + (sort_by(-.amount)[:10][] + | "\(.date[:10]) \(.amount * 100 | round / 100) \(.destination_name): \(.description)")' + ;; +*) + echo "what must be balances, budgets or spending" >&2 + exit 1 + ;; +esac diff --git a/examples/tools/finance.toml b/examples/tools/finance.toml new file mode 100644 index 0000000..b05031c --- /dev/null +++ b/examples/tools/finance.toml @@ -0,0 +1,13 @@ +description = "The user's money, from Firefly III: account balances, this month's budgets, or recent spending. Read-only." +command = ["finance.sh", "{what}", "{days}"] +timeout = 20 +announce.it = ["Controllo i conti."] +announce.en = ["Checking your accounts."] + +[params.what] +type = "string" +description = "balances, budgets or spending" + +[params.days] +type = "integer" +description = "For spending: how many days back. Empty for 30." diff --git a/examples/tools/mail.sh b/examples/tools/mail.sh new file mode 100755 index 0000000..4e0e9c1 --- /dev/null +++ b/examples/tools/mail.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# desktop-assistant tool: unread mail summary through mailctl (read-only). +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# mail.sh [QUERY]: thread count and the 10 newest threads for a notmuch +# query, default unread mail in the inbox, across every account. Only +# mailctl's search runs here: nothing is tagged, moved or synced. +# MAILCTL overrides the command (default mailctl.py on PATH). + +set -uo pipefail + +query="${1:-tag:unread and tag:inbox}" +json=$("${MAILCTL:-mailctl.py}" search "$query" --json) || { echo "mail search failed" >&2; exit 1; } +jq -r 'length as $n + | if $n == 0 then "no threads match" + else "\($n) threads", (.[:10][] | "\(.date_relative), \(.authors): \(.subject)") + end' <<<"$json" diff --git a/examples/tools/mail.toml b/examples/tools/mail.toml new file mode 100644 index 0000000..2f1a9d8 --- /dev/null +++ b/examples/tools/mail.toml @@ -0,0 +1,9 @@ +description = "The user's email: how many unread messages and who they are from. Read-only." +command = ["mail.sh", "{query}"] +timeout = 15 +announce.it = ["Controllo la posta."] +announce.en = ["Checking your mail."] + +[params.query] +type = "string" +description = "notmuch query, e.g. from:amazon or subject:invoice and date:7d.. Empty for unread mail in the inbox." diff --git a/examples/tools/playing.sh b/examples/tools/playing.sh new file mode 100755 index 0000000..9605f82 --- /dev/null +++ b/examples/tools/playing.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# desktop-assistant tool: what is playing now. +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# playing.sh: the current track from any MPRIS player (playerctl), or from +# MPD (mpc) when no MPRIS player is running. + +set -uo pipefail + +if out=$(playerctl metadata --format '{{status}}: {{artist}} - {{title}} ({{playerName}})' 2>/dev/null); then + echo "$out" +elif out=$(mpc status --format '%artist% - %title%' 2>/dev/null) && [ "$(wc -l <<<"$out")" -gt 1 ]; then + head -2 <<<"$out" | tac | tr '\n' ' ' + echo "(mpd)" +else + echo "nothing is playing" +fi diff --git a/examples/tools/playing.toml b/examples/tools/playing.toml new file mode 100644 index 0000000..6d33743 --- /dev/null +++ b/examples/tools/playing.toml @@ -0,0 +1,2 @@ +description = "The song or media playing right now on this computer." +command = ["playing.sh"] |
