@juspay/neurolink 10.8.16 → 10.8.18
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/CHANGELOG.md +12 -0
- package/dist/browser/neurolink.min.js +329 -329
- package/dist/lib/neurolink.js +9 -3
- package/dist/lib/utils/providerErrorClassification.d.ts +34 -0
- package/dist/lib/utils/providerErrorClassification.js +60 -0
- package/dist/neurolink.js +9 -3
- package/dist/utils/providerErrorClassification.d.ts +34 -0
- package/dist/utils/providerErrorClassification.js +60 -0
- package/package.json +5 -3
package/dist/lib/neurolink.js
CHANGED
|
@@ -99,7 +99,7 @@ import { getWorkflow } from "./workflow/core/workflowRegistry.js";
|
|
|
99
99
|
import { runWorkflow } from "./workflow/core/workflowRunner.js";
|
|
100
100
|
import { ModelPool, classifyProviderError } from "./routing/index.js";
|
|
101
101
|
import { ClassifierRouter } from "./routing/classifierRouter.js";
|
|
102
|
-
import { looksLikeModelAccessDenied as sharedLooksLikeModelAccessDenied, isNonRetryableProviderError as sharedIsNonRetryableProviderError, } from "./utils/providerErrorClassification.js";
|
|
102
|
+
import { looksLikeModelAccessDenied as sharedLooksLikeModelAccessDenied, isNonRetryableProviderError as sharedIsNonRetryableProviderError, isNonRetryableForPool as sharedIsNonRetryableForPool, } from "./utils/providerErrorClassification.js";
|
|
103
103
|
import { getErrorStatusCode } from "./utils/providerRetry.js";
|
|
104
104
|
import { detectAndRedactPII } from "./utils/piiDetector.js";
|
|
105
105
|
import { validateResponse } from "./utils/responseValidator.js";
|
|
@@ -173,6 +173,12 @@ function mcpCategoryToErrorCategory(mcpCategory) {
|
|
|
173
173
|
*/
|
|
174
174
|
const looksLikeModelAccessDenied = sharedLooksLikeModelAccessDenied;
|
|
175
175
|
const isNonRetryableProviderError = sharedIsNonRetryableProviderError;
|
|
176
|
+
/**
|
|
177
|
+
* Pool-scoped variant: model-not-found is a fact about one member's model, not
|
|
178
|
+
* about the request, so it must not stop the whole pool. Used only at the two
|
|
179
|
+
* ModelPool catch sites; every other path keeps the general contract.
|
|
180
|
+
*/
|
|
181
|
+
const isNonRetryableForPool = sharedIsNonRetryableForPool;
|
|
176
182
|
/**
|
|
177
183
|
* NeuroLink - Universal AI Development Platform
|
|
178
184
|
*
|
|
@@ -5829,7 +5835,7 @@ Current user's request: ${currentInput}`;
|
|
|
5829
5835
|
if (isAbortError(poolError)) {
|
|
5830
5836
|
throw poolError;
|
|
5831
5837
|
}
|
|
5832
|
-
if (
|
|
5838
|
+
if (isNonRetryableForPool(poolError)) {
|
|
5833
5839
|
const poolErrMsg = poolError instanceof Error
|
|
5834
5840
|
? poolError.message
|
|
5835
5841
|
: String(poolError);
|
|
@@ -8367,7 +8373,7 @@ Current user's request: ${currentInput}`;
|
|
|
8367
8373
|
if (isAbortError(poolStreamError)) {
|
|
8368
8374
|
throw poolStreamError;
|
|
8369
8375
|
}
|
|
8370
|
-
if (
|
|
8376
|
+
if (isNonRetryableForPool(poolStreamError)) {
|
|
8371
8377
|
const poolStreamErrMsg = poolStreamError instanceof Error
|
|
8372
8378
|
? poolStreamError.message
|
|
8373
8379
|
: String(poolStreamError);
|
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
* plus typed-error name/code markers when the full typed class is not present.
|
|
13
13
|
*/
|
|
14
14
|
export declare function looksLikeModelAccessDenied(error: unknown): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Detects "the provider does not have this model": HTTP 404 model lookups,
|
|
17
|
+
* Google's NOT_FOUND, Anthropic's `not_found_error` naming the model, and the
|
|
18
|
+
* typed InvalidModelError providers raise for an unrecognised model id.
|
|
19
|
+
*
|
|
20
|
+
* Deliberately narrow. A 404 alone is not enough — only a 404 that names a
|
|
21
|
+
* model qualifies, so an unrelated missing endpoint stays non-retryable.
|
|
22
|
+
* Auth-flavoured messages are excluded outright: PERMISSION_DENIED means the
|
|
23
|
+
* key is not entitled to the model, which every member sharing that key would
|
|
24
|
+
* hit identically.
|
|
25
|
+
*/
|
|
26
|
+
export declare function looksLikeModelNotFound(error: unknown): boolean;
|
|
15
27
|
/**
|
|
16
28
|
* Returns true when the error is definitively non-retryable: typed error
|
|
17
29
|
* classes (auth, access-denied, invalid-model), non-retryable HTTP status
|
|
@@ -20,5 +32,27 @@ export declare function looksLikeModelAccessDenied(error: unknown): boolean;
|
|
|
20
32
|
* NOTE: ContextBudgetExceededError is intentionally NOT non-retryable —
|
|
21
33
|
* each provider has its own context window, so a budget rejection on one
|
|
22
34
|
* provider does not preclude another provider accepting the same payload.
|
|
35
|
+
*
|
|
36
|
+
* NOTE: model-not-found IS non-retryable here, and intentionally so. This is
|
|
37
|
+
* the general contract, used by provider fallback where the same model id
|
|
38
|
+
* typically carries across providers — retrying a typo everywhere would turn
|
|
39
|
+
* one crisp error into a slow fan-out of identical ones. ModelPool is the
|
|
40
|
+
* exception and uses {@link isNonRetryableForPool} instead.
|
|
23
41
|
*/
|
|
24
42
|
export declare function isNonRetryableProviderError(error: unknown): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Non-retryability as ModelPool sees it.
|
|
45
|
+
*
|
|
46
|
+
* A pool member is an explicit {provider, model} pair, and members are chosen
|
|
47
|
+
* precisely because they differ. "This provider has no such model" is therefore
|
|
48
|
+
* a fact about ONE member, not about the request: member#2 runs a different
|
|
49
|
+
* model and may well serve it. Short-circuiting the whole pool on it defeats
|
|
50
|
+
* the point of configuring a pool — the observed case was a member naming a
|
|
51
|
+
* retired model, where Anthropic answered 404 and the pool gave up instead of
|
|
52
|
+
* failing over to the member that was fine.
|
|
53
|
+
*
|
|
54
|
+
* Everything else keeps the general contract. Auth failures, malformed
|
|
55
|
+
* payloads, and access-denied still stop the pool immediately, because those
|
|
56
|
+
* describe the credentials or the request and every member would hit them.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isNonRetryableForPool(error: unknown): boolean;
|
|
@@ -37,6 +37,39 @@ export function looksLikeModelAccessDenied(error) {
|
|
|
37
37
|
lower.includes("team can only access") ||
|
|
38
38
|
/not\s+allowed\s+to\s+access\s+(this\s+)?model/i.test(msg));
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Detects "the provider does not have this model": HTTP 404 model lookups,
|
|
42
|
+
* Google's NOT_FOUND, Anthropic's `not_found_error` naming the model, and the
|
|
43
|
+
* typed InvalidModelError providers raise for an unrecognised model id.
|
|
44
|
+
*
|
|
45
|
+
* Deliberately narrow. A 404 alone is not enough — only a 404 that names a
|
|
46
|
+
* model qualifies, so an unrelated missing endpoint stays non-retryable.
|
|
47
|
+
* Auth-flavoured messages are excluded outright: PERMISSION_DENIED means the
|
|
48
|
+
* key is not entitled to the model, which every member sharing that key would
|
|
49
|
+
* hit identically.
|
|
50
|
+
*/
|
|
51
|
+
export function looksLikeModelNotFound(error) {
|
|
52
|
+
if (error instanceof InvalidModelError) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (!(error instanceof Error)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const msg = error.message;
|
|
59
|
+
if (msg.includes("PERMISSION_DENIED") ||
|
|
60
|
+
msg.includes("UNAUTHENTICATED") ||
|
|
61
|
+
looksLikeModelAccessDenied(error)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const lower = msg.toLowerCase();
|
|
65
|
+
const namesAModel = lower.includes("model");
|
|
66
|
+
return ((lower.includes("model not found") ||
|
|
67
|
+
lower.includes("not_found_error") ||
|
|
68
|
+
msg.includes("NOT_FOUND") ||
|
|
69
|
+
lower.includes("does not exist") ||
|
|
70
|
+
lower.includes("unknown model")) &&
|
|
71
|
+
namesAModel);
|
|
72
|
+
}
|
|
40
73
|
/**
|
|
41
74
|
* Returns true when the error is definitively non-retryable: typed error
|
|
42
75
|
* classes (auth, access-denied, invalid-model), non-retryable HTTP status
|
|
@@ -45,6 +78,12 @@ export function looksLikeModelAccessDenied(error) {
|
|
|
45
78
|
* NOTE: ContextBudgetExceededError is intentionally NOT non-retryable —
|
|
46
79
|
* each provider has its own context window, so a budget rejection on one
|
|
47
80
|
* provider does not preclude another provider accepting the same payload.
|
|
81
|
+
*
|
|
82
|
+
* NOTE: model-not-found IS non-retryable here, and intentionally so. This is
|
|
83
|
+
* the general contract, used by provider fallback where the same model id
|
|
84
|
+
* typically carries across providers — retrying a typo everywhere would turn
|
|
85
|
+
* one crisp error into a slow fan-out of identical ones. ModelPool is the
|
|
86
|
+
* exception and uses {@link isNonRetryableForPool} instead.
|
|
48
87
|
*/
|
|
49
88
|
export function isNonRetryableProviderError(error) {
|
|
50
89
|
if (error instanceof InvalidModelError) {
|
|
@@ -86,4 +125,25 @@ export function isNonRetryableProviderError(error) {
|
|
|
86
125
|
}
|
|
87
126
|
return false;
|
|
88
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Non-retryability as ModelPool sees it.
|
|
130
|
+
*
|
|
131
|
+
* A pool member is an explicit {provider, model} pair, and members are chosen
|
|
132
|
+
* precisely because they differ. "This provider has no such model" is therefore
|
|
133
|
+
* a fact about ONE member, not about the request: member#2 runs a different
|
|
134
|
+
* model and may well serve it. Short-circuiting the whole pool on it defeats
|
|
135
|
+
* the point of configuring a pool — the observed case was a member naming a
|
|
136
|
+
* retired model, where Anthropic answered 404 and the pool gave up instead of
|
|
137
|
+
* failing over to the member that was fine.
|
|
138
|
+
*
|
|
139
|
+
* Everything else keeps the general contract. Auth failures, malformed
|
|
140
|
+
* payloads, and access-denied still stop the pool immediately, because those
|
|
141
|
+
* describe the credentials or the request and every member would hit them.
|
|
142
|
+
*/
|
|
143
|
+
export function isNonRetryableForPool(error) {
|
|
144
|
+
if (looksLikeModelNotFound(error)) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return isNonRetryableProviderError(error);
|
|
148
|
+
}
|
|
89
149
|
//# sourceMappingURL=providerErrorClassification.js.map
|
package/dist/neurolink.js
CHANGED
|
@@ -99,7 +99,7 @@ import { getWorkflow } from "./workflow/core/workflowRegistry.js";
|
|
|
99
99
|
import { runWorkflow } from "./workflow/core/workflowRunner.js";
|
|
100
100
|
import { ModelPool, classifyProviderError } from "./routing/index.js";
|
|
101
101
|
import { ClassifierRouter } from "./routing/classifierRouter.js";
|
|
102
|
-
import { looksLikeModelAccessDenied as sharedLooksLikeModelAccessDenied, isNonRetryableProviderError as sharedIsNonRetryableProviderError, } from "./utils/providerErrorClassification.js";
|
|
102
|
+
import { looksLikeModelAccessDenied as sharedLooksLikeModelAccessDenied, isNonRetryableProviderError as sharedIsNonRetryableProviderError, isNonRetryableForPool as sharedIsNonRetryableForPool, } from "./utils/providerErrorClassification.js";
|
|
103
103
|
import { getErrorStatusCode } from "./utils/providerRetry.js";
|
|
104
104
|
import { detectAndRedactPII } from "./utils/piiDetector.js";
|
|
105
105
|
import { validateResponse } from "./utils/responseValidator.js";
|
|
@@ -173,6 +173,12 @@ function mcpCategoryToErrorCategory(mcpCategory) {
|
|
|
173
173
|
*/
|
|
174
174
|
const looksLikeModelAccessDenied = sharedLooksLikeModelAccessDenied;
|
|
175
175
|
const isNonRetryableProviderError = sharedIsNonRetryableProviderError;
|
|
176
|
+
/**
|
|
177
|
+
* Pool-scoped variant: model-not-found is a fact about one member's model, not
|
|
178
|
+
* about the request, so it must not stop the whole pool. Used only at the two
|
|
179
|
+
* ModelPool catch sites; every other path keeps the general contract.
|
|
180
|
+
*/
|
|
181
|
+
const isNonRetryableForPool = sharedIsNonRetryableForPool;
|
|
176
182
|
/**
|
|
177
183
|
* NeuroLink - Universal AI Development Platform
|
|
178
184
|
*
|
|
@@ -5829,7 +5835,7 @@ Current user's request: ${currentInput}`;
|
|
|
5829
5835
|
if (isAbortError(poolError)) {
|
|
5830
5836
|
throw poolError;
|
|
5831
5837
|
}
|
|
5832
|
-
if (
|
|
5838
|
+
if (isNonRetryableForPool(poolError)) {
|
|
5833
5839
|
const poolErrMsg = poolError instanceof Error
|
|
5834
5840
|
? poolError.message
|
|
5835
5841
|
: String(poolError);
|
|
@@ -8367,7 +8373,7 @@ Current user's request: ${currentInput}`;
|
|
|
8367
8373
|
if (isAbortError(poolStreamError)) {
|
|
8368
8374
|
throw poolStreamError;
|
|
8369
8375
|
}
|
|
8370
|
-
if (
|
|
8376
|
+
if (isNonRetryableForPool(poolStreamError)) {
|
|
8371
8377
|
const poolStreamErrMsg = poolStreamError instanceof Error
|
|
8372
8378
|
? poolStreamError.message
|
|
8373
8379
|
: String(poolStreamError);
|
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
* plus typed-error name/code markers when the full typed class is not present.
|
|
13
13
|
*/
|
|
14
14
|
export declare function looksLikeModelAccessDenied(error: unknown): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Detects "the provider does not have this model": HTTP 404 model lookups,
|
|
17
|
+
* Google's NOT_FOUND, Anthropic's `not_found_error` naming the model, and the
|
|
18
|
+
* typed InvalidModelError providers raise for an unrecognised model id.
|
|
19
|
+
*
|
|
20
|
+
* Deliberately narrow. A 404 alone is not enough — only a 404 that names a
|
|
21
|
+
* model qualifies, so an unrelated missing endpoint stays non-retryable.
|
|
22
|
+
* Auth-flavoured messages are excluded outright: PERMISSION_DENIED means the
|
|
23
|
+
* key is not entitled to the model, which every member sharing that key would
|
|
24
|
+
* hit identically.
|
|
25
|
+
*/
|
|
26
|
+
export declare function looksLikeModelNotFound(error: unknown): boolean;
|
|
15
27
|
/**
|
|
16
28
|
* Returns true when the error is definitively non-retryable: typed error
|
|
17
29
|
* classes (auth, access-denied, invalid-model), non-retryable HTTP status
|
|
@@ -20,5 +32,27 @@ export declare function looksLikeModelAccessDenied(error: unknown): boolean;
|
|
|
20
32
|
* NOTE: ContextBudgetExceededError is intentionally NOT non-retryable —
|
|
21
33
|
* each provider has its own context window, so a budget rejection on one
|
|
22
34
|
* provider does not preclude another provider accepting the same payload.
|
|
35
|
+
*
|
|
36
|
+
* NOTE: model-not-found IS non-retryable here, and intentionally so. This is
|
|
37
|
+
* the general contract, used by provider fallback where the same model id
|
|
38
|
+
* typically carries across providers — retrying a typo everywhere would turn
|
|
39
|
+
* one crisp error into a slow fan-out of identical ones. ModelPool is the
|
|
40
|
+
* exception and uses {@link isNonRetryableForPool} instead.
|
|
23
41
|
*/
|
|
24
42
|
export declare function isNonRetryableProviderError(error: unknown): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Non-retryability as ModelPool sees it.
|
|
45
|
+
*
|
|
46
|
+
* A pool member is an explicit {provider, model} pair, and members are chosen
|
|
47
|
+
* precisely because they differ. "This provider has no such model" is therefore
|
|
48
|
+
* a fact about ONE member, not about the request: member#2 runs a different
|
|
49
|
+
* model and may well serve it. Short-circuiting the whole pool on it defeats
|
|
50
|
+
* the point of configuring a pool — the observed case was a member naming a
|
|
51
|
+
* retired model, where Anthropic answered 404 and the pool gave up instead of
|
|
52
|
+
* failing over to the member that was fine.
|
|
53
|
+
*
|
|
54
|
+
* Everything else keeps the general contract. Auth failures, malformed
|
|
55
|
+
* payloads, and access-denied still stop the pool immediately, because those
|
|
56
|
+
* describe the credentials or the request and every member would hit them.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isNonRetryableForPool(error: unknown): boolean;
|
|
@@ -37,6 +37,39 @@ export function looksLikeModelAccessDenied(error) {
|
|
|
37
37
|
lower.includes("team can only access") ||
|
|
38
38
|
/not\s+allowed\s+to\s+access\s+(this\s+)?model/i.test(msg));
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Detects "the provider does not have this model": HTTP 404 model lookups,
|
|
42
|
+
* Google's NOT_FOUND, Anthropic's `not_found_error` naming the model, and the
|
|
43
|
+
* typed InvalidModelError providers raise for an unrecognised model id.
|
|
44
|
+
*
|
|
45
|
+
* Deliberately narrow. A 404 alone is not enough — only a 404 that names a
|
|
46
|
+
* model qualifies, so an unrelated missing endpoint stays non-retryable.
|
|
47
|
+
* Auth-flavoured messages are excluded outright: PERMISSION_DENIED means the
|
|
48
|
+
* key is not entitled to the model, which every member sharing that key would
|
|
49
|
+
* hit identically.
|
|
50
|
+
*/
|
|
51
|
+
export function looksLikeModelNotFound(error) {
|
|
52
|
+
if (error instanceof InvalidModelError) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (!(error instanceof Error)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const msg = error.message;
|
|
59
|
+
if (msg.includes("PERMISSION_DENIED") ||
|
|
60
|
+
msg.includes("UNAUTHENTICATED") ||
|
|
61
|
+
looksLikeModelAccessDenied(error)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const lower = msg.toLowerCase();
|
|
65
|
+
const namesAModel = lower.includes("model");
|
|
66
|
+
return ((lower.includes("model not found") ||
|
|
67
|
+
lower.includes("not_found_error") ||
|
|
68
|
+
msg.includes("NOT_FOUND") ||
|
|
69
|
+
lower.includes("does not exist") ||
|
|
70
|
+
lower.includes("unknown model")) &&
|
|
71
|
+
namesAModel);
|
|
72
|
+
}
|
|
40
73
|
/**
|
|
41
74
|
* Returns true when the error is definitively non-retryable: typed error
|
|
42
75
|
* classes (auth, access-denied, invalid-model), non-retryable HTTP status
|
|
@@ -45,6 +78,12 @@ export function looksLikeModelAccessDenied(error) {
|
|
|
45
78
|
* NOTE: ContextBudgetExceededError is intentionally NOT non-retryable —
|
|
46
79
|
* each provider has its own context window, so a budget rejection on one
|
|
47
80
|
* provider does not preclude another provider accepting the same payload.
|
|
81
|
+
*
|
|
82
|
+
* NOTE: model-not-found IS non-retryable here, and intentionally so. This is
|
|
83
|
+
* the general contract, used by provider fallback where the same model id
|
|
84
|
+
* typically carries across providers — retrying a typo everywhere would turn
|
|
85
|
+
* one crisp error into a slow fan-out of identical ones. ModelPool is the
|
|
86
|
+
* exception and uses {@link isNonRetryableForPool} instead.
|
|
48
87
|
*/
|
|
49
88
|
export function isNonRetryableProviderError(error) {
|
|
50
89
|
if (error instanceof InvalidModelError) {
|
|
@@ -86,3 +125,24 @@ export function isNonRetryableProviderError(error) {
|
|
|
86
125
|
}
|
|
87
126
|
return false;
|
|
88
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Non-retryability as ModelPool sees it.
|
|
130
|
+
*
|
|
131
|
+
* A pool member is an explicit {provider, model} pair, and members are chosen
|
|
132
|
+
* precisely because they differ. "This provider has no such model" is therefore
|
|
133
|
+
* a fact about ONE member, not about the request: member#2 runs a different
|
|
134
|
+
* model and may well serve it. Short-circuiting the whole pool on it defeats
|
|
135
|
+
* the point of configuring a pool — the observed case was a member naming a
|
|
136
|
+
* retired model, where Anthropic answered 404 and the pool gave up instead of
|
|
137
|
+
* failing over to the member that was fine.
|
|
138
|
+
*
|
|
139
|
+
* Everything else keeps the general contract. Auth failures, malformed
|
|
140
|
+
* payloads, and access-denied still stop the pool immediately, because those
|
|
141
|
+
* describe the credentials or the request and every member would hit them.
|
|
142
|
+
*/
|
|
143
|
+
export function isNonRetryableForPool(error) {
|
|
144
|
+
if (looksLikeModelNotFound(error)) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return isNonRetryableProviderError(error);
|
|
148
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/neurolink",
|
|
3
|
-
"version": "10.8.
|
|
3
|
+
"version": "10.8.18",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"description": "TypeScript AI SDK with 24+ LLM providers behind one consistent API. MCP-native (connect any MCP server), voice TTS/STT/realtime, RAG, agents, memory, context compaction. OpenAI · Anthropic · Gemini · Bedrock · Azure · Ollama · DeepSeek · NVIDIA NIM and more.",
|
|
6
6
|
"author": {
|
|
@@ -141,6 +141,7 @@
|
|
|
141
141
|
"test:tool-routing-cli": "npx tsx test/continuous-test-suite-tool-routing-flags.ts && npx tsx test/continuous-test-suite-tool-routing-cli.ts",
|
|
142
142
|
"test:tool-dedup": "npx tsx test/continuous-test-suite-tool-dedup.ts",
|
|
143
143
|
"test:model-pool": "npx tsx test/continuous-test-suite-model-pool.ts",
|
|
144
|
+
"test:model-not-found-retryable": "npx tsx test/continuous-test-suite-model-not-found-retryable.ts",
|
|
144
145
|
"test:model-capabilities": "npx tsx test/continuous-test-suite-model-capabilities.ts",
|
|
145
146
|
"test:agent-runtime:vitest": "pnpm exec vitest run test/agentRuntime.test.ts test/agentDelegation.test.ts test/agentPlumbing.test.ts test/toolExecutionRecorder.test.ts",
|
|
146
147
|
"test:retry-after:vitest": "pnpm exec vitest run test/retryAfter.test.ts",
|
|
@@ -151,7 +152,7 @@
|
|
|
151
152
|
"test:system-messages": "npx tsx test/continuous-test-suite-system-messages.ts",
|
|
152
153
|
"test:test-stubs": "npx tsx test/continuous-test-suite-test-stubs.ts",
|
|
153
154
|
"test:tool-routing-semantic": "npx tsx test/continuous-test-suite-tool-routing-semantic.ts",
|
|
154
|
-
"test:unit": "pnpm run test:envguard && pnpm run test:bugfixes && pnpm run test:file-detector-extension && pnpm run test:file-detector-magic-bytes && pnpm run test:mcp:infra && pnpm run test:mcp:bash && pnpm run test:mcp:limits && pnpm run test:mcp:spans && pnpm run test:autoresearch:redis && pnpm run test:tool-routing && pnpm run test:tool-routing-cli && pnpm run test:tool-dedup && pnpm run test:model-pool && pnpm run test:litellm-context:
|
|
155
|
+
"test:unit": "pnpm run test:envguard && pnpm run test:bugfixes && pnpm run test:file-detector-extension && pnpm run test:file-detector-magic-bytes && pnpm run test:mcp:infra && pnpm run test:mcp:bash && pnpm run test:mcp:limits && pnpm run test:mcp:spans && pnpm run test:autoresearch:redis && pnpm run test:tool-routing && pnpm run test:tool-routing-cli && pnpm run test:tool-dedup && pnpm run test:model-pool && pnpm run test:litellm-context && pnpm run test:dedup-execute-map && pnpm run test:step-budget-guard:vitest && pnpm run test:system-messages && pnpm run test:tool-routing-semantic && pnpm run test:anthropic-tools-policy && pnpm run test:sagemaker-tools && pnpm run test:anthropic-multimodal && pnpm run test:excel-interop && pnpm run test:model-capabilities && pnpm run test:agent-runtime:vitest && pnpm run test:retry-after:vitest && pnpm run test:sampling-params && pnpm run test:structured-recovery && pnpm run test:prompt-redaction && pnpm run test:mcp-result-cache && pnpm run test:test-stubs && pnpm run test:model-not-found-retryable",
|
|
155
156
|
"// CI tier — live providers, runs only when API keys are present (test:credentials and test:dynamic make real provider calls when keys are set, so they live here, not in test:unit)": "",
|
|
156
157
|
"test:live": "pnpm run test:providers && pnpm run test:mcp:http && pnpm run test:mcp:sdk && pnpm run test:mcp:cli && pnpm run test:observability && pnpm run test:context && pnpm run test:memory && pnpm run test:tool-reliability && pnpm run test:evaluation && pnpm run test:autoresearch && pnpm run test:credentials && pnpm run test:dynamic",
|
|
157
158
|
"// CI tier — product output (image/video/TTS/PPT) — costs $$ per run": "",
|
|
@@ -213,7 +214,8 @@
|
|
|
213
214
|
"pre-commit": "lint-staged",
|
|
214
215
|
"pre-push": "pnpm run validate:commit && pnpm run validate:env && pnpm run validate && pnpm run test:ci",
|
|
215
216
|
"check:all": "pnpm run lint && pnpm run format --check && pnpm run validate && pnpm run validate:commit",
|
|
216
|
-
"test:litellm-context
|
|
217
|
+
"test:litellm-context": "npx tsx test/continuous-test-suite-litellm-context-windows.ts",
|
|
218
|
+
"test:dedup-execute-map": "npx tsx test/continuous-test-suite-dedup-execute-map.ts",
|
|
217
219
|
"test:step-budget-guard:vitest": "pnpm exec vitest run test/stepBudgetGuard.test.ts",
|
|
218
220
|
"test:audio": "npx tsx test/continuous-test-suite-audio.ts",
|
|
219
221
|
"test:office": "npx tsx test/continuous-test-suite-office.ts",
|