aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-26 08:34:55 +0200
committerDanilo M. <danix@danix.xyz>2026-09-26 08:34:55 +0200
commit4a357b335f74ae64714800527ac3e95b7057a3ce (patch)
tree299f39e8c3788b36d0f4fe779dd4b994a77619bd
parent3b6f56f93c829a741df4ded189a4b8c98ce7fdff (diff)
downloaddesktop-assistant-4a357b335f74ae64714800527ac3e95b7057a3ce.tar.gz
desktop-assistant-4a357b335f74ae64714800527ac3e95b7057a3ce.zip
Fix mail counts and finance ranges found testing live
- mail printed threads and the model called them emails; it now reports messages and threads. - finance spending takes a since date (default the first of the month) instead of a day count, and an optional asset account. The per-account listing needs an end date or the API rejects it; an unknown account name gets the user's accounts back. - Tool errors are capped at 2000 characters like normal output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--AGENTS.md31
-rw-r--r--assistant.py2
-rwxr-xr-xexamples/tools/finance.sh30
-rw-r--r--examples/tools/finance.toml12
-rwxr-xr-xexamples/tools/mail.sh11
5 files changed, 68 insertions, 18 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 51a46d3..bfc29f4 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -331,6 +331,37 @@ distance, a person, next appointment twice).
- `agenda.py` matched khal's listing over 7 and 60 days on the real vdir,
runs in ~60 ms.
+### More tools, live test (2026-09-26)
+
+`calc` (qalc), `mail` (mailctl search), `playing` (playerctl/mpc),
+`finance` (firefly list commands). Every command is fixed in its tool
+file: the model fills parameters but cannot reach `mailctl tag` or
+`firefly tx add`.
+
+- qalc reads "17.5% of 240" as a modulo. With the hint "percent as a
+ factor: 240 * 17.5%" the model sent exactly that and got 42.
+- "Days until Christmas": the model built `days(<today>; 2026-12-25)`
+ from the date in the system prompt, right in one call (1.9 s).
+- mail said "47 unread emails" for 47 *threads* (58 messages). The tool
+ now prints "N messages in M threads".
+- finance "this month" used the 30-day default and the model called it
+ the month's total. Spending now takes a `since` date, empty = first of
+ the month.
+- "Spent on account X" had no account filter: the model fetched balances
+ plus total spending and honestly said it could not split them. Added
+ `account`; firefly's per-account listing needs `--until` or the API
+ answers 422. An unknown name gets the user's asset accounts back (not
+ firefly's own error, which lists every expense account); tool errors
+ are now capped at 2000 characters like normal output.
+- The model passed a lowercase account name; matching is
+ case-insensitive, firefly accepted it.
+- First sentence 1.9-3.6 s with local tools, ~5-6.6 s with firefly
+ (two API calls when filtering by account).
+- STT misheard "mail" as "snail"; the model answered about a snail,
+ harmless for read-only tools. Phase 2 (modifying tools) needs
+ confirmation before acting for exactly this reason.
+- These tools speak personal data (mail subjects, amounts) out loud.
+
### TTS (2026-09-25)
`piper-tts` on CPU (onnxruntime), ~5 s sentence per voice:
diff --git a/assistant.py b/assistant.py
index 84f0dd8..635fb81 100644
--- a/assistant.py
+++ b/assistant.py
@@ -206,7 +206,7 @@ def run_tool(tools, name, arguments, d=TOOLS_DIR):
return "error: timed out"
if p.returncode:
last = err.strip().splitlines()[-1:]
- return "error: " + (last[0] if last else f"exit status {p.returncode}")
+ return ("error: " + (last[0] if last else f"exit status {p.returncode}"))[:2000]
return out.strip()[:2000]
diff --git a/examples/tools/finance.sh b/examples/tools/finance.sh
index 3c6f768..0656b66 100755
--- a/examples/tools/finance.sh
+++ b/examples/tools/finance.sh
@@ -15,10 +15,11 @@
# 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.
+# finance.sh WHAT [SINCE] [ACCOUNT]: WHAT is balances (active asset
+# accounts), budgets (this month, spent against the limit) or spending
+# (withdrawals from SINCE, YYYY-MM-DD, default the first of this month,
+# optionally only from ACCOUNT: total and the 10 largest). Only firefly's list commands run here: nothing is recorded
+# or edited.
set -uo pipefail
@@ -36,13 +37,24 @@ budgets)
+ " \(.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" '
+ since="${2:-$(date +%Y-%m-01)}"
+ date -d "$since" >/dev/null 2>&1 || { echo "since must be YYYY-MM-DD" >&2; exit 1; }
+ account=()
+ if [ -n "${3:-}" ]; then
+ # firefly's own "no such account" lists every expense account too;
+ # the model only needs the user's own accounts to retry.
+ names=$(ff account list --type asset | jq -r '.[] | select(.active) | .name')
+ grep -qixF -- "$3" <<<"$names" \
+ || { echo "no account named $3; accounts: $(paste -sd, <<<"$names")" >&2; exit 1; }
+ # The per-account listing needs an end date, or the API rejects it.
+ account=(--account "$3" --until "$(date +%F)")
+ fi
+ json=$(firefly tx list --since "$since" "${account[@]}" --all --flat) || exit 1
+ jq -r --arg since "$since" --arg acct "${3:-all accounts}" '
[.[] | select(.type == "withdrawal") | .amount |= tonumber]
- | "spent since \($since): \(map(.amount) | add // 0 | . * 100 | round / 100) in \(length) payments",
+ | "spent from \($acct) 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)")'
+ | "\(.date[:10]) \(.amount * 100 | round / 100) \(.destination_name): \(.description)")' <<<"$json"
;;
*)
echo "what must be balances, budgets or spending" >&2
diff --git a/examples/tools/finance.toml b/examples/tools/finance.toml
index b05031c..1cfdc4a 100644
--- a/examples/tools/finance.toml
+++ b/examples/tools/finance.toml
@@ -1,5 +1,5 @@
description = "The user's money, from Firefly III: account balances, this month's budgets, or recent spending. Read-only."
-command = ["finance.sh", "{what}", "{days}"]
+command = ["finance.sh", "{what}", "{since}", "{account}"]
timeout = 20
announce.it = ["Controllo i conti."]
announce.en = ["Checking your accounts."]
@@ -8,6 +8,10 @@ announce.en = ["Checking your accounts."]
type = "string"
description = "balances, budgets or spending"
-[params.days]
-type = "integer"
-description = "For spending: how many days back. Empty for 30."
+[params.since]
+type = "string"
+description = "For spending: first day, YYYY-MM-DD. Empty for the first of this month."
+
+[params.account]
+type = "string"
+description = "For spending: only this account, by name as balances lists it. Empty for all accounts."
diff --git a/examples/tools/mail.sh b/examples/tools/mail.sh
index 4e0e9c1..bd7219d 100755
--- a/examples/tools/mail.sh
+++ b/examples/tools/mail.sh
@@ -23,8 +23,11 @@
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)")
+mailctl="${MAILCTL:-mailctl.py}"
+json=$("$mailctl" search "$query" --json) || { echo "mail search failed" >&2; exit 1; }
+# Messages and threads both: the model otherwise calls threads "emails".
+msgs=$("$mailctl" count "$query" | awk '{print $1}') || { echo "mail count failed" >&2; exit 1; }
+jq -r --arg msgs "$msgs" 'length as $n
+ | if $n == 0 then "no messages match"
+ else "\($msgs) messages in \($n) threads", (.[:10][] | "\(.date_relative), \(.authors): \(.subject)")
end' <<<"$json"