@juspay/neurolink 13.1.1 → 13.2.0
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 +6 -2
- package/README.md +71 -52
- package/dist/browser/neurolink.min.js +374 -374
- package/dist/cli/commands/decide.d.ts +2 -1
- package/dist/cli/commands/decide.js +2 -1
- package/dist/cli/commands/setup.d.ts +1 -1
- package/dist/cli/commands/setup.js +1 -1
- package/dist/cli/factories/commandFactory.js +1 -1
- package/dist/constants/contextWindows.d.ts +7 -0
- package/dist/constants/contextWindows.js +48 -0
- package/dist/constants/enums.d.ts +5 -0
- package/dist/constants/enums.js +6 -0
- package/dist/factories/providerDescriptors.js +13 -9
- package/dist/neurolink.js +7 -1
- package/dist/providers/catalog/charm-hyper.json +6 -10
- package/dist/providers/catalog/index.generated.d.ts +1 -1
- package/dist/providers/catalog/index.generated.js +3 -0
- package/dist/providers/catalog/openai-decisions.json +1 -1
- package/dist/providers/catalog/provider-catalog.schema.json +8 -0
- package/dist/providers/catalog/scaledown.json +68 -0
- package/dist/providers/catalog/schema.js +2 -0
- package/dist/providers/configuredDecision.d.ts +5 -0
- package/dist/providers/configuredDecision.js +27 -5
- package/dist/types/classifierRouter.d.ts +10 -9
- package/dist/types/cli.d.ts +2 -2
- package/dist/types/providerCatalog.d.ts +22 -0
- package/dist/types/providerCatalog.generated.d.ts +2 -2
- package/dist/types/providers.d.ts +4 -0
- package/dist/utils/pricing.js +12 -0
- package/dist/utils/tokenLimits.js +20 -1
- package/docs-site/static/search-index.json +92 -67
- package/package.json +4 -2
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* Credentials are env-only here, exactly as every other CLI command: the
|
|
11
11
|
* decision provider reads its own settings (TYPESAFE_API_KEY, LAYA_API_KEY and
|
|
12
12
|
* LAYA_BASE_URL, XOR_API_KEY and XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY,
|
|
13
|
-
* CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID,
|
|
13
|
+
* CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, OPENAI_API_KEY, or
|
|
14
|
+
* SCALEDOWN_API_KEY) itself. An
|
|
14
15
|
* OPENAI_API_KEY beside an OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL that names a host
|
|
15
16
|
* other than https://api.openai.com is a gateway's and is not used by default.
|
|
16
17
|
*/
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* Credentials are env-only here, exactly as every other CLI command: the
|
|
11
11
|
* decision provider reads its own settings (TYPESAFE_API_KEY, LAYA_API_KEY and
|
|
12
12
|
* LAYA_BASE_URL, XOR_API_KEY and XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY,
|
|
13
|
-
* CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID,
|
|
13
|
+
* CLOUDFLARE_API_KEY and CLOUDFLARE_ACCOUNT_ID, OPENAI_API_KEY, or
|
|
14
|
+
* SCALEDOWN_API_KEY) itself. An
|
|
14
15
|
* OPENAI_API_KEY beside an OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL that names a host
|
|
15
16
|
* other than https://api.openai.com is a gateway's and is not used by default.
|
|
16
17
|
*/
|
|
@@ -13,7 +13,7 @@ import type { ProviderConfigOptions, SetupArgs } from "../../types/index.js";
|
|
|
13
13
|
* perplexity, sambanova, together-ai, xai — mistral is the 9th catalog
|
|
14
14
|
* provider but keeps its own handleMistralSetup() flow above, so it's
|
|
15
15
|
* excluded here), spread directly from the catalog JSON via
|
|
16
|
-
* buildCatalogConfigOptions(); decide-kind catalog entries (laya, xor, subq, openai-decisions) are
|
|
16
|
+
* buildCatalogConfigOptions(); decide-kind catalog entries (laya, xor, subq, openai-decisions, scaledown) are
|
|
17
17
|
* spread the same way from getDecideCatalogEntries(). The hand rows listed
|
|
18
18
|
* first reuse the existing createXConfig() factories in providerConfig.ts; the
|
|
19
19
|
* remaining 5 (ollama, litellm, sagemaker, lm-studio, llamacpp) don't have a
|
|
@@ -150,7 +150,7 @@ const PROVIDERS = [
|
|
|
150
150
|
* perplexity, sambanova, together-ai, xai — mistral is the 9th catalog
|
|
151
151
|
* provider but keeps its own handleMistralSetup() flow above, so it's
|
|
152
152
|
* excluded here), spread directly from the catalog JSON via
|
|
153
|
-
* buildCatalogConfigOptions(); decide-kind catalog entries (laya, xor, subq, openai-decisions) are
|
|
153
|
+
* buildCatalogConfigOptions(); decide-kind catalog entries (laya, xor, subq, openai-decisions, scaledown) are
|
|
154
154
|
* spread the same way from getDecideCatalogEntries(). The hand rows listed
|
|
155
155
|
* first reuse the existing createXConfig() factories in providerConfig.ts; the
|
|
156
156
|
* remaining 5 (ollama, litellm, sagemaker, lm-studio, llamacpp) don't have a
|
|
@@ -649,7 +649,7 @@ export class CLICommandFactory {
|
|
|
649
649
|
},
|
|
650
650
|
classifierStrategy: {
|
|
651
651
|
type: "string",
|
|
652
|
-
description: "Classifier strategy: 'auto' (default — 'jev' when a decision provider is configured, such as TYPESAFE_API_KEY, LAYA_API_KEY with LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY, CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID,
|
|
652
|
+
description: "Classifier strategy: 'auto' (default — 'jev' when a decision provider is configured, such as TYPESAFE_API_KEY, LAYA_API_KEY with LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY, CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, OPENAI_API_KEY unless OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com, or SCALEDOWN_API_KEY, else 'heuristic'), 'heuristic' (no LLM), 'llm' (a cheap model picks per prompt), or 'jev' (a decision model — whichever decision provider is configured: TypeSafe Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI Decisions or ScaleDown — with the confidence it reports).",
|
|
653
653
|
choices: ["auto", "heuristic", "llm", "jev"],
|
|
654
654
|
alias: "classifier-strategy",
|
|
655
655
|
},
|
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
* - Others: Provider documentation as of Feb 2026
|
|
12
12
|
*/
|
|
13
13
|
export { stripBedrockGeoPrefix } from "./bedrockIdentifiers.js";
|
|
14
|
+
/**
|
|
15
|
+
* The output-token ceiling a JSON-catalog provider declares for one model, or
|
|
16
|
+
* undefined when the provider is not a catalog provider, the model is not
|
|
17
|
+
* listed, or the listing records no maxOutputTokens for it. Never falls back
|
|
18
|
+
* to the provider-wide default (see {@link CATALOG_OUTPUT_CEILINGS}).
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCatalogOutputCeiling(provider: string, model?: string): number | undefined;
|
|
14
21
|
/** Default context window when provider/model is unknown */
|
|
15
22
|
export declare const DEFAULT_CONTEXT_WINDOW = 128000;
|
|
16
23
|
/** Maximum output reserve when maxTokens not specified */
|
|
@@ -37,6 +37,54 @@ const CATALOG_CONTEXT_WINDOWS = Object.fromEntries(getCatalogJsonEntries().map((
|
|
|
37
37
|
: [])),
|
|
38
38
|
},
|
|
39
39
|
]));
|
|
40
|
+
/**
|
|
41
|
+
* Per-model output-token ceilings for the JSON-catalog providers, derived
|
|
42
|
+
* from models.catalog[*].maxOutputTokens and keyed by lowercased provider id
|
|
43
|
+
* and alias. Each provider's map holds every model id as written plus its
|
|
44
|
+
* lowercased form, so a lookup tries the exact spelling first.
|
|
45
|
+
*
|
|
46
|
+
* Deliberately NOT models.defaultMaxOutputTokens: for about 28 catalog
|
|
47
|
+
* providers (groq, xai, together-ai, fireworks, perplexity, cloudflare,
|
|
48
|
+
* mistral ...) that is a generic 4096 placeholder (see manifestRegistry.ts),
|
|
49
|
+
* far below the real ceilings of their models. A model with no recorded
|
|
50
|
+
* maxOutputTokens has no entry here, so it is never capped by a guess.
|
|
51
|
+
*/
|
|
52
|
+
const CATALOG_OUTPUT_CEILINGS = new Map(getCatalogJsonEntries().flatMap((entry) => {
|
|
53
|
+
const ceilings = Object.entries(entry.models.catalog).flatMap(([modelId, spec]) => spec.maxOutputTokens !== undefined &&
|
|
54
|
+
Number.isFinite(spec.maxOutputTokens) &&
|
|
55
|
+
spec.maxOutputTokens > 0
|
|
56
|
+
? [[modelId, spec.maxOutputTokens]]
|
|
57
|
+
: []);
|
|
58
|
+
if (ceilings.length === 0) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
// Lowercased spellings go in first so an exact id always overrides a
|
|
62
|
+
// case-folded one; two ids differing only by case keep the smaller cap.
|
|
63
|
+
const byModel = new Map();
|
|
64
|
+
for (const [modelId, ceiling] of ceilings) {
|
|
65
|
+
const folded = modelId.toLowerCase();
|
|
66
|
+
byModel.set(folded, Math.min(byModel.get(folded) ?? ceiling, ceiling));
|
|
67
|
+
}
|
|
68
|
+
for (const [modelId, ceiling] of ceilings) {
|
|
69
|
+
byModel.set(modelId, ceiling);
|
|
70
|
+
}
|
|
71
|
+
return [entry.id, ...entry.aliases].map((name) => [name.toLowerCase(), byModel]);
|
|
72
|
+
}));
|
|
73
|
+
/**
|
|
74
|
+
* The output-token ceiling a JSON-catalog provider declares for one model, or
|
|
75
|
+
* undefined when the provider is not a catalog provider, the model is not
|
|
76
|
+
* listed, or the listing records no maxOutputTokens for it. Never falls back
|
|
77
|
+
* to the provider-wide default (see {@link CATALOG_OUTPUT_CEILINGS}).
|
|
78
|
+
*/
|
|
79
|
+
export function getCatalogOutputCeiling(provider, model) {
|
|
80
|
+
// getSafeMaxTokens has always tolerated a missing provider, so this lookup
|
|
81
|
+
// must too (callers outside the typed option normalisers can pass one).
|
|
82
|
+
if (!model || typeof provider !== "string") {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
const ceilings = CATALOG_OUTPUT_CEILINGS.get(provider.toLowerCase());
|
|
86
|
+
return ceilings?.get(model) ?? ceilings?.get(model.toLowerCase());
|
|
87
|
+
}
|
|
40
88
|
/** Default context window when provider/model is unknown */
|
|
41
89
|
export const DEFAULT_CONTEXT_WINDOW = 128_000;
|
|
42
90
|
/** Maximum output reserve when maxTokens not specified */
|
|
@@ -85,6 +85,7 @@ export declare enum AIProviderName {
|
|
|
85
85
|
SAKANA_AI = "sakana-ai",
|
|
86
86
|
SAMBANOVA = "sambanova",
|
|
87
87
|
SARVAM = "sarvam",
|
|
88
|
+
SCALEDOWN = "scaledown",
|
|
88
89
|
SCALEWAY = "scaleway",
|
|
89
90
|
SILICONFLOW = "siliconflow",
|
|
90
91
|
STACKIT = "stackit",
|
|
@@ -1570,6 +1571,10 @@ export declare enum SarvamModels {
|
|
|
1570
1571
|
SARVAM_105B = "sarvam-105b",
|
|
1571
1572
|
SARVAM_105B_CONVERSATIONS = "sarvam-105b-conversations"
|
|
1572
1573
|
}
|
|
1574
|
+
export declare enum ScaleDownModels {
|
|
1575
|
+
CLASSIFY_1 = "classify-1",
|
|
1576
|
+
CLASSIFY = "classify"
|
|
1577
|
+
}
|
|
1573
1578
|
export declare enum ScalewayModels {
|
|
1574
1579
|
MISTRAL_SMALL_3_2_24B_INSTRUCT_2506 = "mistral-small-3.2-24b-instruct-2506",
|
|
1575
1580
|
LLAMA_3_3_70B_INSTRUCT = "llama-3.3-70b-instruct",
|
package/dist/constants/enums.js
CHANGED
|
@@ -90,6 +90,7 @@ export var AIProviderName;
|
|
|
90
90
|
AIProviderName["SAKANA_AI"] = "sakana-ai";
|
|
91
91
|
AIProviderName["SAMBANOVA"] = "sambanova";
|
|
92
92
|
AIProviderName["SARVAM"] = "sarvam";
|
|
93
|
+
AIProviderName["SCALEDOWN"] = "scaledown";
|
|
93
94
|
AIProviderName["SCALEWAY"] = "scaleway";
|
|
94
95
|
AIProviderName["SILICONFLOW"] = "siliconflow";
|
|
95
96
|
AIProviderName["STACKIT"] = "stackit";
|
|
@@ -1875,6 +1876,11 @@ export var SarvamModels;
|
|
|
1875
1876
|
SarvamModels["SARVAM_105B"] = "sarvam-105b";
|
|
1876
1877
|
SarvamModels["SARVAM_105B_CONVERSATIONS"] = "sarvam-105b-conversations";
|
|
1877
1878
|
})(SarvamModels || (SarvamModels = {}));
|
|
1879
|
+
export var ScaleDownModels;
|
|
1880
|
+
(function (ScaleDownModels) {
|
|
1881
|
+
ScaleDownModels["CLASSIFY_1"] = "classify-1";
|
|
1882
|
+
ScaleDownModels["CLASSIFY"] = "classify";
|
|
1883
|
+
})(ScaleDownModels || (ScaleDownModels = {}));
|
|
1878
1884
|
export var ScalewayModels;
|
|
1879
1885
|
(function (ScalewayModels) {
|
|
1880
1886
|
ScalewayModels["MISTRAL_SMALL_3_2_24B_INSTRUCT_2506"] = "mistral-small-3.2-24b-instruct-2506";
|
|
@@ -469,18 +469,22 @@ const HAND_DESCRIPTORS = [
|
|
|
469
469
|
},
|
|
470
470
|
// Decision precedence is decideOrder, not position: typesafe 1, laya 2 and
|
|
471
471
|
// xor 3 (from catalog/laya.json and catalog/xor.json), subq 4 (from
|
|
472
|
-
// catalog/subq.json), perplexity-decider 5, cloudflare-clef 6
|
|
473
|
-
// openai-decisions 7 (catalog/openai-decisions.json)
|
|
472
|
+
// catalog/subq.json), perplexity-decider 5, cloudflare-clef 6,
|
|
473
|
+
// openai-decisions 7 (catalog/openai-decisions.json) and scaledown 8
|
|
474
|
+
// (catalog/scaledown.json).
|
|
474
475
|
// resolveDefaultDecisionProvider() returns the first configured
|
|
475
476
|
// DECISION_PROVIDERS entry in that order, so a host configured for several
|
|
476
477
|
// keeps Jev for every built-in consumer and reaches the others only by
|
|
477
478
|
// naming them. Renumbering silently changes which model routes, compacts
|
|
478
479
|
// and plans for every such host.
|
|
479
|
-
// perplexity-decider, cloudflare-clef and openai-decisions come
|
|
480
|
-
// each shares its environment key with a text provider: a key set only
|
|
481
|
-
// that text provider must not displace a decision provider a host set up on
|
|
480
|
+
// perplexity-decider, cloudflare-clef and openai-decisions come after subq
|
|
481
|
+
// because each shares its environment key with a text provider: a key set only
|
|
482
|
+
// for that text provider must not displace a decision provider a host set up on
|
|
482
483
|
// purpose. subq is ahead of them only because SUBQ_API_KEY belongs to no other
|
|
483
|
-
// provider.
|
|
484
|
+
// provider. scaledown is last by the owner's decision of 2026-10-15, not by
|
|
485
|
+
// that rule: SCALEDOWN_API_KEY belongs to no other provider either, so an
|
|
486
|
+
// ambient OPENAI_API_KEY, PERPLEXITY_API_KEY or Cloudflare pair outranks a
|
|
487
|
+
// ScaleDown key a host set on purpose, and ScaleDown is reached by naming it.
|
|
484
488
|
{
|
|
485
489
|
name: AIProviderName.PERPLEXITY_DECIDER,
|
|
486
490
|
aliases: [],
|
|
@@ -552,9 +556,9 @@ const HAND_DESCRIPTORS = [
|
|
|
552
556
|
credentialsKey: "cloudflareClef",
|
|
553
557
|
envVars: {
|
|
554
558
|
// The same token and account id the `cloudflare` text provider reads, so
|
|
555
|
-
// ambient Workers AI settings configure this provider too.
|
|
556
|
-
//
|
|
557
|
-
//
|
|
559
|
+
// ambient Workers AI settings configure this provider too. Its place in
|
|
560
|
+
// the decision order (see the comment above) keeps that from displacing
|
|
561
|
+
// TypeSafe, Laya, XOR or SubQ.
|
|
558
562
|
apiKey: "CLOUDFLARE_API_KEY",
|
|
559
563
|
// Cloudflare's own API is the endpoint, so a base URL is optional; but
|
|
560
564
|
// the path carries the account id, so a token alone is useless. Both are
|
package/dist/neurolink.js
CHANGED
|
@@ -14298,7 +14298,13 @@ Current user's request: ${currentInput}`;
|
|
|
14298
14298
|
timeoutMs: options.timeoutMs,
|
|
14299
14299
|
});
|
|
14300
14300
|
const answerCount = Object.keys(result.answers).length;
|
|
14301
|
-
|
|
14301
|
+
// `providerName` is what the caller passed, so it can be an alias
|
|
14302
|
+
// (`jev`, `scaledown-classify`). The pricing table is keyed by the
|
|
14303
|
+
// canonical id and does not read the decide catalog, so an alias
|
|
14304
|
+
// priced the decision at 0.
|
|
14305
|
+
const pricedProvider = PROVIDER_ALIAS_INDEX.get(providerName.toLowerCase()) ??
|
|
14306
|
+
providerName;
|
|
14307
|
+
const cost = calculateCost(pricedProvider, result.model, {
|
|
14302
14308
|
input: result.usage.inputTokens,
|
|
14303
14309
|
output: result.usage.outputTokens,
|
|
14304
14310
|
total: result.usage.inputTokens + result.usage.outputTokens,
|
|
@@ -89,11 +89,10 @@
|
|
|
89
89
|
},
|
|
90
90
|
"vision": true,
|
|
91
91
|
"status": "production",
|
|
92
|
-
"description": "Moonshot Kimi K3 — vision-capable per the live roster; reasoning effort levels low/high/xhigh (default high). Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28)."
|
|
92
|
+
"description": "Moonshot Kimi K3 — vision-capable per the live roster; reasoning effort levels low/high/xhigh (default high). Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28). The 16000 max output tokens is Hyper's own cap for this model: Hyper's List Models docs (https://hyper.charm.land/docs/api/list-models.html) define `max_output_tokens` as the model's max output tokens, and the roster still reported 16000 on 2026-10-18. Moonshot's own API allows more (`max_completion_tokens` defaults to 131072 and can be set up to 1048576, per https://platform.kimi.ai/docs/guide/kimi-k3-quickstart), so the cap belongs to this gateway, not to the model."
|
|
93
93
|
},
|
|
94
94
|
"kimi-k2-thinking": {
|
|
95
95
|
"contextWindow": 262144,
|
|
96
|
-
"maxOutputTokens": 26214,
|
|
97
96
|
"pricingPerMTok": {
|
|
98
97
|
"input": 0.6,
|
|
99
98
|
"output": 2.5,
|
|
@@ -101,7 +100,7 @@
|
|
|
101
100
|
},
|
|
102
101
|
"vision": false,
|
|
103
102
|
"status": "production",
|
|
104
|
-
"description": "Moonshot Kimi K2 Thinking — reasoning-first Kimi variant; reasoning effort levels low/high/xhigh (default high). Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28)."
|
|
103
|
+
"description": "Moonshot Kimi K2 Thinking — reasoning-first Kimi variant; reasoning effort levels low/high/xhigh (default high). Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28). No maxOutputTokens is recorded: the roster reports 26214, which is a fixed fraction of the 262144-token context window and reads like a gateway default rather than a model limit."
|
|
105
104
|
},
|
|
106
105
|
"kimi-k2.7-code": {
|
|
107
106
|
"contextWindow": 256000,
|
|
@@ -113,7 +112,7 @@
|
|
|
113
112
|
},
|
|
114
113
|
"vision": true,
|
|
115
114
|
"status": "production",
|
|
116
|
-
"description": "Moonshot Kimi K2.7 Code — code-focused Kimi variant, vision-capable per the live roster; reasoning effort levels low/high/xhigh (default high). Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28)."
|
|
115
|
+
"description": "Moonshot Kimi K2.7 Code — code-focused Kimi variant, vision-capable per the live roster; reasoning effort levels low/high/xhigh (default high). Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28). The 16000 max output tokens is Hyper's own cap for this model: Hyper's List Models docs (https://hyper.charm.land/docs/api/list-models.html) define `max_output_tokens` as the model's max output tokens, and the roster still reported 16000 on 2026-10-18. Moonshot's own API defaults `max_tokens` to 32768 (https://platform.kimi.ai/docs/guide/kimi-k2-7-code-quickstart), so the cap belongs to this gateway, not to the model."
|
|
117
116
|
},
|
|
118
117
|
"glm-5.3": {
|
|
119
118
|
"contextWindow": 1000000,
|
|
@@ -165,7 +164,6 @@
|
|
|
165
164
|
},
|
|
166
165
|
"minimax-m2.7": {
|
|
167
166
|
"contextWindow": 262100,
|
|
168
|
-
"maxOutputTokens": 6553,
|
|
169
167
|
"pricingPerMTok": {
|
|
170
168
|
"input": 0.484,
|
|
171
169
|
"output": 1.852,
|
|
@@ -173,7 +171,7 @@
|
|
|
173
171
|
},
|
|
174
172
|
"vision": false,
|
|
175
173
|
"status": "production",
|
|
176
|
-
"description": "MiniMax M2.7 — prior MiniMax generation. Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28)."
|
|
174
|
+
"description": "MiniMax M2.7 — prior MiniMax generation. Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28). No maxOutputTokens is recorded: the roster reports 6553, which is a fixed fraction of the 262100-token context window and reads like a gateway default rather than a model limit."
|
|
177
175
|
},
|
|
178
176
|
"inkling": {
|
|
179
177
|
"contextWindow": 1048576,
|
|
@@ -273,7 +271,6 @@
|
|
|
273
271
|
},
|
|
274
272
|
"gpt-oss-120b": {
|
|
275
273
|
"contextWindow": 131072,
|
|
276
|
-
"maxOutputTokens": 13107,
|
|
277
274
|
"pricingPerMTok": {
|
|
278
275
|
"input": 0.178,
|
|
279
276
|
"output": 0.68,
|
|
@@ -281,11 +278,10 @@
|
|
|
281
278
|
},
|
|
282
279
|
"vision": false,
|
|
283
280
|
"status": "production",
|
|
284
|
-
"description": "OpenAI's open-weight gpt-oss-120b. Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28)."
|
|
281
|
+
"description": "OpenAI's open-weight gpt-oss-120b. Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28). No maxOutputTokens is recorded: the roster reports 13107, which is a fixed fraction of the 131072-token context window and reads like a gateway default rather than a model limit."
|
|
285
282
|
},
|
|
286
283
|
"gemma-4-26b-a4b-it": {
|
|
287
284
|
"contextWindow": 256000,
|
|
288
|
-
"maxOutputTokens": 25600,
|
|
289
285
|
"pricingPerMTok": {
|
|
290
286
|
"input": 0.098,
|
|
291
287
|
"output": 0.334,
|
|
@@ -293,7 +289,7 @@
|
|
|
293
289
|
},
|
|
294
290
|
"vision": false,
|
|
295
291
|
"status": "production",
|
|
296
|
-
"description": "Google Gemma 4 26B A4B, instruction-tuned. Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28)."
|
|
292
|
+
"description": "Google Gemma 4 26B A4B, instruction-tuned. Context window, max output tokens, vision and pricing per GET https://hyper.charm.land/v1/models (unauthenticated, 2026-09-28). No maxOutputTokens is recorded: the roster reports 25600, which is a fixed fraction of the 256000-token context window and reads like a gateway default rather than a model limit."
|
|
297
293
|
}
|
|
298
294
|
},
|
|
299
295
|
"topModels": [
|
|
@@ -2,4 +2,4 @@ import type { DecideCatalogJson, ProviderCatalogJson } from "../../types/index.j
|
|
|
2
2
|
export declare const CATALOG_JSON_ENTRIES: ProviderCatalogJson[];
|
|
3
3
|
export declare const CATALOG_PROVIDER_IDS: readonly ["a2agent", "abliteration", "above-dev", "ai21", "aiand", "aihubmix", "aionlabs", "ambient", "api-route", "arcee", "atlas-cloud", "avian-io", "baidu-qianfan", "baseten", "bee-heossi", "byteplus-modelark", "bytez", "cerebras", "charm-hyper", "chutes", "cloudflare", "crusoe", "dashscope", "deepinfra", "deepseek", "empiriolabs", "featherless-ai", "fireworks", "friendli", "gmicloud", "gradientai", "groq", "hetzner-inference", "huggingface", "inception-labs", "inceptron", "inco", "inference-net", "io-intelligence", "koscompute", "lemonfox-ai", "lilac", "llmtech", "longcat", "mancer", "meta-model-api", "minimax", "mistral", "moark", "modelscope", "moonshot-ai", "morph", "naver-clova-studio", "nebius", "neuralwatt", "novita", "ovhcloud", "parasail", "pareto-inference", "perplexity", "poolside", "prime-intellect", "reka", "runinfra", "sakana-ai", "sambanova", "sarvam", "scaleway", "siliconflow", "stackit", "stepfun", "subconscious", "synthetic", "telnyx", "thinking-machines", "tinfoil", "together-ai", "umans-ai", "upstage", "venice-ai", "vispark", "vultr-inference", "wafer", "wandb-inference", "xai", "xiaomi-mimo", "z-ai"];
|
|
4
4
|
export declare const DECIDE_CATALOG_JSON_ENTRIES: DecideCatalogJson[];
|
|
5
|
-
export declare const DECIDE_CATALOG_PROVIDER_IDS: readonly ["laya", "openai-decisions", "subq", "xor"];
|
|
5
|
+
export declare const DECIDE_CATALOG_PROVIDER_IDS: readonly ["laya", "openai-decisions", "scaledown", "subq", "xor"];
|
|
@@ -69,6 +69,7 @@ import runinfraJson from "./runinfra.json" with { type: "json" };
|
|
|
69
69
|
import sakanaAiJson from "./sakana-ai.json" with { type: "json" };
|
|
70
70
|
import sambanovaJson from "./sambanova.json" with { type: "json" };
|
|
71
71
|
import sarvamJson from "./sarvam.json" with { type: "json" };
|
|
72
|
+
import scaledownJson from "./scaledown.json" with { type: "json" };
|
|
72
73
|
import scalewayJson from "./scaleway.json" with { type: "json" };
|
|
73
74
|
import siliconflowJson from "./siliconflow.json" with { type: "json" };
|
|
74
75
|
import stackitJson from "./stackit.json" with { type: "json" };
|
|
@@ -280,12 +281,14 @@ export const CATALOG_PROVIDER_IDS = [
|
|
|
280
281
|
export const DECIDE_CATALOG_JSON_ENTRIES = [
|
|
281
282
|
layaJson,
|
|
282
283
|
openaiDecisionsJson,
|
|
284
|
+
scaledownJson,
|
|
283
285
|
subqJson,
|
|
284
286
|
xorJson,
|
|
285
287
|
].map(asDecideEntry);
|
|
286
288
|
export const DECIDE_CATALOG_PROVIDER_IDS = [
|
|
287
289
|
"laya",
|
|
288
290
|
"openai-decisions",
|
|
291
|
+
"scaledown",
|
|
289
292
|
"subq",
|
|
290
293
|
"xor",
|
|
291
294
|
];
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"instructions": [
|
|
61
61
|
"1. Create an API key at https://platform.openai.com/api-keys",
|
|
62
62
|
"2. Set {apiKeyEnvVar}; it is shared with the openai chat provider",
|
|
63
|
-
"3. With no other decision provider configured, {apiKeyEnvVar} alone makes openai-decisions the default decision provider (
|
|
63
|
+
"3. With no other decision provider configured, {apiKeyEnvVar} alone makes openai-decisions the default decision provider (a last resort, after every other one except ScaleDown, as PERPLEXITY_API_KEY does for perplexity-decider), unless OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL names a host other than https://api.openai.com: the key is then taken to be a gateway's and is not used by default. To use it while another provider is configured, name it in a call (provider: \"openai-decisions\" or --provider openai-decisions), but only if the key is OpenAI's, because a named call sends the environment key to api.openai.com. Behind a gateway, route it on purpose with OPENAI_DECISIONS_BASE_URL or credentials.openaiDecisions, or do not use it",
|
|
64
64
|
"4. Optional: OPENAI_DECISIONS_BASE_URL (an origin) and OPENAI_DECISIONS_MODEL (default gpt-6-luna)"
|
|
65
65
|
]
|
|
66
66
|
},
|
|
@@ -142,6 +142,14 @@
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
},
|
|
145
|
+
"authHeader": {
|
|
146
|
+
"enum": ["bearer", "x-api-key"],
|
|
147
|
+
"description": "How the API key is sent. bearer, the default when omitted, sends Authorization: Bearer <key>. x-api-key sends x-api-key: <key> and no Authorization header at all. This is the decide request's own setting; quirks.authHeaderStyle belongs to the chat path and is not read here."
|
|
148
|
+
},
|
|
149
|
+
"stateEncoding": {
|
|
150
|
+
"enum": ["text"],
|
|
151
|
+
"description": "text makes the state that goes out always a string: a string is sent unchanged (not trimmed), any other value is sent as its JSON text, and a state that is blank after trimming is refused before any request, as an invalid_request. Omitted means the state goes out as given."
|
|
152
|
+
},
|
|
145
153
|
"media": {
|
|
146
154
|
"type": "object",
|
|
147
155
|
"additionalProperties": false,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./provider-catalog.schema.json",
|
|
3
|
+
"id": "scaledown",
|
|
4
|
+
"displayName": "ScaleDown",
|
|
5
|
+
"enumTypeName": "ScaleDownModels",
|
|
6
|
+
"aliases": ["scaledown-classify"],
|
|
7
|
+
"inferenceKinds": ["decide"],
|
|
8
|
+
"wire": { "baseURL": "https://api.scaledown.xyz" },
|
|
9
|
+
"models": {
|
|
10
|
+
"default": "classify-1",
|
|
11
|
+
"topModels": ["classify-1", "classify"],
|
|
12
|
+
"catalog": {
|
|
13
|
+
"classify-1": {
|
|
14
|
+
"contextWindow": 128000,
|
|
15
|
+
"maxOutputTokens": 1,
|
|
16
|
+
"vision": false,
|
|
17
|
+
"status": "preview",
|
|
18
|
+
"description": "Recommended - ScaleDown Classify 1, decision model for boolean, choice and score questions; context window and output limit not established"
|
|
19
|
+
},
|
|
20
|
+
"classify": {
|
|
21
|
+
"vision": false,
|
|
22
|
+
"status": "preview",
|
|
23
|
+
"description": "ScaleDown's name for its latest Classify model; whether it moves to a newer model is not established"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"decide": {
|
|
28
|
+
"dialect": "system-one",
|
|
29
|
+
"order": 8,
|
|
30
|
+
"baseURLNormalize": ["strip-trailing-slash"],
|
|
31
|
+
"endpoint": "{baseURL}/v1/scaledown",
|
|
32
|
+
"model": { "placement": "body" },
|
|
33
|
+
"authHeader": "x-api-key",
|
|
34
|
+
"stateEncoding": "text",
|
|
35
|
+
"errors": {
|
|
36
|
+
"rules": [
|
|
37
|
+
{ "status": 401, "kind": "authentication" },
|
|
38
|
+
{ "status": [402, 422], "kind": "invalid_request" },
|
|
39
|
+
{ "status": 429, "kind": "rate_limit" },
|
|
40
|
+
{ "status": 502, "kind": "server" },
|
|
41
|
+
{ "status": 504, "kind": "timeout" },
|
|
42
|
+
{ "statusMin": 500, "kind": "server" }
|
|
43
|
+
],
|
|
44
|
+
"default": "invalid_request",
|
|
45
|
+
"bodyShapes": [{ "path": "detail.message" }, { "path": "detail" }]
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"setup": {
|
|
49
|
+
"url": "https://docs.scaledown.ai",
|
|
50
|
+
"apiKeyFormat": null,
|
|
51
|
+
"billingPolicy": "promotional-credit",
|
|
52
|
+
"description": "API key from ScaleDown (see its documentation). Sign-up gives a free allowance; whether it expires is not established",
|
|
53
|
+
"instructions": [
|
|
54
|
+
"1. Create an account and an API key, following https://docs.scaledown.ai",
|
|
55
|
+
"2. Set {apiKeyEnvVar} in your .env file",
|
|
56
|
+
"3. ScaleDown's documentation says the key goes in an x-api-key header rather than Authorization: Bearer, and NeuroLink sends it that way",
|
|
57
|
+
"4. ScaleDown's documentation says a request made with no credit left returns HTTP 402"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"evidence": {
|
|
61
|
+
"rosterVerified": {
|
|
62
|
+
"date": "2026-10-15",
|
|
63
|
+
"method": "Checked by the marketing session, not in this change: ScaleDown's docs at docs.scaledown.ai were read and probes were made against api.scaledown.xyz. No request was made to ScaleDown in this change"
|
|
64
|
+
},
|
|
65
|
+
"liveMatrix": null,
|
|
66
|
+
"addedInPR": "https://github.com/juspay/neurolink/pull/2005"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -600,6 +600,8 @@ const decideBlockSchema = z.strictObject({
|
|
|
600
600
|
placement: z.enum(["body", "body-unless-alias"]),
|
|
601
601
|
alias: z.string().min(1).optional(),
|
|
602
602
|
}),
|
|
603
|
+
authHeader: z.enum(["bearer", "x-api-key"]).optional(),
|
|
604
|
+
stateEncoding: z.enum(["text"]).optional(),
|
|
603
605
|
media: decideMediaSchema.optional(),
|
|
604
606
|
ambientKeyGuard: ambientKeyGuardSchema.optional(),
|
|
605
607
|
requestIdHeaders: z.array(decideHeaderNameSchema).optional(),
|
|
@@ -15,6 +15,11 @@ export declare class ConfiguredDecisionProvider extends SystemOneDecisionProvide
|
|
|
15
15
|
protected missingConfigMessage(): string | undefined;
|
|
16
16
|
protected decisionEndpoint(): string;
|
|
17
17
|
protected decisionHeaders(): Record<string, string>;
|
|
18
|
+
/**
|
|
19
|
+
* The state the dialect is given. Only an entry that sets `stateEncoding`
|
|
20
|
+
* changes it, so every other entry sends exactly what the caller passed.
|
|
21
|
+
*/
|
|
22
|
+
private encodeState;
|
|
18
23
|
protected buildDecisionBody(state: DecisionState, questions: Record<string, Record<string, unknown>>, model: string, media?: DecisionPreparedMedia): Record<string, unknown>;
|
|
19
24
|
protected parseDecisionError(status: number, payload: unknown, requestId: string | undefined): DecisionError;
|
|
20
25
|
protected readRequestId(headers: Headers): string | undefined;
|
|
@@ -10,6 +10,9 @@ import { readPath } from "./decide/paths.js";
|
|
|
10
10
|
import { fillEndpointTemplate } from "./decide/template.js";
|
|
11
11
|
import { SystemOneDecisionProvider } from "./systemOneDecision.js";
|
|
12
12
|
const readText = (value) => typeof value === "string" ? value.trim() : "";
|
|
13
|
+
// JSON.stringify answers undefined for a value JSON cannot hold, such as a
|
|
14
|
+
// state a JavaScript caller left out, although its own return type says string.
|
|
15
|
+
const stateText = (state) => typeof state === "string" ? state : JSON.stringify(state);
|
|
13
16
|
/** A `decide` provider described entirely by its catalog entry. */
|
|
14
17
|
export class ConfiguredDecisionProvider extends SystemOneDecisionProvider {
|
|
15
18
|
entry;
|
|
@@ -68,15 +71,34 @@ export class ConfiguredDecisionProvider extends SystemOneDecisionProvider {
|
|
|
68
71
|
return this.endpoint;
|
|
69
72
|
}
|
|
70
73
|
decisionHeaders() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
};
|
|
74
|
+
const credential = this.entry.decide.authHeader === "x-api-key"
|
|
75
|
+
? { "x-api-key": this.apiKey }
|
|
76
|
+
: { Authorization: `Bearer ${this.apiKey}` };
|
|
77
|
+
return { ...credential, "Content-Type": "application/json" };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The state the dialect is given. Only an entry that sets `stateEncoding`
|
|
81
|
+
* changes it, so every other entry sends exactly what the caller passed.
|
|
82
|
+
*/
|
|
83
|
+
encodeState(state) {
|
|
84
|
+
if (this.entry.decide.stateEncoding !== "text") {
|
|
85
|
+
return state;
|
|
86
|
+
}
|
|
87
|
+
const text = stateText(state);
|
|
88
|
+
if (text === undefined || text.trim() === "") {
|
|
89
|
+
throw this.decisionError({
|
|
90
|
+
kind: "invalid_request",
|
|
91
|
+
// Never the state itself, which can hold anything the caller was sent.
|
|
92
|
+
message: `${this.vendorLabel()} needs non-blank state text; the state was empty or only whitespace.`,
|
|
93
|
+
retryable: false,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return text;
|
|
75
97
|
}
|
|
76
98
|
buildDecisionBody(state, questions, model, media) {
|
|
77
99
|
const { placement, alias } = this.entry.decide.model;
|
|
78
100
|
return this.dialect().buildBody({
|
|
79
|
-
state,
|
|
101
|
+
state: this.encodeState(state),
|
|
80
102
|
questions,
|
|
81
103
|
model: placement === "body-unless-alias" && model === alias
|
|
82
104
|
? undefined
|
|
@@ -24,16 +24,16 @@ export type ClassifierDifficulty = "trivial" | "simple" | "moderate" | "hard" |
|
|
|
24
24
|
* - `heuristic` — keyword/length scoring. Deterministic, zero latency.
|
|
25
25
|
* - `llm` — a cheap classifier model via the injected `generate`.
|
|
26
26
|
* - `jev` — a decision model, whichever decision provider is configured
|
|
27
|
-
* (TypeSafe's Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef
|
|
28
|
-
* Decisions); one round trip that returns the confidence the provider
|
|
27
|
+
* (TypeSafe's Jev, Laya, XOR, SubQ, Perplexity, Cloudflare Clef, OpenAI
|
|
28
|
+
* Decisions or ScaleDown); one round trip that returns the confidence the provider
|
|
29
29
|
* reports (*calibrated* on TypeSafe's Jev, ~400ms there) rather than a
|
|
30
30
|
* self-reported one.
|
|
31
31
|
* - `auto` — `jev` when a decision provider is configured, in the environment
|
|
32
32
|
* or in SDK credentials (`TYPESAFE_API_KEY`, `LAYA_API_KEY` with
|
|
33
33
|
* `LAYA_BASE_URL`, `XOR_API_KEY` with `XOR_BASE_URL`, `SUBQ_API_KEY`, `PERPLEXITY_API_KEY`,
|
|
34
|
-
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`,
|
|
34
|
+
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`, `OPENAI_API_KEY`,
|
|
35
35
|
* which does not count while `OPENAI_BASE_URL`, `OPENAI_API_BASE` or `credentials.openai.baseURL` names a
|
|
36
|
-
* host other than `https://api.openai.com`), otherwise `heuristic`.
|
|
36
|
+
* host other than `https://api.openai.com`, or `SCALEDOWN_API_KEY`), otherwise `heuristic`.
|
|
37
37
|
*/
|
|
38
38
|
export type ClassifierStrategyKind = "heuristic" | "llm" | "jev" | "auto";
|
|
39
39
|
/**
|
|
@@ -195,15 +195,16 @@ export type ClassifierRouterConfig = {
|
|
|
195
195
|
* decision provider is configured, in the environment or in SDK credentials
|
|
196
196
|
* (`TYPESAFE_API_KEY`, `LAYA_API_KEY` with `LAYA_BASE_URL`,
|
|
197
197
|
* `XOR_API_KEY` with `XOR_BASE_URL`, `SUBQ_API_KEY`, `PERPLEXITY_API_KEY`,
|
|
198
|
-
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`,
|
|
199
|
-
* "heuristic" otherwise, so configuring one upgrades routing without any code
|
|
198
|
+
* `CLOUDFLARE_API_KEY` with `CLOUDFLARE_ACCOUNT_ID`, `OPENAI_API_KEY` or
|
|
199
|
+
* `SCALEDOWN_API_KEY`) and "heuristic" otherwise, so configuring one upgrades routing without any code
|
|
200
200
|
* change. Behaviour for a caller with none of these is unchanged. Three of them
|
|
201
201
|
* are shared with a text provider and count here too: `PERPLEXITY_API_KEY`
|
|
202
202
|
* (Perplexity's), the Cloudflare pair (Workers AI's) and `OPENAI_API_KEY` (the
|
|
203
203
|
* OpenAI chat provider's). A caller whose only key is `OPENAI_API_KEY` now
|
|
204
|
-
* resolves to "jev", answered by OpenAI Decisions
|
|
205
|
-
* provider
|
|
206
|
-
*
|
|
204
|
+
* resolves to "jev", answered by OpenAI Decisions (the default decision
|
|
205
|
+
* provider whenever none ahead of it in the order is configured); each
|
|
206
|
+
* classification is then a paid call that still falls back to the heuristic
|
|
207
|
+
* on any failure. The exception is a key that sits beside an
|
|
207
208
|
* `OPENAI_BASE_URL`, `OPENAI_API_BASE` or `credentials.openai.baseURL` naming a host other than
|
|
208
209
|
* `https://api.openai.com`: that key is a gateway's and does not count.
|
|
209
210
|
*/
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -1770,9 +1770,9 @@ export type CliClassifierRouterFlags = {
|
|
|
1770
1770
|
* (--classifier-strategy). "auto" resolves to "jev" when a decision
|
|
1771
1771
|
* provider is configured (TYPESAFE_API_KEY, LAYA_API_KEY with
|
|
1772
1772
|
* LAYA_BASE_URL, XOR_API_KEY with XOR_BASE_URL, SUBQ_API_KEY, PERPLEXITY_API_KEY,
|
|
1773
|
-
* CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID,
|
|
1773
|
+
* CLOUDFLARE_API_KEY with CLOUDFLARE_ACCOUNT_ID, OPENAI_API_KEY, which does
|
|
1774
1774
|
* not count beside an OPENAI_BASE_URL, OPENAI_API_BASE or credentials.openai.baseURL naming a host other
|
|
1775
|
-
* than https://api.openai.com) and "heuristic" otherwise.
|
|
1775
|
+
* than https://api.openai.com, or SCALEDOWN_API_KEY) and "heuristic" otherwise.
|
|
1776
1776
|
*/
|
|
1777
1777
|
classifierStrategy?: string;
|
|
1778
1778
|
/**
|
|
@@ -25,6 +25,14 @@ export type CatalogTimeouts = {
|
|
|
25
25
|
};
|
|
26
26
|
export type CatalogModelSpec = {
|
|
27
27
|
contextWindow?: number;
|
|
28
|
+
/**
|
|
29
|
+
* The model's own output-token limit. Enforced at runtime: for a provider
|
|
30
|
+
* with no PROVIDER_MAX_TOKENS row, getSafeMaxTokens clamps a larger
|
|
31
|
+
* requested maxTokens to this value. Record only a number the vendor states
|
|
32
|
+
* as a hard limit; omit it when the source is a roster field that looks
|
|
33
|
+
* derived from the context window, because an omitted value leaves the
|
|
34
|
+
* model uncapped while a wrong one silently truncates callers.
|
|
35
|
+
*/
|
|
28
36
|
maxOutputTokens?: number;
|
|
29
37
|
pricingPerMTok?: CatalogPricingPerMTok;
|
|
30
38
|
vision: boolean;
|
|
@@ -314,6 +322,20 @@ export type DecideBlock = {
|
|
|
314
322
|
/** Request URL; `{baseURL}` is the only placeholder. */
|
|
315
323
|
endpoint: string;
|
|
316
324
|
model: DecideModel;
|
|
325
|
+
/**
|
|
326
|
+
* How the API key is sent. `bearer`, the default when omitted, sends
|
|
327
|
+
* `Authorization: Bearer <key>`. `x-api-key` sends `x-api-key: <key>` and no
|
|
328
|
+
* `Authorization` header at all. This is the decide request's own setting;
|
|
329
|
+
* `quirks.authHeaderStyle` belongs to the chat path and is not read here.
|
|
330
|
+
*/
|
|
331
|
+
authHeader?: "bearer" | "x-api-key";
|
|
332
|
+
/**
|
|
333
|
+
* `text` makes the state that goes out always a string: a string is sent
|
|
334
|
+
* unchanged (not trimmed), any other value is sent as its JSON text, and a
|
|
335
|
+
* state that is blank after trimming is refused before any request, as an
|
|
336
|
+
* `invalid_request`. Omitted means the state goes out as given.
|
|
337
|
+
*/
|
|
338
|
+
stateEncoding?: "text";
|
|
317
339
|
/** Body keys for images and video, after `model`, `state` and `questions`. Omitted means the body never carries media. */
|
|
318
340
|
media?: DecideMedia;
|
|
319
341
|
/**
|