@axplusb/kepler 2.3.2 → 2.3.3
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
|
@@ -221,6 +221,7 @@ export function formatAgentErrorGuidance(data = {}) {
|
|
|
221
221
|
const providerMeta = provider || compact(data.provider || data.gateway || data.gateway_type);
|
|
222
222
|
const taskId = compact(data.task_id);
|
|
223
223
|
const retryAfter = data.retry_after != null ? compact(data.retry_after) : '';
|
|
224
|
+
const retryLabel = retryAfter ? formatRetryAfterLabel(retryAfter) : '';
|
|
224
225
|
const retryable = data.retryable === true;
|
|
225
226
|
|
|
226
227
|
if (isBedrockMissingCredentials(data)) {
|
|
@@ -237,7 +238,16 @@ export function formatAgentErrorGuidance(data = {}) {
|
|
|
237
238
|
|
|
238
239
|
const lines = [];
|
|
239
240
|
const providerGuidance = PROVIDER_GUIDANCE[provider];
|
|
240
|
-
if (
|
|
241
|
+
if (code === 'credit_balance_exhausted') {
|
|
242
|
+
lines.push('Add credits or upgrade your plan to continue using platform-hosted models.');
|
|
243
|
+
lines.push('If you have your own provider key, switch to BYOK in Settings to keep working without Kepler credit charges.');
|
|
244
|
+
if (data.pricing_url) lines.push(`Open ${data.pricing_url} to top up or compare plans.`);
|
|
245
|
+
} else if (code === 'message_limit_reached') {
|
|
246
|
+
const retry = retryLabel ? ` Wait ${retryLabel} for the rolling window to recover.` : ' Wait for the rolling message window to reset.';
|
|
247
|
+
lines.push(`You reached the message limit for this plan.${retry}`);
|
|
248
|
+
lines.push('Upgrade your plan for a larger 5-hour message window, or switch to BYOK if available.');
|
|
249
|
+
if (data.pricing_url) lines.push(`Open ${data.pricing_url} to upgrade.`);
|
|
250
|
+
} else if (phase === 'gateway' || code.includes('gateway')) {
|
|
241
251
|
const label = providerGuidance?.label || 'provider';
|
|
242
252
|
lines.push(`The ${label} gateway failed before the agent could respond.`);
|
|
243
253
|
if (providerGuidance) {
|
|
@@ -266,6 +276,17 @@ export function formatAgentErrorGuidance(data = {}) {
|
|
|
266
276
|
};
|
|
267
277
|
}
|
|
268
278
|
|
|
279
|
+
function formatRetryAfterLabel(value) {
|
|
280
|
+
const secs = Math.max(0, Math.ceil(Number(value) || 0));
|
|
281
|
+
if (!secs) return '';
|
|
282
|
+
const hours = Math.floor(secs / 3600);
|
|
283
|
+
const minutes = Math.ceil((secs % 3600) / 60);
|
|
284
|
+
if (hours > 0 && minutes > 0) return `${hours}h ${minutes}m`;
|
|
285
|
+
if (hours > 0) return `${hours}h`;
|
|
286
|
+
if (minutes > 0) return `${minutes}m`;
|
|
287
|
+
return `${secs}s`;
|
|
288
|
+
}
|
|
289
|
+
|
|
269
290
|
function normalizeProviderToken(value) {
|
|
270
291
|
const raw = lower(value);
|
|
271
292
|
if (!raw) return '';
|
|
@@ -83,13 +83,28 @@ export function lowWindowStatus(rateLimit) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
export function rateLimitErrorMessage(payload, fallback = 'Message limit reached.') {
|
|
86
|
-
const detail = payload
|
|
86
|
+
const detail = quotaErrorDetail(payload);
|
|
87
87
|
const retryAfter = detail?.retry_after ?? detail?.rate_limit?.retry_after ?? detail?.rate_limit?.retry_after_seconds;
|
|
88
|
+
if (detail?.code === 'credit_balance_exhausted') {
|
|
89
|
+
return detail.message || 'Credit balance exhausted — add credits, upgrade your plan, or switch to BYOK in Settings.';
|
|
90
|
+
}
|
|
91
|
+
if (detail?.code === 'message_limit_reached') {
|
|
92
|
+
if (detail.message) return detail.message;
|
|
93
|
+
if (retryAfter != null) return `Message window exhausted — try again in ${formatRetryAfter(retryAfter)}, or upgrade your plan.`;
|
|
94
|
+
return 'Message window exhausted — wait for the window to reset or upgrade your plan.';
|
|
95
|
+
}
|
|
88
96
|
if (detail?.message) return detail.message;
|
|
89
|
-
if (retryAfter != null) return `Message
|
|
97
|
+
if (retryAfter != null) return `Message window exhausted — try again in ${formatRetryAfter(retryAfter)}, or upgrade your plan.`;
|
|
90
98
|
return fallback;
|
|
91
99
|
}
|
|
92
100
|
|
|
101
|
+
export function quotaErrorDetail(payload) {
|
|
102
|
+
if (!payload || typeof payload !== 'object') return {};
|
|
103
|
+
if (typeof payload.detail === 'string') return { message: payload.detail };
|
|
104
|
+
if (payload.detail && typeof payload.detail === 'object') return payload.detail;
|
|
105
|
+
return payload;
|
|
106
|
+
}
|
|
107
|
+
|
|
93
108
|
function numberOrNull(value) {
|
|
94
109
|
if (value == null) return null;
|
|
95
110
|
const n = Number(value);
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { sendCallback, sendSkippedCallback, sendApprovalDecision } from './callback-client.mjs';
|
|
13
13
|
import { ApprovalManager } from './approval.mjs';
|
|
14
|
-
import { rateLimitErrorMessage } from './rate-limit-display.mjs';
|
|
14
|
+
import { quotaErrorDetail, rateLimitErrorMessage } from './rate-limit-display.mjs';
|
|
15
15
|
|
|
16
16
|
export const EVENT_TYPES = Object.freeze({
|
|
17
17
|
// Phase 1 — handled
|
|
@@ -134,7 +134,7 @@ export class TarangStreamClient {
|
|
|
134
134
|
} catch {
|
|
135
135
|
payload = { detail: { message: text } };
|
|
136
136
|
}
|
|
137
|
-
const detail = payload
|
|
137
|
+
const detail = quotaErrorDetail(payload);
|
|
138
138
|
yield {
|
|
139
139
|
type: EVENT_TYPES.ERROR,
|
|
140
140
|
data: {
|
|
@@ -142,6 +142,8 @@ export class TarangStreamClient {
|
|
|
142
142
|
code: detail?.code || 'rate_limited',
|
|
143
143
|
retry_after: detail?.retry_after ?? detail?.rate_limit?.retry_after,
|
|
144
144
|
rate_limit: detail?.rate_limit || null,
|
|
145
|
+
action: detail?.action || null,
|
|
146
|
+
pricing_url: detail?.pricing_url || null,
|
|
145
147
|
fatal: true,
|
|
146
148
|
},
|
|
147
149
|
};
|