88 lines
3.2 KiB
Bash
Executable File
88 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Backend del plasmoide AI Credits Balance.
|
|
# Chiama le API di DeepSeek (GET /user/balance) e OpenRouter
|
|
# (GET /api/v1/credits) e restituisce un JSON unificato. Gli errori sono
|
|
# gestiti per-provider: anche se uno fallisce, l'altro viene comunque riportato.
|
|
set -u
|
|
|
|
AUTH_JSON="${AI_AUTH_JSON:-$HOME/.pi/agent/auth.json}"
|
|
NOW="$(date +%s)"
|
|
|
|
DS_KEY=""
|
|
OR_KEY=""
|
|
if [ -f "$AUTH_JSON" ]; then
|
|
DS_KEY="$(jq -r '.["deepseek"].key // empty' "$AUTH_JSON" 2>/dev/null)"
|
|
OR_KEY="$(jq -r '.["openrouter"].key // empty' "$AUTH_JSON" 2>/dev/null)"
|
|
fi
|
|
[ -n "$DS_KEY" ] || DS_KEY="${DEEPSEEK_API_KEY:-}"
|
|
[ -n "$OR_KEY" ] || OR_KEY="${OPENROUTER_API_KEY:-}"
|
|
|
|
# --- DeepSeek -------------------------------------------------------------
|
|
ds_block() {
|
|
if [ -z "$DS_KEY" ]; then
|
|
printf '{"ok":false,"error":"no_api_key"}'
|
|
return
|
|
fi
|
|
local resp rc
|
|
resp="$(curl -sS --max-time 15 https://api.deepseek.com/user/balance \
|
|
-H "Authorization: Bearer $DS_KEY" 2>/dev/null)"
|
|
rc=$?
|
|
if [ "$rc" -ne 0 ] || [ -z "$resp" ]; then
|
|
printf '{"ok":false,"error":"fetch_failed","detail":"curl exit %s"}' "$rc"
|
|
return
|
|
fi
|
|
if ! printf '%s' "$resp" | jq -e '.balance_infos | type == "array"' >/dev/null 2>&1; then
|
|
printf '{"ok":false,"error":"bad_json","detail":"risposta non valida da DeepSeek"}'
|
|
return
|
|
fi
|
|
printf '%s' "$resp" | jq -c '{
|
|
ok:true,
|
|
available:(.is_available // false),
|
|
currency:((.balance_infos[0].currency) // "USD"),
|
|
total:((.balance_infos[0].total_balance) | tonumber),
|
|
granted:((.balance_infos[0].granted_balance) | tonumber),
|
|
topped_up:((.balance_infos[0].topped_up_balance) | tonumber)
|
|
}' 2>/dev/null || printf '{"ok":false,"error":"bad_json","detail":"impossibile elaborare DeepSeek"}'
|
|
}
|
|
|
|
# --- OpenRouter -----------------------------------------------------------
|
|
or_block() {
|
|
if [ -z "$OR_KEY" ]; then
|
|
printf '{"ok":false,"error":"no_api_key"}'
|
|
return
|
|
fi
|
|
local resp rc
|
|
resp="$(curl -sS --max-time 15 https://openrouter.ai/api/v1/credits \
|
|
-H "Authorization: Bearer $OR_KEY" 2>/dev/null)"
|
|
rc=$?
|
|
if [ "$rc" -ne 0 ] || [ -z "$resp" ]; then
|
|
printf '{"ok":false,"error":"fetch_failed","detail":"curl exit %s"}' "$rc"
|
|
return
|
|
fi
|
|
if ! printf '%s' "$resp" | jq -e '.data.total_credits | type == "number"' >/dev/null 2>&1; then
|
|
# 401/403 => la routing key non ha permessi sul /credits (serve management key).
|
|
printf '{"ok":false,"error":"bad_json","detail":"risposta non valida (la chiave potrebbe essere una routing key: serve una management key)"}'
|
|
return
|
|
fi
|
|
printf '%s' "$resp" | jq -c '{
|
|
ok:true,
|
|
total_credits:(.data.total_credits),
|
|
total_usage:(.data.total_usage),
|
|
remaining:((.data.total_credits) - (.data.total_usage))
|
|
}' 2>/dev/null || printf '{"ok":false,"error":"bad_json","detail":"impossibile elaborare OpenRouter"}'
|
|
}
|
|
|
|
DS_JSON="$(ds_block)"
|
|
OR_JSON="$(or_block)"
|
|
|
|
# ok globale = almeno un provider sano.
|
|
GLOBAL_OK="$(jq -n --argjson d "$DS_JSON" --argjson o "$OR_JSON" '($d.ok or $o.ok)')"
|
|
|
|
jq -nc \
|
|
--argjson ok "$GLOBAL_OK" \
|
|
--argjson deepseek "$DS_JSON" \
|
|
--argjson openrouter "$OR_JSON" \
|
|
--argjson fetched "$NOW" \
|
|
'{ok:$ok, deepseek:$deepseek, openrouter:$openrouter, fetched_at:$fetched}'
|
|
|
|
exit 0 |