@juspay/neurolink 12.14.9 ā 12.14.10
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 +2 -2
- package/dist/browser/neurolink.min.js +2 -2
- package/dist/cli/commands/config.js +2 -2
- package/dist/cli/commands/setup-huggingface.js +19 -11
- package/dist/core/modelConfiguration.d.ts +3 -3
- package/dist/core/modelConfiguration.js +6 -4
- package/dist/models/manifests/huggingface.d.ts +6 -3
- package/dist/models/manifests/huggingface.js +7 -4
- package/dist/providers/huggingFace/client.d.ts +30 -7
- package/dist/providers/huggingFace/client.js +44 -26
- package/dist/utils/providerSetupMessages.js +2 -2
- package/docs-site/static/search-index.json +1 -1
- package/package.json +1 -1
|
@@ -87,7 +87,7 @@ const ConfigSchema = z.object({
|
|
|
87
87
|
huggingface: z
|
|
88
88
|
.object({
|
|
89
89
|
apiKey: z.string().optional(),
|
|
90
|
-
model: z.string().default("
|
|
90
|
+
model: z.string().default("Qwen/Qwen2.5-72B-Instruct"),
|
|
91
91
|
})
|
|
92
92
|
.optional(),
|
|
93
93
|
ollama: z
|
|
@@ -783,7 +783,7 @@ export class ConfigManager {
|
|
|
783
783
|
type: "input",
|
|
784
784
|
name: "model",
|
|
785
785
|
message: "Model name:",
|
|
786
|
-
default: "
|
|
786
|
+
default: "Qwen/Qwen2.5-72B-Instruct",
|
|
787
787
|
},
|
|
788
788
|
]);
|
|
789
789
|
this.config.providers.huggingface = answers;
|
|
@@ -92,26 +92,34 @@ export const handleHuggingFaceSetup = async (argv) => {
|
|
|
92
92
|
type: "select",
|
|
93
93
|
name: "modelChoice",
|
|
94
94
|
message: "Select a Hugging Face model:",
|
|
95
|
+
// Router-served ids only. The previous five options
|
|
96
|
+
// (DialoGPT-large/medium/small, blenderbot-400M-distill) are all
|
|
97
|
+
// absent from the router catalogue and answer 400 on every request,
|
|
98
|
+
// so this wizard wrote a dead model into the user's .env.
|
|
95
99
|
choices: [
|
|
96
100
|
{
|
|
97
|
-
name: "Skip - use default (
|
|
101
|
+
name: "Skip - use default (Qwen/Qwen2.5-72B-Instruct)",
|
|
98
102
|
value: "default",
|
|
99
103
|
},
|
|
100
104
|
{
|
|
101
|
-
name: "
|
|
102
|
-
value: "
|
|
105
|
+
name: "Qwen/Qwen2.5-72B-Instruct (Recommended - tool-capable)",
|
|
106
|
+
value: "Qwen/Qwen2.5-72B-Instruct",
|
|
103
107
|
},
|
|
104
108
|
{
|
|
105
|
-
name: "
|
|
106
|
-
value: "
|
|
109
|
+
name: "meta-llama/Llama-3.1-8B-Instruct (Fastest)",
|
|
110
|
+
value: "meta-llama/Llama-3.1-8B-Instruct",
|
|
107
111
|
},
|
|
108
112
|
{
|
|
109
|
-
name: "
|
|
110
|
-
value: "
|
|
113
|
+
name: "meta-llama/Llama-3.3-70B-Instruct (Stronger reasoning)",
|
|
114
|
+
value: "meta-llama/Llama-3.3-70B-Instruct",
|
|
111
115
|
},
|
|
112
116
|
{
|
|
113
|
-
name: "
|
|
114
|
-
value: "
|
|
117
|
+
name: "deepseek-ai/DeepSeek-V3 (Highest quality)",
|
|
118
|
+
value: "deepseek-ai/DeepSeek-V3",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "Qwen/Qwen2.5-Coder-32B-Instruct (Code-focused)",
|
|
122
|
+
value: "Qwen/Qwen2.5-Coder-32B-Instruct",
|
|
115
123
|
},
|
|
116
124
|
{
|
|
117
125
|
name: "Custom model name",
|
|
@@ -134,7 +142,7 @@ export const handleHuggingFaceSetup = async (argv) => {
|
|
|
134
142
|
return "Model name is required";
|
|
135
143
|
}
|
|
136
144
|
if (!trimmed.includes("/")) {
|
|
137
|
-
return "Model name should include organization (e.g., '
|
|
145
|
+
return "Model name should include organization (e.g., 'Qwen/Qwen2.5-72B-Instruct')";
|
|
138
146
|
}
|
|
139
147
|
return true;
|
|
140
148
|
},
|
|
@@ -173,7 +181,7 @@ export const handleHuggingFaceSetup = async (argv) => {
|
|
|
173
181
|
}
|
|
174
182
|
else {
|
|
175
183
|
logger.always(chalk.gray(' neurolink generate "Tell me a story" --provider huggingface'));
|
|
176
|
-
logger.always(chalk.gray(' neurolink generate "Explain AI" --provider huggingface --model
|
|
184
|
+
logger.always(chalk.gray(' neurolink generate "Explain AI" --provider huggingface --model Qwen/Qwen2.5-72B-Instruct'));
|
|
177
185
|
}
|
|
178
186
|
logger.always(chalk.blue("\nš Resources:"));
|
|
179
187
|
logger.always(chalk.gray(" ⢠Hugging Face Models: https://huggingface.co/models"));
|
|
@@ -51,9 +51,9 @@ export declare const MODEL_NAMES: {
|
|
|
51
51
|
readonly QUALITY: "llama3.1:70b";
|
|
52
52
|
};
|
|
53
53
|
readonly HUGGINGFACE: {
|
|
54
|
-
readonly FAST: "
|
|
55
|
-
readonly BALANCED: "
|
|
56
|
-
readonly QUALITY: "
|
|
54
|
+
readonly FAST: "meta-llama/Llama-3.1-8B-Instruct";
|
|
55
|
+
readonly BALANCED: "Qwen/Qwen2.5-72B-Instruct";
|
|
56
|
+
readonly QUALITY: "deepseek-ai/DeepSeek-V3";
|
|
57
57
|
};
|
|
58
58
|
readonly MISTRAL: {
|
|
59
59
|
readonly FAST: "mistral-small-latest";
|
|
@@ -58,11 +58,13 @@ export const MODEL_NAMES = {
|
|
|
58
58
|
BALANCED: "llama3.1:8b",
|
|
59
59
|
QUALITY: "llama3.1:70b",
|
|
60
60
|
},
|
|
61
|
-
// HuggingFace Models
|
|
61
|
+
// HuggingFace Models ā router-served ids. The previous three
|
|
62
|
+
// (DialoGPT-medium / -large, Llama-2-7b-chat-hf) are absent from the
|
|
63
|
+
// router catalogue and answer 400 on every request.
|
|
62
64
|
HUGGINGFACE: {
|
|
63
|
-
FAST: "
|
|
64
|
-
BALANCED: "
|
|
65
|
-
QUALITY: "
|
|
65
|
+
FAST: "meta-llama/Llama-3.1-8B-Instruct",
|
|
66
|
+
BALANCED: "Qwen/Qwen2.5-72B-Instruct",
|
|
67
|
+
QUALITY: "deepseek-ai/DeepSeek-V3",
|
|
66
68
|
},
|
|
67
69
|
// Mistral Models
|
|
68
70
|
MISTRAL: {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { ProviderModelManifest } from "../../types/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Minimal manifest: huggingface has no MODEL_REGISTRY entries today, so
|
|
4
|
-
* only the provider-wide fallback is known.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* only the provider-wide fallback is known. `functionCalling` is true
|
|
5
|
+
* because the router serves tool-calling models and returns `tool_calls` for
|
|
6
|
+
* them; it previously claimed false, contradicting the wire.
|
|
7
|
+
*
|
|
8
|
+
* Named models can be added here incrementally without touching any
|
|
9
|
+
* consumer ā see Task 5 of the model metadata consolidation plan.
|
|
7
10
|
*/
|
|
8
11
|
export declare const huggingfaceManifest: ProviderModelManifest;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Minimal manifest: huggingface has no MODEL_REGISTRY entries today, so
|
|
3
|
-
* only the provider-wide fallback is known.
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* only the provider-wide fallback is known. `functionCalling` is true
|
|
4
|
+
* because the router serves tool-calling models and returns `tool_calls` for
|
|
5
|
+
* them; it previously claimed false, contradicting the wire.
|
|
6
|
+
*
|
|
7
|
+
* Named models can be added here incrementally without touching any
|
|
8
|
+
* consumer ā see Task 5 of the model metadata consolidation plan.
|
|
6
9
|
*/
|
|
7
10
|
export const huggingfaceManifest = {
|
|
8
11
|
defaultContextWindow: 32000,
|
|
@@ -12,7 +15,7 @@ export const huggingfaceManifest = {
|
|
|
12
15
|
contextWindow: 32000,
|
|
13
16
|
maxOutputTokens: 32000,
|
|
14
17
|
vision: false,
|
|
15
|
-
functionCalling:
|
|
18
|
+
functionCalling: true,
|
|
16
19
|
},
|
|
17
20
|
},
|
|
18
21
|
};
|
|
@@ -19,13 +19,36 @@ export declare class HuggingFaceProvider extends OpenAIChatCompletionsProvider {
|
|
|
19
19
|
protected getDefaultModel(): string;
|
|
20
20
|
protected getFallbackModelName(): string;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* the
|
|
27
|
-
*
|
|
22
|
+
* Tool support is resolved by the base through MODEL_REGISTRY's
|
|
23
|
+
* `modelSupports()` facade, which defaults unknown models to supported.
|
|
24
|
+
*
|
|
25
|
+
* This class used to override that with a 13-entry allowlist of model-name
|
|
26
|
+
* substrings, written for the old per-model Inference API where many
|
|
27
|
+
* endpoints rejected the OpenAI `tools` field. The router replaced that, and
|
|
28
|
+
* the list did not keep up. Measured against the 142 models
|
|
29
|
+
* `GET router.huggingface.co/v1/models` served on 2026-09-13 (the
|
|
30
|
+
* catalogue drifts, so treat the totals as a snapshot; the ratio is the
|
|
31
|
+
* point):
|
|
32
|
+
*
|
|
33
|
+
* allowlist entries matching ANY served model 1 of 13
|
|
34
|
+
* served models the allowlist ADMITS 1 of 142
|
|
35
|
+
* served models the allowlist BLOCKS 141
|
|
36
|
+
*
|
|
37
|
+
* So it suppressed tool calling for 99% of the catalogue, including
|
|
38
|
+
* Qwen/Qwen2.5-72B-Instruct, which the router demonstrably tool-calls. A
|
|
39
|
+
* spread of the blocked models ā GLM-5.3-Flash, gemma-4-31B-it,
|
|
40
|
+
* DeepSeek-V4-Flash ā all accept `tools` with HTTP 200 and return
|
|
41
|
+
* `tool_calls`; none rejected the field.
|
|
42
|
+
*
|
|
43
|
+
* The allowlist's own comment named `microsoft/DialoGPT-medium` ā which
|
|
44
|
+
* `getDefaultModel()`, not `getFallbackModelName()`, used to return ā as a
|
|
45
|
+
* model that rejects `tools`. The router does not serve it under any
|
|
46
|
+
* request shape, so that path was never reachable; the default now points
|
|
47
|
+
* at a served model (see `getDefaultHuggingFaceModel`).
|
|
48
|
+
*
|
|
49
|
+
* A model that genuinely cannot use tools simply does not emit `tool_calls`,
|
|
50
|
+
* which the loop already handles, so the optimistic default costs nothing
|
|
51
|
+
* that the allowlist was protecting.
|
|
28
52
|
*/
|
|
29
|
-
supportsTools(): boolean;
|
|
30
53
|
protected formatProviderError(error: unknown): Error;
|
|
31
54
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HuggingFaceModels } from "../../constants/enums.js";
|
|
1
2
|
import { AuthenticationError, InvalidModelError, ProviderError, RateLimitError, } from "../../types/index.js";
|
|
2
3
|
import { classifyProviderError, DEFAULT_ERROR_RULES, } from "../../utils/errorClassifier.js";
|
|
3
4
|
import { logger } from "../../utils/logger.js";
|
|
@@ -6,7 +7,19 @@ import { createHuggingFaceConfig, getProviderModel, validateApiKey, } from "../.
|
|
|
6
7
|
import { OpenAIChatCompletionsProvider } from "../openaiChatCompletionsBase.js";
|
|
7
8
|
const HUGGINGFACE_DEFAULT_BASE_URL = "https://router.huggingface.co/v1";
|
|
8
9
|
const getHuggingFaceApiKey = () => validateApiKey(createHuggingFaceConfig());
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Must stay the same id `providerRegistry` passes as the registration default
|
|
12
|
+
* (`process.env.HUGGINGFACE_MODEL || HuggingFaceModels.QWEN_2_5_72B_INSTRUCT`),
|
|
13
|
+
* hence the shared constant rather than a second literal.
|
|
14
|
+
*
|
|
15
|
+
* The registry supplies `modelName` on every factory-created provider, so this
|
|
16
|
+
* only decides a directly-constructed `new HuggingFaceProvider()`. It still
|
|
17
|
+
* matters: it previously read `microsoft/DialoGPT-medium`, which the router
|
|
18
|
+
* does not serve under any request shape ā it answers 400 "not supported by
|
|
19
|
+
* any provider you have enabled" with or without `tools` ā and that stale id
|
|
20
|
+
* was what the docs and setup guidance advertised as the default.
|
|
21
|
+
*/
|
|
22
|
+
const getDefaultHuggingFaceModel = () => getProviderModel("HUGGINGFACE_MODEL", HuggingFaceModels.QWEN_2_5_72B_INSTRUCT);
|
|
10
23
|
/**
|
|
11
24
|
* HuggingFace Provider ā direct HTTP, no AI SDK.
|
|
12
25
|
*
|
|
@@ -47,32 +60,37 @@ export class HuggingFaceProvider extends OpenAIChatCompletionsProvider {
|
|
|
47
60
|
return "meta-llama/Llama-3.1-8B-Instruct";
|
|
48
61
|
}
|
|
49
62
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* the
|
|
55
|
-
*
|
|
63
|
+
* Tool support is resolved by the base through MODEL_REGISTRY's
|
|
64
|
+
* `modelSupports()` facade, which defaults unknown models to supported.
|
|
65
|
+
*
|
|
66
|
+
* This class used to override that with a 13-entry allowlist of model-name
|
|
67
|
+
* substrings, written for the old per-model Inference API where many
|
|
68
|
+
* endpoints rejected the OpenAI `tools` field. The router replaced that, and
|
|
69
|
+
* the list did not keep up. Measured against the 142 models
|
|
70
|
+
* `GET router.huggingface.co/v1/models` served on 2026-09-13 (the
|
|
71
|
+
* catalogue drifts, so treat the totals as a snapshot; the ratio is the
|
|
72
|
+
* point):
|
|
73
|
+
*
|
|
74
|
+
* allowlist entries matching ANY served model 1 of 13
|
|
75
|
+
* served models the allowlist ADMITS 1 of 142
|
|
76
|
+
* served models the allowlist BLOCKS 141
|
|
77
|
+
*
|
|
78
|
+
* So it suppressed tool calling for 99% of the catalogue, including
|
|
79
|
+
* Qwen/Qwen2.5-72B-Instruct, which the router demonstrably tool-calls. A
|
|
80
|
+
* spread of the blocked models ā GLM-5.3-Flash, gemma-4-31B-it,
|
|
81
|
+
* DeepSeek-V4-Flash ā all accept `tools` with HTTP 200 and return
|
|
82
|
+
* `tool_calls`; none rejected the field.
|
|
83
|
+
*
|
|
84
|
+
* The allowlist's own comment named `microsoft/DialoGPT-medium` ā which
|
|
85
|
+
* `getDefaultModel()`, not `getFallbackModelName()`, used to return ā as a
|
|
86
|
+
* model that rejects `tools`. The router does not serve it under any
|
|
87
|
+
* request shape, so that path was never reachable; the default now points
|
|
88
|
+
* at a served model (see `getDefaultHuggingFaceModel`).
|
|
89
|
+
*
|
|
90
|
+
* A model that genuinely cannot use tools simply does not emit `tool_calls`,
|
|
91
|
+
* which the loop already handles, so the optimistic default costs nothing
|
|
92
|
+
* that the allowlist was protecting.
|
|
56
93
|
*/
|
|
57
|
-
supportsTools() {
|
|
58
|
-
const modelName = this.modelName.toLowerCase();
|
|
59
|
-
const toolCapableModels = [
|
|
60
|
-
"llama-3.1-8b-instruct",
|
|
61
|
-
"llama-3.1-70b-instruct",
|
|
62
|
-
"llama-3.1-405b-instruct",
|
|
63
|
-
"llama-3.1-nemotron-ultra",
|
|
64
|
-
"hermes-3-llama-3.2",
|
|
65
|
-
"hermes-2-pro",
|
|
66
|
-
"codellama-34b-instruct",
|
|
67
|
-
"codellama-13b-instruct",
|
|
68
|
-
"mistral-7b-instruct-v0.3",
|
|
69
|
-
"mistral-8x7b-instruct",
|
|
70
|
-
"nous-hermes",
|
|
71
|
-
"openchat",
|
|
72
|
-
"wizardcoder",
|
|
73
|
-
];
|
|
74
|
-
return toolCapableModels.some((capable) => modelName.includes(capable));
|
|
75
|
-
}
|
|
76
94
|
formatProviderError(error) {
|
|
77
95
|
const rules = [
|
|
78
96
|
{
|
|
@@ -71,8 +71,8 @@ export function getProviderSetupMessage(provider, missingVars) {
|
|
|
71
71
|
envVars: [
|
|
72
72
|
'HUGGINGFACE_API_KEY="hf_your_huggingface_token"',
|
|
73
73
|
"# Optional:",
|
|
74
|
-
'HUGGINGFACE_MODEL="
|
|
75
|
-
'
|
|
74
|
+
'HUGGINGFACE_MODEL="Qwen/Qwen2.5-72B-Instruct"',
|
|
75
|
+
'HUGGINGFACE_BASE_URL="https://router.huggingface.co/v1"',
|
|
76
76
|
],
|
|
77
77
|
},
|
|
78
78
|
mistral: {
|