@gobing-ai/ts-ai-runner 0.5.18 → 0.5.20
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/dist/quota.d.ts +4 -2
- package/dist/quota.d.ts.map +1 -1
- package/dist/quota.js +31 -6
- package/package.json +4 -4
- package/src/quota.ts +30 -6
package/dist/quota.d.ts
CHANGED
|
@@ -58,8 +58,10 @@ export declare const MAX_QUOTA_EVIDENCE_BYTES = 8192;
|
|
|
58
58
|
/**
|
|
59
59
|
* Classify one error record as quota exhaustion. Accepts only structured
|
|
60
60
|
* provider error envelopes — a JSON object with an `error` object whose
|
|
61
|
-
* `type` or `code` exactly matches a canonical quota code
|
|
62
|
-
*
|
|
61
|
+
* `type` or `code` exactly matches a canonical quota code, or (for providers
|
|
62
|
+
* that omit the wrapper) a top-level `{ code, message }` pair where `code`
|
|
63
|
+
* matches a canonical or verified provider code. Free text, quoted prompt
|
|
64
|
+
* content inside `error.message`, plain HTTP 429 rate-limit codes,
|
|
63
65
|
* throttling/overload, authentication, context/output limits, and timeouts
|
|
64
66
|
* all classify as negative (R2). Input is bounded to
|
|
65
67
|
* {@link MAX_QUOTA_EVIDENCE_BYTES} trailing bytes.
|
package/dist/quota.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../src/quota.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAC3B,oBAAoB,GACpB,6BAA6B,GAC7B,gBAAgB,GAChB,qBAAqB,GACrB,mBAAmB,GACnB,4BAA4B;AAC9B,+FAA+F;GAC7F,0BAA0B,CAAC;AAEjC,mHAAmH;AACnH,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,cAAc,CAAC;AAExF;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+GAA+G;AAC/G,MAAM,WAAW,qBAAqB;IAClC,kHAAkH;IAClH,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,mBAAmB,CAAC;IACpC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,4HAA4H;AAC5H,MAAM,WAAW,kBAAkB;IAC/B,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,sDAAsD;AACtD,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpG,kHAAkH;AAClH,eAAO,MAAM,wBAAwB,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../src/quota.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAC3B,oBAAoB,GACpB,6BAA6B,GAC7B,gBAAgB,GAChB,qBAAqB,GACrB,mBAAmB,GACnB,4BAA4B;AAC9B,+FAA+F;GAC7F,0BAA0B,CAAC;AAEjC,mHAAmH;AACnH,MAAM,MAAM,mBAAmB,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,cAAc,CAAC;AAExF;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+GAA+G;AAC/G,MAAM,WAAW,qBAAqB;IAClC,kHAAkH;IAClH,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,mBAAmB,CAAC;IACpC,MAAM,EAAE,qBAAqB,CAAC;IAC9B,sGAAsG;IACtG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,4HAA4H;AAC5H,MAAM,WAAW,kBAAkB;IAC/B,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,sDAAsD;AACtD,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpG,kHAAkH;AAClH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAmB7C;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAY5E;AA8BD,qFAAqF;AACrF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,CAEpD;AAYD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC1C,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACrC,GAAG,qBAAqB,CAoBxB;AAED;;;;;GAKG;AACH,qBAAa,wBAAwB;IAGrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEhB,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,SAAS;IAEtE,mGAAmG;IACnG,OAAO,CAAC,WAAW,EAAE,qBAAqB,GAAG,OAAO;IAOpD,mGAAmG;IACnG,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO;CAKzD"}
|
package/dist/quota.js
CHANGED
|
@@ -9,11 +9,20 @@ const QUOTA_CODES = new Set([
|
|
|
9
9
|
'credits_exhausted',
|
|
10
10
|
'billing_hard_limit_reached',
|
|
11
11
|
]);
|
|
12
|
+
/**
|
|
13
|
+
* Verified provider-specific exhaustion codes, mapped onto the canonical reason
|
|
14
|
+
* they confirm. The canonical allowlist above stays exact-match; a provider code
|
|
15
|
+
* is added here only when it has been observed to mean exhaustion (Spur 1134 R2 —
|
|
16
|
+
* `1310` is z.ai's weekly/monthly allowance cap).
|
|
17
|
+
*/
|
|
18
|
+
const PROVIDER_QUOTA_CODES = new Map([['1310', 'usage_limit_reached']]);
|
|
12
19
|
/**
|
|
13
20
|
* Classify one error record as quota exhaustion. Accepts only structured
|
|
14
21
|
* provider error envelopes — a JSON object with an `error` object whose
|
|
15
|
-
* `type` or `code` exactly matches a canonical quota code
|
|
16
|
-
*
|
|
22
|
+
* `type` or `code` exactly matches a canonical quota code, or (for providers
|
|
23
|
+
* that omit the wrapper) a top-level `{ code, message }` pair where `code`
|
|
24
|
+
* matches a canonical or verified provider code. Free text, quoted prompt
|
|
25
|
+
* content inside `error.message`, plain HTTP 429 rate-limit codes,
|
|
17
26
|
* throttling/overload, authentication, context/output limits, and timeouts
|
|
18
27
|
* all classify as negative (R2). Input is bounded to
|
|
19
28
|
* {@link MAX_QUOTA_EVIDENCE_BYTES} trailing bytes.
|
|
@@ -29,9 +38,19 @@ export function classifyQuotaErrorRecord(record) {
|
|
|
29
38
|
if (QUOTA_CODES.has(candidate))
|
|
30
39
|
return { quota: true, reason: candidate };
|
|
31
40
|
}
|
|
41
|
+
const providerReason = PROVIDER_QUOTA_CODES.get(code);
|
|
42
|
+
if (providerReason !== undefined)
|
|
43
|
+
return { quota: true, reason: providerReason };
|
|
32
44
|
return { quota: false };
|
|
33
45
|
}
|
|
34
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Best-effort parse of a JSON provider error envelope. Two shapes are accepted:
|
|
48
|
+
* the `error`-wrapped form (`{ error: { type?, code?, message? } }`) used by most
|
|
49
|
+
* providers, and a top-level `{ code, message }` form used by providers that omit
|
|
50
|
+
* the wrapper. The top-level form requires both a string `code` and a string
|
|
51
|
+
* `message` so an incidental `{"code":"…"}` echo in surrounding text is not read
|
|
52
|
+
* as an envelope. A present-but-malformed `error` key stays negative.
|
|
53
|
+
*/
|
|
35
54
|
function tryParseErrorEnvelope(record) {
|
|
36
55
|
const start = record.indexOf('{');
|
|
37
56
|
const end = record.lastIndexOf('}');
|
|
@@ -41,10 +60,16 @@ function tryParseErrorEnvelope(record) {
|
|
|
41
60
|
const parsed = JSON.parse(record.slice(start, end + 1));
|
|
42
61
|
if (typeof parsed !== 'object' || parsed === null)
|
|
43
62
|
return null;
|
|
44
|
-
|
|
45
|
-
|
|
63
|
+
if ('error' in parsed) {
|
|
64
|
+
const error = parsed.error;
|
|
65
|
+
if (typeof error !== 'object' || error === null)
|
|
66
|
+
return null;
|
|
67
|
+
return error;
|
|
68
|
+
}
|
|
69
|
+
const topLevel = parsed;
|
|
70
|
+
if (typeof topLevel.code !== 'string' || typeof topLevel.message !== 'string')
|
|
46
71
|
return null;
|
|
47
|
-
return
|
|
72
|
+
return { type: topLevel.type, code: topLevel.code };
|
|
48
73
|
}
|
|
49
74
|
catch {
|
|
50
75
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/ts-ai-runner",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.20",
|
|
4
4
|
"description": "@gobing-ai/ts-ai-runner — Coding-agent shims, detection, doctor checks, and prompt execution.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-ai-runner-v<version> && git push --tags' && exit 1"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@gobing-ai/ts-infra": "^0.5.
|
|
51
|
-
"@gobing-ai/ts-runtime": "^0.5.
|
|
50
|
+
"@gobing-ai/ts-infra": "^0.5.20",
|
|
51
|
+
"@gobing-ai/ts-runtime": "^0.5.20",
|
|
52
52
|
"@typesafe-ai/sdk": "0.6.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/bun": "1.3.14",
|
|
56
|
-
"@gobing-ai/ts-db": "^0.5.
|
|
56
|
+
"@gobing-ai/ts-db": "^0.5.20"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|
package/src/quota.ts
CHANGED
|
@@ -74,11 +74,21 @@ const QUOTA_CODES: ReadonlySet<string> = new Set([
|
|
|
74
74
|
'billing_hard_limit_reached',
|
|
75
75
|
]);
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Verified provider-specific exhaustion codes, mapped onto the canonical reason
|
|
79
|
+
* they confirm. The canonical allowlist above stays exact-match; a provider code
|
|
80
|
+
* is added here only when it has been observed to mean exhaustion (Spur 1134 R2 —
|
|
81
|
+
* `1310` is z.ai's weekly/monthly allowance cap).
|
|
82
|
+
*/
|
|
83
|
+
const PROVIDER_QUOTA_CODES: ReadonlyMap<string, QuotaExhaustionReason> = new Map([['1310', 'usage_limit_reached']]);
|
|
84
|
+
|
|
77
85
|
/**
|
|
78
86
|
* Classify one error record as quota exhaustion. Accepts only structured
|
|
79
87
|
* provider error envelopes — a JSON object with an `error` object whose
|
|
80
|
-
* `type` or `code` exactly matches a canonical quota code
|
|
81
|
-
*
|
|
88
|
+
* `type` or `code` exactly matches a canonical quota code, or (for providers
|
|
89
|
+
* that omit the wrapper) a top-level `{ code, message }` pair where `code`
|
|
90
|
+
* matches a canonical or verified provider code. Free text, quoted prompt
|
|
91
|
+
* content inside `error.message`, plain HTTP 429 rate-limit codes,
|
|
82
92
|
* throttling/overload, authentication, context/output limits, and timeouts
|
|
83
93
|
* all classify as negative (R2). Input is bounded to
|
|
84
94
|
* {@link MAX_QUOTA_EVIDENCE_BYTES} trailing bytes.
|
|
@@ -92,10 +102,19 @@ export function classifyQuotaErrorRecord(record: string): QuotaClassification {
|
|
|
92
102
|
for (const candidate of [type, code]) {
|
|
93
103
|
if (QUOTA_CODES.has(candidate)) return { quota: true, reason: candidate as QuotaExhaustionReason };
|
|
94
104
|
}
|
|
105
|
+
const providerReason = PROVIDER_QUOTA_CODES.get(code);
|
|
106
|
+
if (providerReason !== undefined) return { quota: true, reason: providerReason };
|
|
95
107
|
return { quota: false };
|
|
96
108
|
}
|
|
97
109
|
|
|
98
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Best-effort parse of a JSON provider error envelope. Two shapes are accepted:
|
|
112
|
+
* the `error`-wrapped form (`{ error: { type?, code?, message? } }`) used by most
|
|
113
|
+
* providers, and a top-level `{ code, message }` form used by providers that omit
|
|
114
|
+
* the wrapper. The top-level form requires both a string `code` and a string
|
|
115
|
+
* `message` so an incidental `{"code":"…"}` echo in surrounding text is not read
|
|
116
|
+
* as an envelope. A present-but-malformed `error` key stays negative.
|
|
117
|
+
*/
|
|
99
118
|
function tryParseErrorEnvelope(record: string): { type?: unknown; code?: unknown } | null {
|
|
100
119
|
const start = record.indexOf('{');
|
|
101
120
|
const end = record.lastIndexOf('}');
|
|
@@ -103,9 +122,14 @@ function tryParseErrorEnvelope(record: string): { type?: unknown; code?: unknown
|
|
|
103
122
|
try {
|
|
104
123
|
const parsed: unknown = JSON.parse(record.slice(start, end + 1));
|
|
105
124
|
if (typeof parsed !== 'object' || parsed === null) return null;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
125
|
+
if ('error' in parsed) {
|
|
126
|
+
const error = (parsed as { error?: unknown }).error;
|
|
127
|
+
if (typeof error !== 'object' || error === null) return null;
|
|
128
|
+
return error as { type?: unknown; code?: unknown };
|
|
129
|
+
}
|
|
130
|
+
const topLevel = parsed as { type?: unknown; code?: unknown; message?: unknown };
|
|
131
|
+
if (typeof topLevel.code !== 'string' || typeof topLevel.message !== 'string') return null;
|
|
132
|
+
return { type: topLevel.type, code: topLevel.code };
|
|
109
133
|
} catch {
|
|
110
134
|
return null;
|
|
111
135
|
}
|