Billing Monitor Skill
Load Local Context
CODEBLOCK0
Minimum Model
Any model. Detection and alerting are rule-based. No reasoning required.
When to Run This Skill
Run when you see ANY of these in an API response:
CODEBLOCK1
When NOT to Alert the Owner
- - Routine billing check completed with no errors → silent, no message
- HTTP 200 / all clear → silent, no message
- ElevenLabs 401 (auth, not billing) → silent unless TTS is actively needed
Only alert the owner if:
- 1. HTTP 402 detected (out of credits)
- LLM is unreachable and the agent cannot function
- A peer PA reports a billing error
Routine health checks run silently. The owner does not need a "billing OK" message.
NOTE (Production): Netanel uses a proxy — billing-health-check cron has been REMOVED as not relevant. Only alert on actual API failure detected during real usage.
Response Steps (Run in Order)
Step 1 — Notify Owner
Send via WhatsApp (or preferred channel):
CODEBLOCK2
Step 2 — Notify Admin
CODEBLOCK3
Step 3 — Switch to Fallback Model
- 1. Check if
config/billing-fallback.json exists - If yes → read the
fallback_model field - Run: INLINECODE2
- If the command fails → tell owner: "Auto-switch failed — please update model manually in agent settings"
- Notify owner: "Switched to [Fallback Model] temporarily while primary key is resolved"
If billing-fallback.json doesn't exist → skip this step and tell admin to configure it.
Step 4 — Log the Incident
CODEBLOCK4
Health Check Script
Run this during heartbeat to catch billing issues before they cause failures:
CODEBLOCK5
HTTP status meanings:
- -
200 → OK - INLINECODE5 → Billing error → run 4-step protocol
- INLINECODE6 → Invalid key → notify admin
- INLINECODE7 → Rate limit (temporary) → wait and retry, do NOT trigger billing protocol
Fallback Config File
Create config/billing-fallback.json in your workspace:
CODEBLOCK6
Replace placeholders with real values. Examples:
- - Anthropic → OpenAI:
"primary_provider": "anthropic", "primary_model": "claude-haiku-20240307", "fallback_provider": "openai", INLINECODE12
Recovery (After Credits Restored)
- 1. Owner confirms credits are topped up.
- Read the primary model name from config:
PRIMARY=$(python3 -c "
import json
with open('config/billing-fallback.json') as f:
print(json.load(f)['primary_model'])
")
- 3. Switch back to primary:
openclaw config set model "$PRIMARY"
- 4. Log the recovery:
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) BILLING_RESTORED" \
>> ~/.openclaw/workspace/logs/billing-incidents.log
- 5. Notify owner: "✅ Primary model restored. Normal service resumed."
Edge Cases
| Scenario | Action |
|---|
| 429 rate limit | Wait 60s, retry. Do NOT trigger billing protocol. |
| 5xx server error |
Retry 2x with 10s delay. If persists → notify owner. |
| Both primary AND fallback billing errors | Escalate to admin immediately. Agent cannot function. |
| No API key env var set | Log as config issue. Notify admin. |
| Peer PA reports billing error | Log it. Notify admin if you are the network coordinator. |
Cost Tips
- - Cheap: Health checks with
curl — no LLM cost at all - Expensive: Running health checks too frequently wastes money. Every 2 hours is enough.
- Batch: Combine billing check with other heartbeat checks in one script run
- Small model OK: This skill needs no reasoning — any model can send a notification message
Running via Cron (Recommended)
Instead of a plugin, run billing-monitor as a scheduled skill via cron:
CODEBLOCK10
This runs every hour and alerts automatically — no plugin required.
账单监控技能
加载本地上下文
bash
CONTEXT_FILE=/opt/ocana/openclaw/workspace/skills/billing-monitor/.context
[ -f $CONTEXT
FILE ] && source $CONTEXTFILE
然后使用:$OWNERPHONE, $ADMINPHONE, $BILLINGLOG, $BILLINGFALLBACK_CONFIG 等变量
最低模型要求
任意模型。检测和告警基于规则,无需推理能力。
何时运行此技能
当在API响应中看到以下任意内容时运行:
your API key has run out of credits
insufficient balance
billing_error
payment_required
exceeded your current quota
HTTP 402
type: billing_error
何时不向所有者发送告警
- - 常规账单检查完成且无错误 → 静默处理,不发送消息
- HTTP 200 / 一切正常 → 静默处理,不发送消息
- ElevenLabs 401(认证问题,非账单问题)→ 除非需要主动使用TTS,否则静默处理
仅在以下情况下向所有者发送告警:
- 1. 检测到HTTP 402(积分耗尽)
- LLM无法访问且代理无法运行
- 同级PA报告账单错误
常规健康检查静默运行。所有者不需要收到账单正常的消息。
注意(生产环境): Netanel使用代理——账单健康检查定时任务已移除(不相关)。仅在实际使用过程中检测到API故障时发送告警。
响应步骤(按顺序执行)
步骤1 — 通知所有者
通过WhatsApp(或首选渠道)发送:
⚠️ 账单问题 — 我无法正常响应。
我的API密钥积分已耗尽(或受到速率限制)。
请在代理设置中充值或更换我的API密钥。
步骤2 — 通知管理员
[PA名称] 出现账单错误。
所有者:[所有者名称]
操作:充值API积分或重新分配密钥。
时间:[当前时间戳]
步骤3 — 切换到备用模型
- 1. 检查 config/billing-fallback.json 是否存在
- 如果存在 → 读取 fallbackmodel 字段
- 运行:openclaw config set model $FALLBACKMODEL
- 如果命令失败 → 告知所有者:自动切换失败 — 请在代理设置中手动更新模型
- 通知所有者:已临时切换到 [备用模型],等待主密钥问题解决
如果 billing-fallback.json 不存在 → 跳过此步骤并告知管理员进行配置。
步骤4 — 记录事件
bash
LOG_DIR=$HOME/.openclaw/workspace/logs
mkdir -p $LOG_DIR
向日志文件追加一行
echo $(date -u +%Y-%m-%dT%H:%M:%SZ) BILLING
ERROR apikey_exhausted \
>> $LOG_DIR/billing-incidents.log
健康检查脚本
在心跳检测期间运行此脚本,以便在账单问题导致故障前及时发现:
bash
#!/bin/bash
billing-check.sh
检查环境变量中配置的LLM提供商API密钥
set -e
LOG_DIR=$HOME/.openclaw/workspace/logs
mkdir -p $LOG_DIR
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
从环境变量检测提供商(按顺序检查)
if [ -n ${ANTHROPIC
APIKEY:-} ]; then
PROVIDER=Anthropic
HTTP
STATUS=$(curl -s -o /dev/null -w %{httpcode} \
-H x-api-key: ${ANTHROPIC
APIKEY} \
-H anthropic-version: 2023-06-01 \
-H content-type: application/json \
-d {\model\:\claude-haiku-20240307\,\max_tokens\:1,\messages\:[{\role\:\user\,\content\:\ping\}]} \
https://api.anthropic.com/v1/messages 2>/dev/null)
elif [ -n ${OPENAIAPIKEY:-} ]; then
PROVIDER=OpenAI
HTTPSTATUS=$(curl -s -o /dev/null -w %{httpcode} \
-H Authorization: Bearer ${OPENAIAPIKEY} \
-H content-type: application/json \
-d {\model\:\gpt-4o-mini\,\max_tokens\:1,\messages\:[{\role\:\user\,\content\:\ping\}]} \
https://api.openai.com/v1/chat/completions 2>/dev/null)
elif [ -n ${GOOGLEAPIKEY:-} ]; then
PROVIDER=Google
HTTPSTATUS=$(curl -s -o /dev/null -w %{httpcode} \
https://generativelanguage.googleapis.com/v1beta/models?key=${GOOGLEAPIKEY} 2>/dev/null)
else
echo $TIMESTAMP SKIP no API key env var found >> $LOG_DIR/billing-incidents.log
exit 0
fi
根据HTTP状态码执行操作
case $HTTP_STATUS in
200)
echo $TIMESTAMP OK $PROVIDER >> $LOG_DIR/billing-incidents.log
;;
402)
echo $TIMESTAMP BILLING
ERROR $PROVIDER HTTP402 >> $LOG_DIR/billing-incidents.log
echo 账单错误 — 运行上述4步响应协议
exit 1
;;
401)
echo $TIMESTAMP AUTH
ERROR $PROVIDER HTTP401 >> $LOG_DIR/billing-incidents.log
echo 认证错误 — API密钥无效,通知管理员
exit 1
;;
429)
echo $TIMESTAMP RATE
LIMITED $PROVIDER HTTP429 >> $LOG_DIR/billing-incidents.log
echo 速率受限 — 等待60秒后重试。非账单问题。
exit 2
;;
*)
echo $TIMESTAMP UNKNOWN $PROVIDER HTTP
$HTTPSTATUS >> $LOG_DIR/billing-incidents.log
echo 未知错误 HTTP $HTTP_STATUS
exit 1
;;
esac
HTTP状态码含义:
- - 200 → 正常
- 402 → 账单错误 → 运行4步协议
- 401 → 密钥无效 → 通知管理员
- 429 → 速率限制(临时)→ 等待后重试,不要触发账单协议
备用配置文件
在工作区创建 config/billing-fallback.json:
json
{
primary_provider: your-primary-provider,
primary_model: your-primary-model,
fallback_provider: your-fallback-provider,
fallback_model: your-fallback-model,
admin_phone: +1XXXXXXXXXX,
alert_channel: whatsapp
}
将占位符替换为实际值。示例:
- - Anthropic → OpenAI:primaryprovider: anthropic, primarymodel: claude-haiku-20240307, fallbackprovider: openai, fallbackmodel: gpt-4o-mini
恢复(积分恢复后)
- 1. 所有者确认积分已充值。
- 从配置中读取主模型名称:
bash
PRIMARY=$(python3 -c
import json
with open(config/billing-fallback.json) as f:
print(json.load(f)[primary_model])
)
- 3. 切换回主模型:
bash
openclaw config set model $PRIMARY
- 4. 记录恢复事件:
bash
echo $(date -u +%Y-%m-%dT%H:%M:%SZ) BILLING_RESTORED \
>> ~/.openclaw/workspace/logs/billing-incidents.log
- 5. 通知所有者:✅ 主模型已恢复。正常服务已恢复。
边界情况
| 场景 | 操作 |
|---|
| 429 速率限制 | 等待60秒后重试。不要触发账单协议。 |
| 5xx 服务器错误 |
重试2次,间隔10秒。如果持续失败 → 通知所有者。 |
| 主模型和备用模型均出现账单错误 | 立即升级至管理员。代理无法运行。 |
| 未设置API密钥环境变量 | 记录为配置问题。通知管理员。 |
| 同级PA报告账单错误 | 记录事件。如果你是网络协调员,通知管理员。 |
成本提示
- - 低成本: 使用 curl 进行健康检查 — 完全没有LLM成本
- 高成本: 过于频繁地运行健康检查会浪费资金。每2小时检查一次就足够了。
- 批量处理: