pi-telegram-notifier 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-telegram-notifier",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Telegram notifications for final Pi agent responses and provider balances",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,9 +27,14 @@ export function registerNotifications(pi, agentDir, token, fetchImpl = fetch) {
27
27
  startLeafId = undefined;
28
28
  const chatId = loadChatId(agentDir);
29
29
  if (!chatId || !response) return;
30
+ let quota;
30
31
  try {
31
32
  const model = ctx.modelRegistry?.find(response.provider, response.modelId);
32
- const quota = await getQuota(model, ctx.modelRegistry, fetchImpl);
33
+ quota = await getQuota(model, ctx.modelRegistry, fetchImpl);
34
+ } catch {
35
+ quota = 'Quota unavailable';
36
+ }
37
+ try {
33
38
  await sendTelegram(token, chatId,
34
39
  formatNotification(new Date().toISOString(), response, quota), fetchImpl);
35
40
  } catch {
package/src/quota.js CHANGED
@@ -1,15 +1,15 @@
1
1
  const UNAVAILABLE = 'Quota unavailable';
2
2
 
3
3
  const providers = {
4
- openrouter: ['https://openrouter.ai', 'https://openrouter.ai/api/v1/credits'],
5
- 'openai-codex': ['https://chatgpt.com', 'https://chatgpt.com/backend-api/wham/usage'],
6
- deepseek: ['https://api.deepseek.com', 'https://api.deepseek.com/user/balance'],
7
- moonshotai: ['https://api.moonshot.ai', 'https://api.moonshot.ai/v1/users/me/balance'],
8
- 'moonshotai-cn': ['https://api.moonshot.cn', 'https://api.moonshot.cn/v1/users/me/balance'],
9
- zai: ['https://api.z.ai', 'https://api.z.ai/api/monitor/usage/quota/limit'],
10
- 'zai-coding-cn': ['https://open.bigmodel.cn', 'https://open.bigmodel.cn/api/monitor/usage/quota/limit'],
11
- anthropic: ['https://api.anthropic.com', 'https://api.anthropic.com/api/oauth/usage'],
12
- xai: ['https://api.x.ai', 'https://cli-chat-proxy.grok.com/v1/billing?format=credits'],
4
+ openrouter: { origin: 'https://openrouter.ai', url: 'https://openrouter.ai/api/v1/credits' },
5
+ 'openai-codex': { origin: 'https://chatgpt.com', url: 'https://chatgpt.com/backend-api/wham/usage' },
6
+ deepseek: { origin: 'https://api.deepseek.com', url: 'https://api.deepseek.com/user/balance' },
7
+ moonshotai: { origin: 'https://api.moonshot.ai', url: 'https://api.moonshot.ai/v1/users/me/balance' },
8
+ 'moonshotai-cn': { origin: 'https://api.moonshot.cn', url: 'https://api.moonshot.cn/v1/users/me/balance' },
9
+ zai: { origin: 'https://api.z.ai', url: 'https://api.z.ai/api/monitor/usage/quota/limit' },
10
+ 'zai-coding-cn': { origin: 'https://open.bigmodel.cn', url: 'https://open.bigmodel.cn/api/monitor/usage/quota/limit' },
11
+ anthropic: { origin: 'https://api.anthropic.com', url: 'https://api.anthropic.com/api/oauth/usage' },
12
+ xai: { origin: 'https://api.x.ai', url: 'https://cli-chat-proxy.grok.com/v1/billing?format=credits' },
13
13
  };
14
14
 
15
15
  function remainingPercent(used) {
@@ -20,10 +20,10 @@ export async function getQuota(model, modelRegistry, fetchImpl = fetch) {
20
20
  const provider = model && providers[model.provider];
21
21
  if (!provider) return UNAVAILABLE;
22
22
  try {
23
- if (new URL(model.baseUrl).origin !== provider[0]) return UNAVAILABLE;
23
+ if (new URL(model.baseUrl).origin !== provider.origin) return UNAVAILABLE;
24
24
  if (['anthropic', 'xai'].includes(model.provider) && !modelRegistry.isUsingOAuth(model)) return UNAVAILABLE;
25
25
  const auth = await modelRegistry.getApiKeyAndHeaders(model);
26
- if (!auth.ok || !auth.apiKey || (auth.baseUrl && new URL(auth.baseUrl).origin !== provider[0])) return UNAVAILABLE;
26
+ if (!auth.ok || !auth.apiKey || (auth.baseUrl && new URL(auth.baseUrl).origin !== provider.origin)) return UNAVAILABLE;
27
27
  const headers = { Authorization: ['zai', 'zai-coding-cn'].includes(model.provider) ? auth.apiKey : `Bearer ${auth.apiKey}` };
28
28
  if (model.provider === 'anthropic') {
29
29
  headers['anthropic-beta'] = 'oauth-2025-04-20';
@@ -35,7 +35,7 @@ export async function getQuota(model, modelRegistry, fetchImpl = fetch) {
35
35
  if (typeof accountId !== 'string' || !accountId) return UNAVAILABLE;
36
36
  headers['ChatGPT-Account-Id'] = accountId;
37
37
  }
38
- const response = await fetchImpl(provider[1], {
38
+ const response = await fetchImpl(provider.url, {
39
39
  headers,
40
40
  signal: AbortSignal.timeout(10_000),
41
41
  });
@@ -62,7 +62,7 @@ export async function getQuota(model, modelRegistry, fetchImpl = fetch) {
62
62
  if (remaining === undefined && config.creditUsagePercent === undefined) {
63
63
  const { currentPeriod, productUsage } = config;
64
64
  if (Date.parse(currentPeriod.start) < Date.parse(currentPeriod.end) &&
65
- (productUsage === undefined || (Array.isArray(productUsage) && productUsage.every((item) => item?.usagePercent === 0)))) remaining = 100;
65
+ Array.isArray(productUsage) && productUsage.length > 0 && productUsage.every((item) => item?.usagePercent === 0)) remaining = 100;
66
66
  }
67
67
  return remaining === undefined ? UNAVAILABLE : `Remaining quota: 7d ${remaining}%`;
68
68
  }