@infersec/conduit 1.100.0 → 1.102.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/dist/cli.js +2357 -2230
- package/dist/cli.sea.cjs +2355 -2228
- package/dist/modelManagement/ModelManager.d.ts +1 -0
- package/dist/modelManagement/chatTemplate.d.ts +41 -0
- package/dist/requestHandlers/createConduitOpenAIAPIReferenceHandlers.d.ts +3 -1
- package/dist/utils/openai.d.ts +18 -1
- package/package.json +1 -1
- package/dist/modelManagement/extraArgs.d.ts +0 -1
package/dist/cli.sea.cjs
CHANGED
|
@@ -42,10 +42,10 @@ var require$$1$8 = require('node:async_hooks');
|
|
|
42
42
|
var require$$1$9 = require('node:console');
|
|
43
43
|
var require$$0$m = require('node:fs/promises');
|
|
44
44
|
var require$$2$5 = require('node:timers');
|
|
45
|
-
var node_string_decoder = require('node:string_decoder');
|
|
46
|
-
var promises = require('node:stream/promises');
|
|
47
45
|
require('fs/promises');
|
|
48
46
|
require('stream/promises');
|
|
47
|
+
var node_string_decoder = require('node:string_decoder');
|
|
48
|
+
var promises = require('node:stream/promises');
|
|
49
49
|
var os = require('node:os');
|
|
50
50
|
var tty = require('node:tty');
|
|
51
51
|
var require$$3$9 = require('child_process');
|
|
@@ -4360,35 +4360,6 @@ function ulid$2(seedTime, prng) {
|
|
|
4360
4360
|
return encodeTime(seed, TIME_LEN) + encodeRandom(RANDOM_LEN, currentPRNG);
|
|
4361
4361
|
}
|
|
4362
4362
|
|
|
4363
|
-
function getEffectiveContextLength({ contextLength, engineConfig, engineType }) {
|
|
4364
|
-
if (contextLength === null || contextLength <= 0) {
|
|
4365
|
-
return null;
|
|
4366
|
-
}
|
|
4367
|
-
if (!engineConfig) {
|
|
4368
|
-
return contextLength;
|
|
4369
|
-
}
|
|
4370
|
-
switch (engineType) {
|
|
4371
|
-
case "llama.cpp": {
|
|
4372
|
-
const parallelism = engineConfig.parallelism;
|
|
4373
|
-
if (typeof parallelism === "number" && parallelism > 0) {
|
|
4374
|
-
return contextLength / parallelism;
|
|
4375
|
-
}
|
|
4376
|
-
return contextLength;
|
|
4377
|
-
}
|
|
4378
|
-
case "sglang":
|
|
4379
|
-
case "tensorrt-llm":
|
|
4380
|
-
case "vllm": {
|
|
4381
|
-
const tensorParallelSize = engineConfig.tensorParallelSize;
|
|
4382
|
-
if (typeof tensorParallelSize === "number" && tensorParallelSize > 0) {
|
|
4383
|
-
return contextLength / tensorParallelSize;
|
|
4384
|
-
}
|
|
4385
|
-
return contextLength;
|
|
4386
|
-
}
|
|
4387
|
-
default:
|
|
4388
|
-
return contextLength;
|
|
4389
|
-
}
|
|
4390
|
-
}
|
|
4391
|
-
|
|
4392
4363
|
function asError(error) {
|
|
4393
4364
|
if (error instanceof Error) {
|
|
4394
4365
|
return error;
|
|
@@ -19929,58 +19900,10 @@ const LLMEngineSchema = _enum$1([
|
|
|
19929
19900
|
"tensorrt-llm",
|
|
19930
19901
|
"vllm"
|
|
19931
19902
|
]);
|
|
19932
|
-
const
|
|
19933
|
-
|
|
19934
|
-
|
|
19935
|
-
cacheTypeV: string$2().nullable().optional(),
|
|
19936
|
-
extraArgs: array(string$2()).optional(),
|
|
19937
|
-
flashAttn: boolean$1().optional(),
|
|
19938
|
-
gpuLayers: number$1().int().min(0).optional(),
|
|
19939
|
-
mainGpu: number$1().int().min(0).nullable().optional(),
|
|
19940
|
-
parallelism: number$1().int().positive().optional(),
|
|
19941
|
-
tensorSplit: string$2().nullable().optional(),
|
|
19942
|
-
ubatchSize: number$1().int().positive().nullable().optional()
|
|
19943
|
-
});
|
|
19944
|
-
const VLLMEngineConfigSchema = object$1({
|
|
19945
|
-
device: string$2().optional(),
|
|
19946
|
-
dtype: string$2().optional(),
|
|
19947
|
-
extraArgs: array(string$2()).optional(),
|
|
19948
|
-
tensorParallelSize: number$1().int().positive().optional()
|
|
19949
|
-
});
|
|
19950
|
-
const SGLangEngineConfigSchema = object$1({
|
|
19951
|
-
device: string$2().optional(),
|
|
19952
|
-
dtype: string$2().optional(),
|
|
19953
|
-
extraArgs: array(string$2()).optional(),
|
|
19954
|
-
tensorParallelSize: number$1().int().positive().optional()
|
|
19955
|
-
});
|
|
19956
|
-
const TensorRTLLMEngineConfigSchema = object$1({
|
|
19957
|
-
backend: _enum$1(["_autodeploy", "pytorch", "tensorrt"]).optional(),
|
|
19958
|
-
dtype: string$2().optional(),
|
|
19959
|
-
extraArgs: array(string$2()).optional(),
|
|
19960
|
-
tensorParallelSize: number$1().int().positive().optional()
|
|
19961
|
-
});
|
|
19962
|
-
const Exllamav3EngineConfigSchema = object$1({
|
|
19963
|
-
cacheMode: _enum$1(["fp16", "q4", "q6", "q8"]).optional(),
|
|
19964
|
-
extraArgs: array(string$2()).optional(),
|
|
19965
|
-
gpuSplit: string$2().optional(),
|
|
19966
|
-
maxSeqLen: number$1().int().positive().optional()
|
|
19967
|
-
});
|
|
19968
|
-
const MLXLMEngineConfigSchema = object$1({
|
|
19969
|
-
extraArgs: array(string$2()).optional(),
|
|
19970
|
-
maxKvSize: number$1().int().positive().optional(),
|
|
19971
|
-
trustRemoteCode: boolean$1().optional()
|
|
19903
|
+
const EngineConfigSchema = object$1({
|
|
19904
|
+
extraArgs: array(string$2()),
|
|
19905
|
+
type: LLMEngineSchema
|
|
19972
19906
|
});
|
|
19973
|
-
const EngineConfigSchema = discriminatedUnion("type", [
|
|
19974
|
-
object$1({ config: Exllamav3EngineConfigSchema, type: literal("exllamav3") }),
|
|
19975
|
-
object$1({ config: LlamacppEngineConfigSchema, type: literal("llama.cpp") }),
|
|
19976
|
-
object$1({ config: MLXLMEngineConfigSchema, type: literal("mlx-lm") }),
|
|
19977
|
-
object$1({ config: SGLangEngineConfigSchema, type: literal("sglang") }),
|
|
19978
|
-
object$1({
|
|
19979
|
-
config: TensorRTLLMEngineConfigSchema,
|
|
19980
|
-
type: literal("tensorrt-llm")
|
|
19981
|
-
}),
|
|
19982
|
-
object$1({ config: VLLMEngineConfigSchema, type: literal("vllm") })
|
|
19983
|
-
]);
|
|
19984
19907
|
const LLMModelFormatSchema = _enum$1([
|
|
19985
19908
|
// VLLM / SGLang / TensorRT-LLM
|
|
19986
19909
|
"safetensors",
|
|
@@ -20001,7 +19924,39 @@ object$1({
|
|
|
20001
19924
|
supportsVision: boolean$1()
|
|
20002
19925
|
});
|
|
20003
19926
|
const LLMModelTaskTypeSchema = _enum$1(["text-generation", "embeddings"]);
|
|
19927
|
+
const ReasoningEffortSchema = _enum$1(["none", "minimal", "low", "medium", "high", "xhigh"]);
|
|
19928
|
+
const CHAT_TEMPLATE_DEFAULT_FILE_PATH = "chat_template.jinja";
|
|
19929
|
+
const CHAT_TEMPLATE_LOCAL_FILE_NAME = "infersec-chat-template.jinja";
|
|
19930
|
+
const ChatTemplateOverrideSchema = discriminatedUnion("type", [
|
|
19931
|
+
object$1({
|
|
19932
|
+
filePath: string$2().min(1).default(CHAT_TEMPLATE_DEFAULT_FILE_PATH),
|
|
19933
|
+
repo: string$2().min(1),
|
|
19934
|
+
type: literal("huggingface")
|
|
19935
|
+
}),
|
|
19936
|
+
object$1({
|
|
19937
|
+
content: string$2().min(1),
|
|
19938
|
+
type: literal("inline")
|
|
19939
|
+
})
|
|
19940
|
+
]);
|
|
19941
|
+
const ThinkingConfigSchema = object$1({
|
|
19942
|
+
enabled: boolean$1().optional(),
|
|
19943
|
+
effort: ReasoningEffortSchema.optional()
|
|
19944
|
+
});
|
|
19945
|
+
const ANTHROPIC_THINKING_BUDGET_EFFORT_TIERS = [
|
|
19946
|
+
{ effort: "low", maxBudgetTokens: 2048 },
|
|
19947
|
+
{ effort: "medium", maxBudgetTokens: 8192 },
|
|
19948
|
+
{ effort: "high", maxBudgetTokens: Number.POSITIVE_INFINITY }
|
|
19949
|
+
];
|
|
19950
|
+
function reasoningEffortForAnthropicBudget(budgetTokens) {
|
|
19951
|
+
for (const tier of ANTHROPIC_THINKING_BUDGET_EFFORT_TIERS) {
|
|
19952
|
+
if (budgetTokens <= tier.maxBudgetTokens) {
|
|
19953
|
+
return tier.effort;
|
|
19954
|
+
}
|
|
19955
|
+
}
|
|
19956
|
+
return "high";
|
|
19957
|
+
}
|
|
20004
19958
|
const LLMModelSchema = object$1({
|
|
19959
|
+
chatTemplate: ChatTemplateOverrideSchema.nullable().optional(),
|
|
20005
19960
|
format: LLMModelFormatSchema,
|
|
20006
19961
|
id: string$2().min(1),
|
|
20007
19962
|
multimodalEnabled: boolean$1(),
|
|
@@ -20016,7 +19971,8 @@ const LLMModelSchema = object$1({
|
|
|
20016
19971
|
type: literal("huggingface")
|
|
20017
19972
|
})
|
|
20018
19973
|
]),
|
|
20019
|
-
taskType: LLMModelTaskTypeSchema
|
|
19974
|
+
taskType: LLMModelTaskTypeSchema,
|
|
19975
|
+
thinkingConfig: ThinkingConfigSchema.nullable().optional()
|
|
20020
19976
|
});
|
|
20021
19977
|
object$1({
|
|
20022
19978
|
filePath: string$2().min(1),
|
|
@@ -20135,7 +20091,8 @@ const ConduitStateSchema = z
|
|
|
20135
20091
|
])
|
|
20136
20092
|
.and(z.object({
|
|
20137
20093
|
activeRequestCount: z.number().int().nonnegative().optional(),
|
|
20138
|
-
timestamp: z.string().datetime()
|
|
20094
|
+
timestamp: z.string().datetime(),
|
|
20095
|
+
warnings: z.array(z.string()).optional()
|
|
20139
20096
|
}));
|
|
20140
20097
|
const ConduitState = z.preprocess(value => {
|
|
20141
20098
|
if (value === null) {
|
|
@@ -20674,6 +20631,10 @@ const ChatCompletionMessageSchema = object$1({
|
|
|
20674
20631
|
const ChatCompletionCreateParamsSchema = object$1({
|
|
20675
20632
|
messages: array(ChatCompletionMessageParamSchema),
|
|
20676
20633
|
model: string$2(),
|
|
20634
|
+
chat_template_kwargs: record(string$2(), unknown())
|
|
20635
|
+
.nullable()
|
|
20636
|
+
.optional()
|
|
20637
|
+
.describe("Additional chat template variables passed to the model's chat template at render time (e.g. reasoning_effort)"),
|
|
20677
20638
|
frequency_penalty: number$1().min(-2).max(2).nullable().optional(),
|
|
20678
20639
|
function_call: union([literal("none"), literal("auto"), object$1({ name: string$2() })])
|
|
20679
20640
|
.optional(),
|
|
@@ -20689,6 +20650,9 @@ const ChatCompletionCreateParamsSchema = object$1({
|
|
|
20689
20650
|
max_tokens: number$1().positive().nullable().optional(),
|
|
20690
20651
|
n: number$1().positive().nullable().optional(),
|
|
20691
20652
|
presence_penalty: number$1().min(-2).max(2).nullable().optional(),
|
|
20653
|
+
reasoning_effort: ReasoningEffortSchema.nullable()
|
|
20654
|
+
.optional()
|
|
20655
|
+
.describe("Reasoning effort hint for thinking models. Forwarded to the chat template when one is configured"),
|
|
20692
20656
|
response_format: object$1({
|
|
20693
20657
|
type: _enum$1(["text", "json_object"])
|
|
20694
20658
|
})
|
|
@@ -20970,6 +20934,7 @@ RoutingMethod.FirstAvailable;
|
|
|
20970
20934
|
});
|
|
20971
20935
|
|
|
20972
20936
|
object$1({
|
|
20937
|
+
chatTemplate: ChatTemplateOverrideSchema.nullable().optional(),
|
|
20973
20938
|
format: LLMModelFormatSchema,
|
|
20974
20939
|
multimodalEnabled: boolean$1().optional(),
|
|
20975
20940
|
name: ResourceNameSchema,
|
|
@@ -20979,7 +20944,8 @@ object$1({
|
|
|
20979
20944
|
.refine(value => value.includes("/"), {
|
|
20980
20945
|
message: "Slug must be fully qualified (owner/repo)"
|
|
20981
20946
|
}),
|
|
20982
|
-
taskType: LLMModelTaskTypeSchema.optional()
|
|
20947
|
+
taskType: LLMModelTaskTypeSchema.optional(),
|
|
20948
|
+
thinkingConfig: ThinkingConfigSchema.nullable().optional()
|
|
20983
20949
|
});
|
|
20984
20950
|
object$1({
|
|
20985
20951
|
results: array(object$1({
|
|
@@ -20995,6 +20961,7 @@ object$1({
|
|
|
20995
20961
|
}))
|
|
20996
20962
|
});
|
|
20997
20963
|
object$1({
|
|
20964
|
+
chatTemplate: ChatTemplateOverrideSchema.nullable(),
|
|
20998
20965
|
created: string$2(),
|
|
20999
20966
|
id: ULIDSchema,
|
|
21000
20967
|
modelFormat: LLMModelFormatSchema,
|
|
@@ -21012,12 +20979,15 @@ object$1({
|
|
|
21012
20979
|
updated: string$2()
|
|
21013
20980
|
})),
|
|
21014
20981
|
taskType: LLMModelTaskTypeSchema,
|
|
20982
|
+
thinkingConfig: ThinkingConfigSchema.nullable(),
|
|
21015
20983
|
updated: string$2()
|
|
21016
20984
|
});
|
|
21017
20985
|
object$1({
|
|
20986
|
+
chatTemplate: ChatTemplateOverrideSchema.nullable().optional(),
|
|
21018
20987
|
multimodalEnabled: boolean$1().optional(),
|
|
21019
20988
|
name: ResourceNameSchema.optional(),
|
|
21020
|
-
taskType: LLMModelTaskTypeSchema.optional()
|
|
20989
|
+
taskType: LLMModelTaskTypeSchema.optional(),
|
|
20990
|
+
thinkingConfig: ThinkingConfigSchema.nullable().optional()
|
|
21021
20991
|
});
|
|
21022
20992
|
object$1({
|
|
21023
20993
|
success: literal(true)
|
|
@@ -21129,105 +21099,21 @@ object$1({
|
|
|
21129
21099
|
});
|
|
21130
21100
|
const EngineOutputSchema = object$1({
|
|
21131
21101
|
created: string$2(),
|
|
21132
|
-
|
|
21133
|
-
exllamav3ExtraArgs: array(string$2()),
|
|
21134
|
-
exllamav3GpuSplit: string$2().nullable(),
|
|
21135
|
-
exllamav3MaxSeqLen: number$1().nullable(),
|
|
21102
|
+
extraArgs: array(string$2()),
|
|
21136
21103
|
id: ULIDSchema,
|
|
21137
|
-
llamacppBatchSize: number$1().nullable(),
|
|
21138
|
-
llamacppCacheTypeK: string$2().nullable(),
|
|
21139
|
-
llamacppCacheTypeV: string$2().nullable(),
|
|
21140
|
-
llamacppExtraArgs: array(string$2()),
|
|
21141
|
-
llamacppFlashAttn: boolean$1(),
|
|
21142
|
-
llamacppGpuLayers: number$1(),
|
|
21143
|
-
llamacppMainGpu: number$1().nullable(),
|
|
21144
|
-
llamacppParallelism: number$1(),
|
|
21145
|
-
llamacppTensorSplit: string$2().nullable(),
|
|
21146
|
-
llamacppUbatchSize: number$1().nullable(),
|
|
21147
|
-
mlxlmExtraArgs: array(string$2()),
|
|
21148
|
-
mlxlmMaxKvSize: number$1().nullable(),
|
|
21149
|
-
mlxlmTrustRemoteCode: boolean$1(),
|
|
21150
21104
|
name: string$2(),
|
|
21151
|
-
sglangDevice: string$2().nullable(),
|
|
21152
|
-
sglangDtype: string$2().nullable(),
|
|
21153
|
-
sglangExtraArgs: array(string$2()),
|
|
21154
|
-
sglangTensorParallelSize: number$1(),
|
|
21155
|
-
trtllmBackend: string$2().nullable(),
|
|
21156
|
-
trtllmDtype: string$2().nullable(),
|
|
21157
|
-
trtllmExtraArgs: array(string$2()),
|
|
21158
|
-
trtllmTensorParallelSize: number$1(),
|
|
21159
21105
|
type: LLMEngineSchema,
|
|
21160
|
-
updated: string$2()
|
|
21161
|
-
vllmDevice: string$2().nullable(),
|
|
21162
|
-
vllmDtype: string$2().nullable(),
|
|
21163
|
-
vllmExtraArgs: array(string$2()),
|
|
21164
|
-
vllmTensorParallelSize: number$1()
|
|
21106
|
+
updated: string$2()
|
|
21165
21107
|
});
|
|
21166
21108
|
object$1({
|
|
21167
|
-
|
|
21168
|
-
exllamav3ExtraArgs: array(string$2()).optional(),
|
|
21169
|
-
exllamav3GpuSplit: string$2().nullable().optional(),
|
|
21170
|
-
exllamav3MaxSeqLen: number$1().int().positive().nullable().optional(),
|
|
21171
|
-
llamacppBatchSize: number$1().int().positive().nullable().optional(),
|
|
21172
|
-
llamacppCacheTypeK: string$2().nullable().optional(),
|
|
21173
|
-
llamacppCacheTypeV: string$2().nullable().optional(),
|
|
21174
|
-
llamacppExtraArgs: array(string$2()).optional(),
|
|
21175
|
-
llamacppFlashAttn: boolean$1().optional(),
|
|
21176
|
-
llamacppGpuLayers: number$1().int().min(0).optional(),
|
|
21177
|
-
llamacppMainGpu: number$1().int().min(0).nullable().optional(),
|
|
21178
|
-
llamacppParallelism: number$1().int().positive().optional(),
|
|
21179
|
-
llamacppTensorSplit: string$2().nullable().optional(),
|
|
21180
|
-
llamacppUbatchSize: number$1().int().positive().nullable().optional(),
|
|
21181
|
-
mlxlmExtraArgs: array(string$2()).optional(),
|
|
21182
|
-
mlxlmMaxKvSize: number$1().int().positive().nullable().optional(),
|
|
21183
|
-
mlxlmTrustRemoteCode: boolean$1().optional(),
|
|
21109
|
+
extraArgs: array(string$2()).optional(),
|
|
21184
21110
|
name: ResourceNameSchema,
|
|
21185
|
-
|
|
21186
|
-
sglangDtype: string$2().nullable().optional(),
|
|
21187
|
-
sglangExtraArgs: array(string$2()).optional(),
|
|
21188
|
-
sglangTensorParallelSize: number$1().int().positive().optional(),
|
|
21189
|
-
trtllmBackend: string$2().nullable().optional(),
|
|
21190
|
-
trtllmDtype: string$2().nullable().optional(),
|
|
21191
|
-
trtllmExtraArgs: array(string$2()).optional(),
|
|
21192
|
-
trtllmTensorParallelSize: number$1().int().positive().optional(),
|
|
21193
|
-
type: LLMEngineSchema,
|
|
21194
|
-
vllmDevice: string$2().nullable().optional(),
|
|
21195
|
-
vllmDtype: string$2().nullable().optional(),
|
|
21196
|
-
vllmExtraArgs: array(string$2()).optional(),
|
|
21197
|
-
vllmTensorParallelSize: number$1().int().positive().optional()
|
|
21111
|
+
type: LLMEngineSchema
|
|
21198
21112
|
});
|
|
21199
21113
|
object$1({
|
|
21200
|
-
|
|
21201
|
-
exllamav3ExtraArgs: array(string$2()).optional(),
|
|
21202
|
-
exllamav3GpuSplit: string$2().nullable().optional(),
|
|
21203
|
-
exllamav3MaxSeqLen: number$1().int().positive().nullable().optional(),
|
|
21204
|
-
llamacppBatchSize: number$1().int().positive().nullable().optional(),
|
|
21205
|
-
llamacppCacheTypeK: string$2().nullable().optional(),
|
|
21206
|
-
llamacppCacheTypeV: string$2().nullable().optional(),
|
|
21207
|
-
llamacppExtraArgs: array(string$2()).optional(),
|
|
21208
|
-
llamacppFlashAttn: boolean$1().optional(),
|
|
21209
|
-
llamacppGpuLayers: number$1().int().min(0).optional(),
|
|
21210
|
-
llamacppMainGpu: number$1().int().min(0).nullable().optional(),
|
|
21211
|
-
llamacppParallelism: number$1().int().positive().optional(),
|
|
21212
|
-
llamacppTensorSplit: string$2().nullable().optional(),
|
|
21213
|
-
llamacppUbatchSize: number$1().int().positive().nullable().optional(),
|
|
21214
|
-
mlxlmExtraArgs: array(string$2()).optional(),
|
|
21215
|
-
mlxlmMaxKvSize: number$1().int().positive().nullable().optional(),
|
|
21216
|
-
mlxlmTrustRemoteCode: boolean$1().optional(),
|
|
21114
|
+
extraArgs: array(string$2()).optional(),
|
|
21217
21115
|
name: ResourceNameSchema.optional(),
|
|
21218
|
-
|
|
21219
|
-
sglangDtype: string$2().nullable().optional(),
|
|
21220
|
-
sglangExtraArgs: array(string$2()).optional(),
|
|
21221
|
-
sglangTensorParallelSize: number$1().int().positive().optional(),
|
|
21222
|
-
trtllmBackend: string$2().nullable().optional(),
|
|
21223
|
-
trtllmDtype: string$2().nullable().optional(),
|
|
21224
|
-
trtllmExtraArgs: array(string$2()).optional(),
|
|
21225
|
-
trtllmTensorParallelSize: number$1().int().positive().optional(),
|
|
21226
|
-
type: LLMEngineSchema.optional(),
|
|
21227
|
-
vllmDevice: string$2().nullable().optional(),
|
|
21228
|
-
vllmDtype: string$2().nullable().optional(),
|
|
21229
|
-
vllmExtraArgs: array(string$2()).optional(),
|
|
21230
|
-
vllmTensorParallelSize: number$1().int().positive().optional()
|
|
21116
|
+
type: LLMEngineSchema.optional()
|
|
21231
21117
|
});
|
|
21232
21118
|
object$1({
|
|
21233
21119
|
results: array(EngineOutputSchema)
|
|
@@ -21304,6 +21190,12 @@ object$1({
|
|
|
21304
21190
|
}
|
|
21305
21191
|
});
|
|
21306
21192
|
|
|
21193
|
+
object$1({
|
|
21194
|
+
config: EngineConfigSchema,
|
|
21195
|
+
description: string$2().optional(),
|
|
21196
|
+
name: ResourceNameSchema
|
|
21197
|
+
});
|
|
21198
|
+
|
|
21307
21199
|
const ENGINE_API_COMPATIBILITY = {
|
|
21308
21200
|
exllamav3: {
|
|
21309
21201
|
nativeAnthropicMessages: false,
|
|
@@ -21722,6 +21614,105 @@ discriminatedUnion("chargeName", [
|
|
|
21722
21614
|
ToolServiceCallMetaSchema
|
|
21723
21615
|
]);
|
|
21724
21616
|
|
|
21617
|
+
function parseExtraArgs(extraArgs) {
|
|
21618
|
+
if (!Array.isArray(extraArgs) ||
|
|
21619
|
+
!extraArgs.every((value) => typeof value === "string")) {
|
|
21620
|
+
return [];
|
|
21621
|
+
}
|
|
21622
|
+
return extraArgs.flatMap(tokenizeShellLine);
|
|
21623
|
+
}
|
|
21624
|
+
function findArgValue(args, flag) {
|
|
21625
|
+
let found = null;
|
|
21626
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
21627
|
+
const token = args[index];
|
|
21628
|
+
if (token === flag) {
|
|
21629
|
+
const value = args[index + 1];
|
|
21630
|
+
if (value !== undefined && !value.startsWith("--")) {
|
|
21631
|
+
found = value;
|
|
21632
|
+
}
|
|
21633
|
+
else {
|
|
21634
|
+
found = null;
|
|
21635
|
+
}
|
|
21636
|
+
}
|
|
21637
|
+
else if (token.startsWith(`${flag}=`)) {
|
|
21638
|
+
found = token.slice(flag.length + 1);
|
|
21639
|
+
}
|
|
21640
|
+
}
|
|
21641
|
+
return found;
|
|
21642
|
+
}
|
|
21643
|
+
function tokenizeShellLine(input) {
|
|
21644
|
+
const tokens = [];
|
|
21645
|
+
let buffer = "";
|
|
21646
|
+
let inQuote = null;
|
|
21647
|
+
let hasBuffer = false;
|
|
21648
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
21649
|
+
const char = input[index];
|
|
21650
|
+
if (inQuote) {
|
|
21651
|
+
if (char === inQuote) {
|
|
21652
|
+
inQuote = null;
|
|
21653
|
+
}
|
|
21654
|
+
else {
|
|
21655
|
+
buffer += char;
|
|
21656
|
+
}
|
|
21657
|
+
hasBuffer = true;
|
|
21658
|
+
}
|
|
21659
|
+
else if (char === '"' || char === "'") {
|
|
21660
|
+
inQuote = char;
|
|
21661
|
+
hasBuffer = true;
|
|
21662
|
+
}
|
|
21663
|
+
else if (char === " " || char === "\t") {
|
|
21664
|
+
if (hasBuffer) {
|
|
21665
|
+
tokens.push(buffer);
|
|
21666
|
+
buffer = "";
|
|
21667
|
+
hasBuffer = false;
|
|
21668
|
+
}
|
|
21669
|
+
}
|
|
21670
|
+
else {
|
|
21671
|
+
buffer += char;
|
|
21672
|
+
hasBuffer = true;
|
|
21673
|
+
}
|
|
21674
|
+
}
|
|
21675
|
+
if (hasBuffer) {
|
|
21676
|
+
tokens.push(buffer);
|
|
21677
|
+
}
|
|
21678
|
+
return tokens;
|
|
21679
|
+
}
|
|
21680
|
+
|
|
21681
|
+
function getEffectiveContextLength({ contextLength, engineConfig, engineType }) {
|
|
21682
|
+
if (contextLength === null || contextLength <= 0) {
|
|
21683
|
+
return null;
|
|
21684
|
+
}
|
|
21685
|
+
if (!engineConfig) {
|
|
21686
|
+
return contextLength;
|
|
21687
|
+
}
|
|
21688
|
+
let divisorFlag = null;
|
|
21689
|
+
switch (engineType) {
|
|
21690
|
+
case "llama.cpp":
|
|
21691
|
+
divisorFlag = "--parallel";
|
|
21692
|
+
break;
|
|
21693
|
+
case "sglang":
|
|
21694
|
+
case "tensorrt-llm":
|
|
21695
|
+
divisorFlag = "--tp-size";
|
|
21696
|
+
break;
|
|
21697
|
+
case "vllm":
|
|
21698
|
+
divisorFlag = "--tensor-parallel-size";
|
|
21699
|
+
break;
|
|
21700
|
+
}
|
|
21701
|
+
if (!divisorFlag) {
|
|
21702
|
+
return contextLength;
|
|
21703
|
+
}
|
|
21704
|
+
const tokens = parseExtraArgs(engineConfig.extraArgs);
|
|
21705
|
+
const rawValue = findArgValue(tokens, divisorFlag);
|
|
21706
|
+
if (rawValue === null) {
|
|
21707
|
+
return contextLength;
|
|
21708
|
+
}
|
|
21709
|
+
const divisor = Number(rawValue);
|
|
21710
|
+
if (Number.isSafeInteger(divisor) && divisor > 0) {
|
|
21711
|
+
return contextLength / divisor;
|
|
21712
|
+
}
|
|
21713
|
+
return contextLength;
|
|
21714
|
+
}
|
|
21715
|
+
|
|
21725
21716
|
const ENV_BOOL_TRUE = ["true", "1", "yes"];
|
|
21726
21717
|
const ENV_BOOL_FALSE = ["false", "0", "no"];
|
|
21727
21718
|
function readEnvBoolean(name) {
|
|
@@ -22205,41 +22196,6 @@ class ProcessManager extends EventEmitter {
|
|
|
22205
22196
|
}
|
|
22206
22197
|
}
|
|
22207
22198
|
|
|
22208
|
-
function watchStreamProgress(emitIntervalBytes) {
|
|
22209
|
-
let bytesProcessed = 0;
|
|
22210
|
-
let lastEmittedAt = 0;
|
|
22211
|
-
const emitter = new EventEmitter();
|
|
22212
|
-
const stream = new require$$0$8.Transform({
|
|
22213
|
-
transform(chunk, _encoding, callback) {
|
|
22214
|
-
bytesProcessed += chunk.length;
|
|
22215
|
-
// Emit progress updates at intervals
|
|
22216
|
-
if (bytesProcessed - lastEmittedAt >= emitIntervalBytes) {
|
|
22217
|
-
emitter.emit("progress", bytesProcessed);
|
|
22218
|
-
lastEmittedAt = bytesProcessed;
|
|
22219
|
-
}
|
|
22220
|
-
// Pass chunk through unchanged
|
|
22221
|
-
callback(null, chunk);
|
|
22222
|
-
},
|
|
22223
|
-
flush(callback) {
|
|
22224
|
-
emitter.emit("progress", bytesProcessed);
|
|
22225
|
-
callback();
|
|
22226
|
-
}
|
|
22227
|
-
});
|
|
22228
|
-
stream.progress = emitter;
|
|
22229
|
-
return stream;
|
|
22230
|
-
}
|
|
22231
|
-
|
|
22232
|
-
function joinURL(...parts) {
|
|
22233
|
-
return parts
|
|
22234
|
-
.join("/")
|
|
22235
|
-
.replace(/[\/]+/g, "/")
|
|
22236
|
-
.replace(/^(.+):\//, "$1://")
|
|
22237
|
-
.replace(/^file:/, "file:/")
|
|
22238
|
-
.replace(/\/(\?|&|#[^!])/g, "$1")
|
|
22239
|
-
.replace(/\?/g, "&")
|
|
22240
|
-
.replace("&", "?");
|
|
22241
|
-
}
|
|
22242
|
-
|
|
22243
22199
|
function isTerminatedError(error) {
|
|
22244
22200
|
return error instanceof Error && error.message === "terminated" && error.name === "TypeError";
|
|
22245
22201
|
}
|
|
@@ -22323,6 +22279,41 @@ function parseSSEEvent(rawEvent) {
|
|
|
22323
22279
|
};
|
|
22324
22280
|
}
|
|
22325
22281
|
|
|
22282
|
+
function watchStreamProgress(emitIntervalBytes) {
|
|
22283
|
+
let bytesProcessed = 0;
|
|
22284
|
+
let lastEmittedAt = 0;
|
|
22285
|
+
const emitter = new EventEmitter();
|
|
22286
|
+
const stream = new require$$0$8.Transform({
|
|
22287
|
+
transform(chunk, _encoding, callback) {
|
|
22288
|
+
bytesProcessed += chunk.length;
|
|
22289
|
+
// Emit progress updates at intervals
|
|
22290
|
+
if (bytesProcessed - lastEmittedAt >= emitIntervalBytes) {
|
|
22291
|
+
emitter.emit("progress", bytesProcessed);
|
|
22292
|
+
lastEmittedAt = bytesProcessed;
|
|
22293
|
+
}
|
|
22294
|
+
// Pass chunk through unchanged
|
|
22295
|
+
callback(null, chunk);
|
|
22296
|
+
},
|
|
22297
|
+
flush(callback) {
|
|
22298
|
+
emitter.emit("progress", bytesProcessed);
|
|
22299
|
+
callback();
|
|
22300
|
+
}
|
|
22301
|
+
});
|
|
22302
|
+
stream.progress = emitter;
|
|
22303
|
+
return stream;
|
|
22304
|
+
}
|
|
22305
|
+
|
|
22306
|
+
function joinURL(...parts) {
|
|
22307
|
+
return parts
|
|
22308
|
+
.join("/")
|
|
22309
|
+
.replace(/[\/]+/g, "/")
|
|
22310
|
+
.replace(/^(.+):\//, "$1://")
|
|
22311
|
+
.replace(/^file:/, "file:/")
|
|
22312
|
+
.replace(/\/(\?|&|#[^!])/g, "$1")
|
|
22313
|
+
.replace(/\?/g, "&")
|
|
22314
|
+
.replace("&", "?");
|
|
22315
|
+
}
|
|
22316
|
+
|
|
22326
22317
|
function buildConfigurationOverrides(options) {
|
|
22327
22318
|
const configurationOverrides = {};
|
|
22328
22319
|
if (options.apiUrl) {
|
|
@@ -112947,458 +112938,1618 @@ var createRouter = /*@__PURE__*/getDefaultExportFromCjs(expressPromiseRouterExpo
|
|
|
112947
112938
|
|
|
112948
112939
|
const SERVED_MODEL_NAME = "default";
|
|
112949
112940
|
|
|
112950
|
-
|
|
112951
|
-
"api-key",
|
|
112952
|
-
"auth-token",
|
|
112953
|
-
"hf-token",
|
|
112954
|
-
"key",
|
|
112955
|
-
"password",
|
|
112956
|
-
"secret",
|
|
112957
|
-
"token"
|
|
112958
|
-
]);
|
|
112959
|
-
function redactSecretArgs(args) {
|
|
112960
|
-
return args.map((arg, index) => {
|
|
112961
|
-
const equalsIndex = arg.indexOf("=");
|
|
112962
|
-
if (arg.startsWith("--") && equalsIndex > 0) {
|
|
112963
|
-
const flag = arg.slice(2, equalsIndex);
|
|
112964
|
-
if (SECRET_FLAGS.has(flag)) {
|
|
112965
|
-
return `${arg.slice(0, equalsIndex + 1)}***`;
|
|
112966
|
-
}
|
|
112967
|
-
}
|
|
112968
|
-
const previous = args[index - 1];
|
|
112969
|
-
if (previous &&
|
|
112970
|
-
previous.startsWith("--") &&
|
|
112971
|
-
!previous.includes("=") &&
|
|
112972
|
-
SECRET_FLAGS.has(previous.slice(2))) {
|
|
112973
|
-
return "***";
|
|
112974
|
-
}
|
|
112975
|
-
return arg;
|
|
112976
|
-
});
|
|
112977
|
-
}
|
|
112978
|
-
async function createEngineProcess({ args, bin, logger }) {
|
|
112979
|
-
logger.info("Starting engine process", {
|
|
112980
|
-
command: { args: redactSecretArgs(args), bin }
|
|
112981
|
-
});
|
|
112982
|
-
const processManager = new ProcessManager({ args, command: bin });
|
|
112983
|
-
await processManager.start();
|
|
112984
|
-
return processManager;
|
|
112985
|
-
}
|
|
112941
|
+
// src/lib/cache-management.ts
|
|
112986
112942
|
|
|
112987
|
-
|
|
112988
|
-
|
|
112989
|
-
|
|
112990
|
-
|
|
112943
|
+
// src/consts.ts
|
|
112944
|
+
var HUB_URL = "https://huggingface.co";
|
|
112945
|
+
|
|
112946
|
+
// src/error.ts
|
|
112947
|
+
async function createApiError(response, opts) {
|
|
112948
|
+
const error = new HubApiError(response.url, response.status, response.headers.get("X-Request-Id") ?? opts?.requestId);
|
|
112949
|
+
error.message = `Api error with status ${error.statusCode}${""}`;
|
|
112950
|
+
const trailer = [`URL: ${error.url}`, error.requestId ? `Request ID: ${error.requestId}` : void 0].filter(Boolean).join(". ");
|
|
112951
|
+
if (response.headers.get("Content-Type")?.startsWith("application/json")) {
|
|
112952
|
+
const json = await response.json();
|
|
112953
|
+
error.message = json.error || json.message || error.message;
|
|
112954
|
+
if (json.error_description) {
|
|
112955
|
+
error.message = error.message ? error.message + `: ${json.error_description}` : json.error_description;
|
|
112991
112956
|
}
|
|
112992
|
-
|
|
112957
|
+
error.data = json;
|
|
112958
|
+
} else {
|
|
112959
|
+
error.data = { message: await response.text() };
|
|
112960
|
+
}
|
|
112961
|
+
error.message += `. ${trailer}`;
|
|
112962
|
+
throw error;
|
|
112993
112963
|
}
|
|
112994
|
-
|
|
112995
|
-
|
|
112996
|
-
|
|
112997
|
-
|
|
112998
|
-
|
|
112999
|
-
|
|
113000
|
-
|
|
113001
|
-
|
|
113002
|
-
|
|
113003
|
-
|
|
113004
|
-
|
|
113005
|
-
|
|
113006
|
-
|
|
113007
|
-
|
|
113008
|
-
|
|
113009
|
-
|
|
113010
|
-
|
|
113011
|
-
|
|
113012
|
-
|
|
113013
|
-
|
|
113014
|
-
|
|
113015
|
-
|
|
113016
|
-
|
|
113017
|
-
|
|
113018
|
-
|
|
113019
|
-
|
|
113020
|
-
|
|
113021
|
-
|
|
113022
|
-
|
|
113023
|
-
|
|
113024
|
-
|
|
112964
|
+
var HubApiError = class extends Error {
|
|
112965
|
+
statusCode;
|
|
112966
|
+
url;
|
|
112967
|
+
requestId;
|
|
112968
|
+
data;
|
|
112969
|
+
constructor(url, statusCode, requestId, message) {
|
|
112970
|
+
super(message);
|
|
112971
|
+
this.statusCode = statusCode;
|
|
112972
|
+
this.requestId = requestId;
|
|
112973
|
+
this.url = url;
|
|
112974
|
+
}
|
|
112975
|
+
};
|
|
112976
|
+
var InvalidApiResponseFormatError = class extends Error {
|
|
112977
|
+
};
|
|
112978
|
+
|
|
112979
|
+
// src/utils/checkCredentials.ts
|
|
112980
|
+
function checkAccessToken(accessToken) {
|
|
112981
|
+
if (!accessToken.startsWith("hf_")) {
|
|
112982
|
+
throw new TypeError("Your access token must start with 'hf_'");
|
|
112983
|
+
}
|
|
112984
|
+
}
|
|
112985
|
+
function checkCredentials(params) {
|
|
112986
|
+
if (params.accessToken) {
|
|
112987
|
+
checkAccessToken(params.accessToken);
|
|
112988
|
+
return params.accessToken;
|
|
112989
|
+
}
|
|
112990
|
+
if (params.credentials?.accessToken) {
|
|
112991
|
+
checkAccessToken(params.credentials.accessToken);
|
|
112992
|
+
return params.credentials.accessToken;
|
|
112993
|
+
}
|
|
112994
|
+
}
|
|
112995
|
+
|
|
112996
|
+
// src/utils/toRepoId.ts
|
|
112997
|
+
function toRepoId(repo) {
|
|
112998
|
+
if (typeof repo !== "string") {
|
|
112999
|
+
return repo;
|
|
113000
|
+
}
|
|
113001
|
+
if (repo.startsWith("model/") || repo.startsWith("models/")) {
|
|
113002
|
+
throw new TypeError(
|
|
113003
|
+
"A repo designation for a model should not start with 'models/', directly specify the model namespace / name"
|
|
113004
|
+
);
|
|
113005
|
+
}
|
|
113006
|
+
if (repo.startsWith("space/")) {
|
|
113007
|
+
throw new TypeError("Spaces should start with 'spaces/', plural, not 'space/'");
|
|
113008
|
+
}
|
|
113009
|
+
if (repo.startsWith("dataset/")) {
|
|
113010
|
+
throw new TypeError("Datasets should start with 'dataset/', plural, not 'dataset/'");
|
|
113011
|
+
}
|
|
113012
|
+
const slashes = repo.split("/").length - 1;
|
|
113013
|
+
if (repo.startsWith("spaces/")) {
|
|
113014
|
+
if (slashes !== 2) {
|
|
113015
|
+
throw new TypeError("Space Id must include namespace and name of the space");
|
|
113025
113016
|
}
|
|
113026
|
-
|
|
113027
|
-
|
|
113017
|
+
return {
|
|
113018
|
+
type: "space",
|
|
113019
|
+
name: repo.slice("spaces/".length)
|
|
113020
|
+
};
|
|
113021
|
+
}
|
|
113022
|
+
if (repo.startsWith("datasets/")) {
|
|
113023
|
+
if (slashes > 2) {
|
|
113024
|
+
throw new TypeError("Too many slashes in repo designation: " + repo);
|
|
113028
113025
|
}
|
|
113029
|
-
return
|
|
113026
|
+
return {
|
|
113027
|
+
type: "dataset",
|
|
113028
|
+
name: repo.slice("datasets/".length)
|
|
113029
|
+
};
|
|
113030
|
+
}
|
|
113031
|
+
if (slashes > 1) {
|
|
113032
|
+
throw new TypeError("Too many slashes in repo designation: " + repo);
|
|
113033
|
+
}
|
|
113034
|
+
return {
|
|
113035
|
+
type: "model",
|
|
113036
|
+
name: repo
|
|
113037
|
+
};
|
|
113030
113038
|
}
|
|
113039
|
+
new Promise((r) => {
|
|
113040
|
+
});
|
|
113031
113041
|
|
|
113032
|
-
|
|
113033
|
-
|
|
113034
|
-
|
|
113035
|
-
|
|
113036
|
-
|
|
113037
|
-
|
|
113038
|
-
|
|
113039
|
-
|
|
113040
|
-
|
|
113041
|
-
|
|
113042
|
-
|
|
113043
|
-
|
|
113044
|
-
|
|
113045
|
-
|
|
113046
|
-
|
|
113042
|
+
// src/utils/combineUint8Arrays.ts
|
|
113043
|
+
function combineUint8Arrays(a, b) {
|
|
113044
|
+
const aLength = a.length;
|
|
113045
|
+
const combinedBytes = new Uint8Array(aLength + b.length);
|
|
113046
|
+
combinedBytes.set(a);
|
|
113047
|
+
combinedBytes.set(b, aLength);
|
|
113048
|
+
return combinedBytes;
|
|
113049
|
+
}
|
|
113050
|
+
function readU64(b, n) {
|
|
113051
|
+
let x = 0;
|
|
113052
|
+
x |= b[n++] << 0;
|
|
113053
|
+
x |= b[n++] << 8;
|
|
113054
|
+
x |= b[n++] << 16;
|
|
113055
|
+
x |= b[n++] << 24;
|
|
113056
|
+
x |= b[n++] << 32;
|
|
113057
|
+
x |= b[n++] << 40;
|
|
113058
|
+
x |= b[n++] << 48;
|
|
113059
|
+
x |= b[n++] << 56;
|
|
113060
|
+
return x;
|
|
113061
|
+
}
|
|
113062
|
+
function readU32(b, n) {
|
|
113063
|
+
let x = 0;
|
|
113064
|
+
x |= b[n++] << 0;
|
|
113065
|
+
x |= b[n++] << 8;
|
|
113066
|
+
x |= b[n++] << 16;
|
|
113067
|
+
x |= b[n++] << 24;
|
|
113068
|
+
return x;
|
|
113069
|
+
}
|
|
113070
|
+
|
|
113071
|
+
// src/vendor/lz4js/index.ts
|
|
113072
|
+
var minMatch = 4;
|
|
113073
|
+
var hashSize = 1 << 16;
|
|
113074
|
+
makeHashTable();
|
|
113075
|
+
var magicNum = 407708164;
|
|
113076
|
+
var fdContentChksum = 4;
|
|
113077
|
+
var fdContentSize = 8;
|
|
113078
|
+
var fdBlockChksum = 16;
|
|
113079
|
+
var fdVersion = 64;
|
|
113080
|
+
var fdVersionMask = 192;
|
|
113081
|
+
var bsUncompressed = 2147483648;
|
|
113082
|
+
var bsShift = 4;
|
|
113083
|
+
var bsMask = 7;
|
|
113084
|
+
var bsMap = {
|
|
113085
|
+
4: 65536,
|
|
113086
|
+
5: 262144,
|
|
113087
|
+
6: 1048576,
|
|
113088
|
+
7: 4194304
|
|
113047
113089
|
};
|
|
113048
|
-
|
|
113049
|
-
|
|
113050
|
-
|
|
113051
|
-
|
|
113052
|
-
|
|
113053
|
-
|
|
113054
|
-
|
|
113055
|
-
return [ai, bi];
|
|
113056
|
-
}
|
|
113057
|
-
begs = [];
|
|
113058
|
-
left = str.length;
|
|
113059
|
-
while (i >= 0 && !result) {
|
|
113060
|
-
if (i === ai) {
|
|
113061
|
-
begs.push(i);
|
|
113062
|
-
ai = str.indexOf(a, i + 1);
|
|
113063
|
-
}
|
|
113064
|
-
else if (begs.length === 1) {
|
|
113065
|
-
const r = begs.pop();
|
|
113066
|
-
if (r !== undefined)
|
|
113067
|
-
result = [r, bi];
|
|
113068
|
-
}
|
|
113069
|
-
else {
|
|
113070
|
-
beg = begs.pop();
|
|
113071
|
-
if (beg !== undefined && beg < left) {
|
|
113072
|
-
left = beg;
|
|
113073
|
-
right = bi;
|
|
113074
|
-
}
|
|
113075
|
-
bi = str.indexOf(b, i + 1);
|
|
113076
|
-
}
|
|
113077
|
-
i = ai < bi && ai >= 0 ? ai : bi;
|
|
113078
|
-
}
|
|
113079
|
-
if (begs.length && right !== undefined) {
|
|
113080
|
-
result = [left, right];
|
|
113081
|
-
}
|
|
113090
|
+
function makeHashTable() {
|
|
113091
|
+
try {
|
|
113092
|
+
return new Uint32Array(hashSize);
|
|
113093
|
+
} catch (error) {
|
|
113094
|
+
const hashTable2 = new Array(hashSize);
|
|
113095
|
+
for (let i = 0; i < hashSize; i++) {
|
|
113096
|
+
hashTable2[i] = 0;
|
|
113082
113097
|
}
|
|
113083
|
-
return
|
|
113084
|
-
}
|
|
113085
|
-
|
|
113086
|
-
const escSlash = '\0SLASH' + Math.random() + '\0';
|
|
113087
|
-
const escOpen = '\0OPEN' + Math.random() + '\0';
|
|
113088
|
-
const escClose = '\0CLOSE' + Math.random() + '\0';
|
|
113089
|
-
const escComma = '\0COMMA' + Math.random() + '\0';
|
|
113090
|
-
const escPeriod = '\0PERIOD' + Math.random() + '\0';
|
|
113091
|
-
const escSlashPattern = new RegExp(escSlash, 'g');
|
|
113092
|
-
const escOpenPattern = new RegExp(escOpen, 'g');
|
|
113093
|
-
const escClosePattern = new RegExp(escClose, 'g');
|
|
113094
|
-
const escCommaPattern = new RegExp(escComma, 'g');
|
|
113095
|
-
const escPeriodPattern = new RegExp(escPeriod, 'g');
|
|
113096
|
-
const slashPattern = /\\\\/g;
|
|
113097
|
-
const openPattern = /\\{/g;
|
|
113098
|
-
const closePattern = /\\}/g;
|
|
113099
|
-
const commaPattern = /\\,/g;
|
|
113100
|
-
const periodPattern = /\\\./g;
|
|
113101
|
-
const EXPANSION_MAX = 100_000;
|
|
113102
|
-
// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
|
|
113103
|
-
// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
|
|
113104
|
-
// truncated to 100k results - while making every result ~1500 characters
|
|
113105
|
-
// long. The result set, and the intermediate arrays built while combining
|
|
113106
|
-
// brace sets, then grow large enough to exhaust memory and crash the process
|
|
113107
|
-
// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
|
|
113108
|
-
// characters the accumulator may hold at any point, so memory stays flat no
|
|
113109
|
-
// matter how many brace groups are chained. The limit sits well above any
|
|
113110
|
-
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
|
113111
|
-
// characters) so legitimate input is unaffected.
|
|
113112
|
-
const EXPANSION_MAX_LENGTH = 4_000_000;
|
|
113113
|
-
function numeric(str) {
|
|
113114
|
-
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
113098
|
+
return hashTable2;
|
|
113099
|
+
}
|
|
113115
113100
|
}
|
|
113116
|
-
function
|
|
113117
|
-
|
|
113118
|
-
.replace(slashPattern, escSlash)
|
|
113119
|
-
.replace(openPattern, escOpen)
|
|
113120
|
-
.replace(closePattern, escClose)
|
|
113121
|
-
.replace(commaPattern, escComma)
|
|
113122
|
-
.replace(periodPattern, escPeriod);
|
|
113101
|
+
function makeBuffer(size) {
|
|
113102
|
+
return new Uint8Array(size);
|
|
113123
113103
|
}
|
|
113124
|
-
function
|
|
113125
|
-
|
|
113126
|
-
.replace(escSlashPattern, '\\')
|
|
113127
|
-
.replace(escOpenPattern, '{')
|
|
113128
|
-
.replace(escClosePattern, '}')
|
|
113129
|
-
.replace(escCommaPattern, ',')
|
|
113130
|
-
.replace(escPeriodPattern, '.');
|
|
113104
|
+
function sliceArray(array, start, end) {
|
|
113105
|
+
return array.slice(start, end);
|
|
113131
113106
|
}
|
|
113132
|
-
|
|
113133
|
-
|
|
113134
|
-
|
|
113135
|
-
|
|
113136
|
-
|
|
113137
|
-
|
|
113138
|
-
|
|
113139
|
-
|
|
113107
|
+
function decompressBound(src) {
|
|
113108
|
+
let sIndex = 0;
|
|
113109
|
+
if (readU32(src, sIndex) !== magicNum) {
|
|
113110
|
+
throw new Error("invalid magic number");
|
|
113111
|
+
}
|
|
113112
|
+
sIndex += 4;
|
|
113113
|
+
const descriptor = src[sIndex++];
|
|
113114
|
+
if ((descriptor & fdVersionMask) !== fdVersion) {
|
|
113115
|
+
throw new Error("incompatible descriptor version " + (descriptor & fdVersionMask));
|
|
113116
|
+
}
|
|
113117
|
+
const useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
113118
|
+
const useContentSize = (descriptor & fdContentSize) !== 0;
|
|
113119
|
+
const bsIdx = src[sIndex++] >> bsShift & bsMask;
|
|
113120
|
+
if (bsMap[bsIdx] === void 0) {
|
|
113121
|
+
throw new Error("invalid block size " + bsIdx);
|
|
113122
|
+
}
|
|
113123
|
+
const maxBlockSize = bsMap[bsIdx];
|
|
113124
|
+
if (useContentSize) {
|
|
113125
|
+
return readU64(src, sIndex);
|
|
113126
|
+
}
|
|
113127
|
+
sIndex++;
|
|
113128
|
+
let maxSize = 0;
|
|
113129
|
+
while (true) {
|
|
113130
|
+
let blockSize = readU32(src, sIndex);
|
|
113131
|
+
sIndex += 4;
|
|
113132
|
+
if (blockSize & bsUncompressed) {
|
|
113133
|
+
blockSize &= ~bsUncompressed;
|
|
113134
|
+
maxSize += blockSize;
|
|
113135
|
+
} else if (blockSize > 0) {
|
|
113136
|
+
maxSize += maxBlockSize;
|
|
113140
113137
|
}
|
|
113141
|
-
|
|
113142
|
-
|
|
113143
|
-
if (!m) {
|
|
113144
|
-
return str.split(',');
|
|
113138
|
+
if (blockSize === 0) {
|
|
113139
|
+
return maxSize;
|
|
113145
113140
|
}
|
|
113146
|
-
|
|
113147
|
-
|
|
113148
|
-
p[p.length - 1] += '{' + body + '}';
|
|
113149
|
-
const postParts = parseCommaParts(post);
|
|
113150
|
-
if (post.length) {
|
|
113151
|
-
p[p.length - 1] += postParts.shift();
|
|
113152
|
-
p.push.apply(p, postParts);
|
|
113141
|
+
if (useBlockSum) {
|
|
113142
|
+
sIndex += 4;
|
|
113153
113143
|
}
|
|
113154
|
-
|
|
113155
|
-
|
|
113144
|
+
sIndex += blockSize;
|
|
113145
|
+
}
|
|
113156
113146
|
}
|
|
113157
|
-
function
|
|
113158
|
-
|
|
113159
|
-
|
|
113147
|
+
function decompressBlock(src, dst, sIndex, sLength, dIndex) {
|
|
113148
|
+
let mLength, mOffset, sEnd, n, i;
|
|
113149
|
+
const hasCopyWithin = dst.copyWithin !== void 0 && dst.fill !== void 0;
|
|
113150
|
+
sEnd = sIndex + sLength;
|
|
113151
|
+
while (sIndex < sEnd) {
|
|
113152
|
+
const token = src[sIndex++];
|
|
113153
|
+
let literalCount = token >> 4;
|
|
113154
|
+
if (literalCount > 0) {
|
|
113155
|
+
if (literalCount === 15) {
|
|
113156
|
+
while (true) {
|
|
113157
|
+
literalCount += src[sIndex];
|
|
113158
|
+
if (src[sIndex++] !== 255) {
|
|
113159
|
+
break;
|
|
113160
|
+
}
|
|
113161
|
+
}
|
|
113162
|
+
}
|
|
113163
|
+
for (n = sIndex + literalCount; sIndex < n; ) {
|
|
113164
|
+
dst[dIndex++] = src[sIndex++];
|
|
113165
|
+
}
|
|
113160
113166
|
}
|
|
113161
|
-
|
|
113162
|
-
|
|
113163
|
-
// Anything starting with {} will have the first two bytes preserved
|
|
113164
|
-
// but *only* at the top level, so {},a}b will not expand to anything,
|
|
113165
|
-
// but a{},b}c will be expanded to [a}c,abc].
|
|
113166
|
-
// One could argue that this is a bug in Bash, but since the goal of
|
|
113167
|
-
// this module is to match Bash's rules, we escape a leading {}
|
|
113168
|
-
if (str.slice(0, 2) === '{}') {
|
|
113169
|
-
str = '\\{\\}' + str.slice(2);
|
|
113167
|
+
if (sIndex >= sEnd) {
|
|
113168
|
+
break;
|
|
113170
113169
|
}
|
|
113171
|
-
|
|
113172
|
-
|
|
113173
|
-
|
|
113174
|
-
|
|
113175
|
-
|
|
113176
|
-
|
|
113177
|
-
|
|
113178
|
-
}
|
|
113179
|
-
function lte(i, y) {
|
|
113180
|
-
return i <= y;
|
|
113181
|
-
}
|
|
113182
|
-
function gte(i, y) {
|
|
113183
|
-
return i >= y;
|
|
113184
|
-
}
|
|
113185
|
-
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
|
|
113186
|
-
// number of results at `max` and the total number of characters at `maxLength`.
|
|
113187
|
-
// This is the one place output grows, so bounding it here keeps the single
|
|
113188
|
-
// accumulator - and therefore memory - flat regardless of how many brace groups
|
|
113189
|
-
// are combined (CVE-2026-14257).
|
|
113190
|
-
function combine(acc, pre, values, max, maxLength, dropEmpties) {
|
|
113191
|
-
const out = [];
|
|
113192
|
-
let length = 0;
|
|
113193
|
-
for (let a = 0; a < acc.length; a++) {
|
|
113194
|
-
for (let v = 0; v < values.length; v++) {
|
|
113195
|
-
if (out.length >= max)
|
|
113196
|
-
return out;
|
|
113197
|
-
const expansion = acc[a] + pre + values[v];
|
|
113198
|
-
// Bash drops empty results at the top level. Skip them before they count
|
|
113199
|
-
// against `max`, so `max` bounds the number of *kept* results.
|
|
113200
|
-
if (dropEmpties && !expansion)
|
|
113201
|
-
continue;
|
|
113202
|
-
if (length + expansion.length > maxLength)
|
|
113203
|
-
return out;
|
|
113204
|
-
out.push(expansion);
|
|
113205
|
-
length += expansion.length;
|
|
113170
|
+
mLength = token & 15;
|
|
113171
|
+
mOffset = src[sIndex++] | src[sIndex++] << 8;
|
|
113172
|
+
if (mLength === 15) {
|
|
113173
|
+
while (true) {
|
|
113174
|
+
mLength += src[sIndex];
|
|
113175
|
+
if (src[sIndex++] !== 255) {
|
|
113176
|
+
break;
|
|
113206
113177
|
}
|
|
113178
|
+
}
|
|
113207
113179
|
}
|
|
113208
|
-
|
|
113180
|
+
mLength += minMatch;
|
|
113181
|
+
if (hasCopyWithin && mOffset === 1) {
|
|
113182
|
+
dst.fill(dst[dIndex - 1] | 0, dIndex, dIndex + mLength);
|
|
113183
|
+
dIndex += mLength;
|
|
113184
|
+
} else if (hasCopyWithin && mOffset > mLength && mLength > 31) {
|
|
113185
|
+
dst.copyWithin(dIndex, dIndex - mOffset, dIndex - mOffset + mLength);
|
|
113186
|
+
dIndex += mLength;
|
|
113187
|
+
} else {
|
|
113188
|
+
for (i = dIndex - mOffset, n = i + mLength; i < n; ) {
|
|
113189
|
+
dst[dIndex++] = dst[i++] | 0;
|
|
113190
|
+
}
|
|
113191
|
+
}
|
|
113192
|
+
}
|
|
113193
|
+
return dIndex;
|
|
113209
113194
|
}
|
|
113210
|
-
|
|
113211
|
-
|
|
113212
|
-
|
|
113213
|
-
|
|
113214
|
-
|
|
113215
|
-
|
|
113216
|
-
|
|
113217
|
-
|
|
113218
|
-
|
|
113219
|
-
|
|
113195
|
+
function decompressFrame(src, dst) {
|
|
113196
|
+
let useBlockSum, useContentSum, useContentSize, descriptor;
|
|
113197
|
+
let sIndex = 0;
|
|
113198
|
+
let dIndex = 0;
|
|
113199
|
+
if (readU32(src, sIndex) !== magicNum) {
|
|
113200
|
+
throw new Error("invalid magic number");
|
|
113201
|
+
}
|
|
113202
|
+
sIndex += 4;
|
|
113203
|
+
descriptor = src[sIndex++];
|
|
113204
|
+
if ((descriptor & fdVersionMask) !== fdVersion) {
|
|
113205
|
+
throw new Error("incompatible descriptor version");
|
|
113206
|
+
}
|
|
113207
|
+
useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
113208
|
+
useContentSum = (descriptor & fdContentChksum) !== 0;
|
|
113209
|
+
useContentSize = (descriptor & fdContentSize) !== 0;
|
|
113210
|
+
const bsIdx = src[sIndex++] >> bsShift & bsMask;
|
|
113211
|
+
if (bsMap[bsIdx] === void 0) {
|
|
113212
|
+
throw new Error("invalid block size");
|
|
113213
|
+
}
|
|
113214
|
+
if (useContentSize) {
|
|
113215
|
+
sIndex += 8;
|
|
113216
|
+
}
|
|
113217
|
+
sIndex++;
|
|
113218
|
+
while (true) {
|
|
113219
|
+
var compSize;
|
|
113220
|
+
compSize = readU32(src, sIndex);
|
|
113221
|
+
sIndex += 4;
|
|
113222
|
+
if (compSize === 0) {
|
|
113223
|
+
break;
|
|
113220
113224
|
}
|
|
113221
|
-
|
|
113222
|
-
|
|
113223
|
-
const y = numeric(n[1]);
|
|
113224
|
-
const width = Math.max(n[0].length, n[1].length);
|
|
113225
|
-
let incr = n.length === 3 && n[2] !== undefined ?
|
|
113226
|
-
Math.max(Math.abs(numeric(n[2])), 1)
|
|
113227
|
-
: 1;
|
|
113228
|
-
let test = lte;
|
|
113229
|
-
const reverse = y < x;
|
|
113230
|
-
if (reverse) {
|
|
113231
|
-
incr *= -1;
|
|
113232
|
-
test = gte;
|
|
113225
|
+
if (useBlockSum) {
|
|
113226
|
+
sIndex += 4;
|
|
113233
113227
|
}
|
|
113234
|
-
|
|
113235
|
-
|
|
113236
|
-
|
|
113237
|
-
|
|
113238
|
-
|
|
113239
|
-
|
|
113240
|
-
|
|
113241
|
-
|
|
113242
|
-
}
|
|
113243
|
-
}
|
|
113244
|
-
else {
|
|
113245
|
-
c = String(i);
|
|
113246
|
-
if (pad) {
|
|
113247
|
-
const need = width - c.length;
|
|
113248
|
-
if (need > 0) {
|
|
113249
|
-
const z = new Array(need + 1).join('0');
|
|
113250
|
-
if (i < 0) {
|
|
113251
|
-
c = '-' + z + c.slice(1);
|
|
113252
|
-
}
|
|
113253
|
-
else {
|
|
113254
|
-
c = z + c;
|
|
113255
|
-
}
|
|
113256
|
-
}
|
|
113257
|
-
}
|
|
113258
|
-
}
|
|
113259
|
-
if (length + c.length > maxLength)
|
|
113260
|
-
break;
|
|
113261
|
-
N.push(c);
|
|
113262
|
-
length += c.length;
|
|
113228
|
+
if ((compSize & bsUncompressed) !== 0) {
|
|
113229
|
+
compSize &= ~bsUncompressed;
|
|
113230
|
+
for (let j = 0; j < compSize; j++) {
|
|
113231
|
+
dst[dIndex++] = src[sIndex++];
|
|
113232
|
+
}
|
|
113233
|
+
} else {
|
|
113234
|
+
dIndex = decompressBlock(src, dst, sIndex, compSize, dIndex);
|
|
113235
|
+
sIndex += compSize;
|
|
113263
113236
|
}
|
|
113264
|
-
|
|
113237
|
+
}
|
|
113238
|
+
if (useContentSum) {
|
|
113239
|
+
sIndex += 4;
|
|
113240
|
+
}
|
|
113241
|
+
return dIndex;
|
|
113265
113242
|
}
|
|
113266
|
-
function
|
|
113267
|
-
|
|
113268
|
-
|
|
113269
|
-
|
|
113270
|
-
|
|
113271
|
-
|
|
113272
|
-
|
|
113273
|
-
|
|
113274
|
-
|
|
113275
|
-
|
|
113276
|
-
|
|
113277
|
-
// them (the one with no brace set left in the tail).
|
|
113278
|
-
let dropEmpties = false;
|
|
113279
|
-
let firstGroup = true;
|
|
113280
|
-
for (;;) {
|
|
113281
|
-
const m = balanced('{', '}', str);
|
|
113282
|
-
// No brace set left: the rest of the string is literal.
|
|
113283
|
-
if (!m) {
|
|
113284
|
-
return combine(acc, str, [''], max, maxLength, dropEmpties);
|
|
113285
|
-
}
|
|
113286
|
-
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
113287
|
-
const pre = m.pre;
|
|
113288
|
-
if (/\$$/.test(pre)) {
|
|
113289
|
-
acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
|
|
113290
|
-
firstGroup = false;
|
|
113291
|
-
if (!m.post.length)
|
|
113292
|
-
break;
|
|
113293
|
-
str = m.post;
|
|
113294
|
-
continue;
|
|
113295
|
-
}
|
|
113296
|
-
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
113297
|
-
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
113298
|
-
const isSequence = isNumericSequence || isAlphaSequence;
|
|
113299
|
-
const isOptions = m.body.indexOf(',') >= 0;
|
|
113300
|
-
if (!isSequence && !isOptions) {
|
|
113301
|
-
// {a},b}
|
|
113302
|
-
if (m.post.match(/,(?!,).*\}/)) {
|
|
113303
|
-
str = m.pre + '{' + m.body + escClose + m.post;
|
|
113304
|
-
isTop = true;
|
|
113305
|
-
continue;
|
|
113306
|
-
}
|
|
113307
|
-
// Nothing here expands, so the whole remaining string is literal.
|
|
113308
|
-
return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
|
|
113309
|
-
}
|
|
113310
|
-
if (firstGroup) {
|
|
113311
|
-
dropEmpties = isTop && !isSequence;
|
|
113312
|
-
firstGroup = false;
|
|
113313
|
-
}
|
|
113314
|
-
let values;
|
|
113315
|
-
if (isSequence) {
|
|
113316
|
-
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
|
|
113317
|
-
}
|
|
113318
|
-
else {
|
|
113319
|
-
let n = parseCommaParts(m.body);
|
|
113320
|
-
if (n.length === 1 && n[0] !== undefined) {
|
|
113321
|
-
// x{{a,b}}y ==> x{a}y x{b}y
|
|
113322
|
-
n = expand_(n[0], max, maxLength, false).map(embrace);
|
|
113323
|
-
//XXX is this necessary? Can't seem to hit it in tests.
|
|
113324
|
-
/* c8 ignore start */
|
|
113325
|
-
if (n.length === 1) {
|
|
113326
|
-
acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
|
|
113327
|
-
if (!m.post.length)
|
|
113328
|
-
break;
|
|
113329
|
-
str = m.post;
|
|
113330
|
-
continue;
|
|
113331
|
-
}
|
|
113332
|
-
/* c8 ignore stop */
|
|
113333
|
-
}
|
|
113334
|
-
// Values that `combine` is going to drop as empty produce no result, so
|
|
113335
|
-
// they must not count against `max` - otherwise `{a,,b}` with `max: 2`
|
|
113336
|
-
// would stop at `['a', '']` and yield one result instead of two. Skipping
|
|
113337
|
-
// them outright keeps `values` bounded while leaving `max` a bound on
|
|
113338
|
-
// *kept* results.
|
|
113339
|
-
let dropsEmpties = dropEmpties && !m.post.length && !pre;
|
|
113340
|
-
for (let d = 0; dropsEmpties && d < acc.length; d++) {
|
|
113341
|
-
if (acc[d]) {
|
|
113342
|
-
dropsEmpties = false;
|
|
113343
|
-
}
|
|
113344
|
-
}
|
|
113345
|
-
values = [];
|
|
113346
|
-
let valuesLength = 0;
|
|
113347
|
-
outer: for (let j = 0; j < n.length; j++) {
|
|
113348
|
-
const expanded = expand_(n[j], max, maxLength, false);
|
|
113349
|
-
for (let k = 0; k < expanded.length; k++) {
|
|
113350
|
-
const v = expanded[k];
|
|
113351
|
-
if (dropsEmpties && !v)
|
|
113352
|
-
continue;
|
|
113353
|
-
if (values.length >= max || valuesLength + v.length > maxLength) {
|
|
113354
|
-
break outer;
|
|
113355
|
-
}
|
|
113356
|
-
values.push(v);
|
|
113357
|
-
valuesLength += v.length;
|
|
113358
|
-
}
|
|
113359
|
-
}
|
|
113360
|
-
}
|
|
113361
|
-
acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
|
|
113362
|
-
if (!m.post.length)
|
|
113363
|
-
break;
|
|
113364
|
-
str = m.post;
|
|
113365
|
-
}
|
|
113366
|
-
return acc;
|
|
113243
|
+
function decompress(src, maxSize) {
|
|
113244
|
+
let dst, size;
|
|
113245
|
+
if (maxSize === void 0) {
|
|
113246
|
+
maxSize = decompressBound(src);
|
|
113247
|
+
}
|
|
113248
|
+
dst = makeBuffer(maxSize);
|
|
113249
|
+
size = decompressFrame(src, dst);
|
|
113250
|
+
if (size !== maxSize) {
|
|
113251
|
+
dst = sliceArray(dst, 0, size);
|
|
113252
|
+
}
|
|
113253
|
+
return dst;
|
|
113367
113254
|
}
|
|
113368
113255
|
|
|
113369
|
-
|
|
113370
|
-
|
|
113371
|
-
|
|
113372
|
-
|
|
113256
|
+
// src/utils/RangeList.ts
|
|
113257
|
+
var RangeList = class {
|
|
113258
|
+
ranges = [];
|
|
113259
|
+
/**
|
|
113260
|
+
* Add a range to the list. If it overlaps with existing ranges,
|
|
113261
|
+
* it will split them and increment reference counts accordingly.
|
|
113262
|
+
*/
|
|
113263
|
+
add(start, end) {
|
|
113264
|
+
if (end <= start) {
|
|
113265
|
+
throw new TypeError("End must be greater than start");
|
|
113373
113266
|
}
|
|
113374
|
-
|
|
113375
|
-
|
|
113267
|
+
const overlappingRanges = [];
|
|
113268
|
+
for (let i = 0; i < this.ranges.length; i++) {
|
|
113269
|
+
const range2 = this.ranges[i];
|
|
113270
|
+
if (start < range2.end && end > range2.start) {
|
|
113271
|
+
overlappingRanges.push({ index: i, range: range2 });
|
|
113272
|
+
}
|
|
113273
|
+
if (range2.data !== null) {
|
|
113274
|
+
throw new Error("Overlapping range already has data");
|
|
113275
|
+
}
|
|
113276
|
+
}
|
|
113277
|
+
if (overlappingRanges.length === 0) {
|
|
113278
|
+
this.ranges.push({ start, end, refCount: 1, data: null });
|
|
113279
|
+
this.ranges.sort((a, b) => a.start - b.start);
|
|
113280
|
+
return;
|
|
113281
|
+
}
|
|
113282
|
+
const newRanges = [];
|
|
113283
|
+
let currentPos = start;
|
|
113284
|
+
for (let i = 0; i < overlappingRanges.length; i++) {
|
|
113285
|
+
const { range: range2 } = overlappingRanges[i];
|
|
113286
|
+
if (currentPos < range2.start) {
|
|
113287
|
+
newRanges.push({
|
|
113288
|
+
start: currentPos,
|
|
113289
|
+
end: range2.start,
|
|
113290
|
+
refCount: 1,
|
|
113291
|
+
data: null
|
|
113292
|
+
});
|
|
113293
|
+
} else if (range2.start < currentPos) {
|
|
113294
|
+
newRanges.push({
|
|
113295
|
+
start: range2.start,
|
|
113296
|
+
end: currentPos,
|
|
113297
|
+
refCount: range2.refCount,
|
|
113298
|
+
data: null
|
|
113299
|
+
});
|
|
113300
|
+
}
|
|
113301
|
+
newRanges.push({
|
|
113302
|
+
start: Math.max(currentPos, range2.start),
|
|
113303
|
+
end: Math.min(end, range2.end),
|
|
113304
|
+
refCount: range2.refCount + 1,
|
|
113305
|
+
data: null
|
|
113306
|
+
});
|
|
113307
|
+
if (range2.end > end) {
|
|
113308
|
+
newRanges.push({
|
|
113309
|
+
start: end,
|
|
113310
|
+
end: range2.end,
|
|
113311
|
+
refCount: range2.refCount,
|
|
113312
|
+
data: null
|
|
113313
|
+
});
|
|
113314
|
+
}
|
|
113315
|
+
currentPos = Math.max(currentPos, range2.end);
|
|
113316
|
+
}
|
|
113317
|
+
if (currentPos < end) {
|
|
113318
|
+
newRanges.push({
|
|
113319
|
+
start: currentPos,
|
|
113320
|
+
end,
|
|
113321
|
+
refCount: 1,
|
|
113322
|
+
data: null
|
|
113323
|
+
});
|
|
113324
|
+
}
|
|
113325
|
+
const firstIndex = overlappingRanges[0].index;
|
|
113326
|
+
const lastIndex = overlappingRanges[overlappingRanges.length - 1].index;
|
|
113327
|
+
this.ranges.splice(firstIndex, lastIndex - firstIndex + 1, ...newRanges);
|
|
113328
|
+
this.ranges.sort((a, b) => a.start - b.start);
|
|
113329
|
+
}
|
|
113330
|
+
/**
|
|
113331
|
+
* Remove a range from the list. The range must start and end at existing boundaries.
|
|
113332
|
+
*/
|
|
113333
|
+
remove(start, end) {
|
|
113334
|
+
if (end <= start) {
|
|
113335
|
+
throw new TypeError("End must be greater than start");
|
|
113336
|
+
}
|
|
113337
|
+
const affectedRanges = [];
|
|
113338
|
+
for (let i = 0; i < this.ranges.length; i++) {
|
|
113339
|
+
const range2 = this.ranges[i];
|
|
113340
|
+
if (start < range2.end && end > range2.start) {
|
|
113341
|
+
affectedRanges.push({ index: i, range: range2 });
|
|
113342
|
+
}
|
|
113343
|
+
}
|
|
113344
|
+
if (affectedRanges.length === 0) {
|
|
113345
|
+
throw new Error("No ranges found to remove");
|
|
113346
|
+
}
|
|
113347
|
+
if (start !== affectedRanges[0].range.start || end !== affectedRanges[affectedRanges.length - 1].range.end) {
|
|
113348
|
+
throw new Error("Range boundaries must match existing boundaries");
|
|
113349
|
+
}
|
|
113350
|
+
for (let i = 0; i < affectedRanges.length; i++) {
|
|
113351
|
+
const { range: range2 } = affectedRanges[i];
|
|
113352
|
+
range2.refCount--;
|
|
113353
|
+
}
|
|
113354
|
+
this.ranges = this.ranges.filter((range2) => range2.refCount > 0);
|
|
113355
|
+
}
|
|
113356
|
+
/**
|
|
113357
|
+
* Get all ranges within the specified boundaries.
|
|
113358
|
+
*/
|
|
113359
|
+
getRanges(start, end) {
|
|
113360
|
+
if (end <= start) {
|
|
113361
|
+
throw new TypeError("End must be greater than start");
|
|
113376
113362
|
}
|
|
113363
|
+
return this.ranges.filter((range2) => start < range2.end && end > range2.start);
|
|
113364
|
+
}
|
|
113365
|
+
/**
|
|
113366
|
+
* Get all ranges in the list
|
|
113367
|
+
*/
|
|
113368
|
+
getAllRanges() {
|
|
113369
|
+
return [...this.ranges];
|
|
113370
|
+
}
|
|
113377
113371
|
};
|
|
113378
113372
|
|
|
113379
|
-
//
|
|
113380
|
-
|
|
113381
|
-
|
|
113382
|
-
|
|
113383
|
-
|
|
113384
|
-
|
|
113385
|
-
|
|
113386
|
-
|
|
113387
|
-
|
|
113388
|
-
|
|
113389
|
-
|
|
113390
|
-
|
|
113391
|
-
|
|
113392
|
-
|
|
113393
|
-
|
|
113394
|
-
|
|
113395
|
-
|
|
113396
|
-
|
|
113397
|
-
|
|
113398
|
-
|
|
113399
|
-
|
|
113400
|
-
|
|
113401
|
-
|
|
113373
|
+
// src/utils/XetBlob.ts
|
|
113374
|
+
var JWT_SAFETY_PERIOD = 6e4;
|
|
113375
|
+
var JWT_CACHE_SIZE = 1e3;
|
|
113376
|
+
var compressionSchemeLabels = {
|
|
113377
|
+
[0 /* None */]: "None",
|
|
113378
|
+
[1 /* LZ4 */]: "LZ4",
|
|
113379
|
+
[2 /* ByteGroupingLZ4 */]: "ByteGroupingLZ4"
|
|
113380
|
+
};
|
|
113381
|
+
var XET_CHUNK_HEADER_BYTES = 8;
|
|
113382
|
+
var XetBlob = class extends Blob {
|
|
113383
|
+
fetch;
|
|
113384
|
+
accessToken;
|
|
113385
|
+
refreshUrl;
|
|
113386
|
+
reconstructionUrl;
|
|
113387
|
+
hash;
|
|
113388
|
+
start = 0;
|
|
113389
|
+
end = 0;
|
|
113390
|
+
internalLogging = false;
|
|
113391
|
+
reconstructionInfo;
|
|
113392
|
+
listener;
|
|
113393
|
+
constructor(params) {
|
|
113394
|
+
super([]);
|
|
113395
|
+
this.fetch = params.fetch ?? fetch.bind(globalThis);
|
|
113396
|
+
this.accessToken = checkCredentials(params);
|
|
113397
|
+
this.refreshUrl = params.refreshUrl;
|
|
113398
|
+
this.end = params.size;
|
|
113399
|
+
this.reconstructionUrl = params.reconstructionUrl;
|
|
113400
|
+
this.hash = params.hash;
|
|
113401
|
+
this.listener = params.listener;
|
|
113402
|
+
this.internalLogging = params.internalLogging ?? false;
|
|
113403
|
+
this.refreshUrl;
|
|
113404
|
+
}
|
|
113405
|
+
get size() {
|
|
113406
|
+
return this.end - this.start;
|
|
113407
|
+
}
|
|
113408
|
+
#clone() {
|
|
113409
|
+
const blob = new XetBlob({
|
|
113410
|
+
fetch: this.fetch,
|
|
113411
|
+
hash: this.hash,
|
|
113412
|
+
refreshUrl: this.refreshUrl,
|
|
113413
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
113414
|
+
reconstructionUrl: this.reconstructionUrl,
|
|
113415
|
+
size: this.size
|
|
113416
|
+
});
|
|
113417
|
+
blob.accessToken = this.accessToken;
|
|
113418
|
+
blob.start = this.start;
|
|
113419
|
+
blob.end = this.end;
|
|
113420
|
+
blob.reconstructionInfo = this.reconstructionInfo;
|
|
113421
|
+
blob.listener = this.listener;
|
|
113422
|
+
blob.internalLogging = this.internalLogging;
|
|
113423
|
+
return blob;
|
|
113424
|
+
}
|
|
113425
|
+
slice(start = 0, end = this.size) {
|
|
113426
|
+
const slice = this.#clone();
|
|
113427
|
+
slice.start = this.start + start;
|
|
113428
|
+
slice.end = Math.min(this.start + end, this.end);
|
|
113429
|
+
if (slice.start !== this.start || slice.end !== this.end) {
|
|
113430
|
+
slice.reconstructionInfo = void 0;
|
|
113431
|
+
}
|
|
113432
|
+
return slice;
|
|
113433
|
+
}
|
|
113434
|
+
#reconstructionInfoPromise;
|
|
113435
|
+
#loadReconstructionInfo() {
|
|
113436
|
+
if (this.#reconstructionInfoPromise) {
|
|
113437
|
+
return this.#reconstructionInfoPromise;
|
|
113438
|
+
}
|
|
113439
|
+
this.#reconstructionInfoPromise = (async () => {
|
|
113440
|
+
const connParams = await getAccessToken(this.accessToken, this.fetch, this.refreshUrl);
|
|
113441
|
+
const resp = await this.fetch(this.reconstructionUrl ?? `${connParams.casUrl}/v1/reconstructions/${this.hash}`, {
|
|
113442
|
+
headers: {
|
|
113443
|
+
Authorization: `Bearer ${connParams.accessToken}`,
|
|
113444
|
+
Range: `bytes=${this.start}-${this.end - 1}`
|
|
113445
|
+
}
|
|
113446
|
+
});
|
|
113447
|
+
if (!resp.ok) {
|
|
113448
|
+
throw await createApiError(resp);
|
|
113449
|
+
}
|
|
113450
|
+
this.reconstructionInfo = await resp.json();
|
|
113451
|
+
return this.reconstructionInfo;
|
|
113452
|
+
})().finally(() => this.#reconstructionInfoPromise = void 0);
|
|
113453
|
+
return this.#reconstructionInfoPromise;
|
|
113454
|
+
}
|
|
113455
|
+
async #fetch() {
|
|
113456
|
+
if (!this.reconstructionInfo) {
|
|
113457
|
+
await this.#loadReconstructionInfo();
|
|
113458
|
+
}
|
|
113459
|
+
const rangeLists = /* @__PURE__ */ new Map();
|
|
113460
|
+
if (!this.reconstructionInfo) {
|
|
113461
|
+
throw new Error("Failed to load reconstruction info");
|
|
113462
|
+
}
|
|
113463
|
+
for (const term of this.reconstructionInfo.terms) {
|
|
113464
|
+
let rangeList = rangeLists.get(term.hash);
|
|
113465
|
+
if (!rangeList) {
|
|
113466
|
+
rangeList = new RangeList();
|
|
113467
|
+
rangeLists.set(term.hash, rangeList);
|
|
113468
|
+
}
|
|
113469
|
+
rangeList.add(term.range.start, term.range.end);
|
|
113470
|
+
}
|
|
113471
|
+
const listener = this.listener;
|
|
113472
|
+
const log = this.internalLogging ? (...args) => console.log(...args) : () => {
|
|
113473
|
+
};
|
|
113474
|
+
async function* readData(reconstructionInfo, customFetch, maxBytes, reloadReconstructionInfo) {
|
|
113475
|
+
let totalBytesRead = 0;
|
|
113476
|
+
let readBytesToSkip = reconstructionInfo.offset_into_first_range;
|
|
113477
|
+
for (const term of reconstructionInfo.terms) {
|
|
113478
|
+
if (totalBytesRead >= maxBytes) {
|
|
113479
|
+
break;
|
|
113480
|
+
}
|
|
113481
|
+
const rangeList = rangeLists.get(term.hash);
|
|
113482
|
+
if (!rangeList) {
|
|
113483
|
+
throw new Error(`Failed to find range list for term ${term.hash}`);
|
|
113484
|
+
}
|
|
113485
|
+
{
|
|
113486
|
+
const termRanges = rangeList.getRanges(term.range.start, term.range.end);
|
|
113487
|
+
if (termRanges.every((range2) => range2.data)) {
|
|
113488
|
+
log("all data available for term", term.hash, readBytesToSkip);
|
|
113489
|
+
rangeLoop:
|
|
113490
|
+
for (const range2 of termRanges) {
|
|
113491
|
+
for (let chunk2 of range2.data) {
|
|
113492
|
+
if (readBytesToSkip) {
|
|
113493
|
+
const skipped = Math.min(readBytesToSkip, chunk2.byteLength);
|
|
113494
|
+
chunk2 = chunk2.slice(skipped);
|
|
113495
|
+
readBytesToSkip -= skipped;
|
|
113496
|
+
if (!chunk2.byteLength) {
|
|
113497
|
+
continue;
|
|
113498
|
+
}
|
|
113499
|
+
}
|
|
113500
|
+
if (chunk2.byteLength > maxBytes - totalBytesRead) {
|
|
113501
|
+
chunk2 = chunk2.slice(0, maxBytes - totalBytesRead);
|
|
113502
|
+
}
|
|
113503
|
+
totalBytesRead += chunk2.byteLength;
|
|
113504
|
+
yield range2.refCount > 1 ? chunk2.slice() : chunk2;
|
|
113505
|
+
listener?.({ event: "progress", progress: { read: totalBytesRead, total: maxBytes } });
|
|
113506
|
+
if (totalBytesRead >= maxBytes) {
|
|
113507
|
+
break rangeLoop;
|
|
113508
|
+
}
|
|
113509
|
+
}
|
|
113510
|
+
}
|
|
113511
|
+
rangeList.remove(term.range.start, term.range.end);
|
|
113512
|
+
continue;
|
|
113513
|
+
}
|
|
113514
|
+
}
|
|
113515
|
+
const fetchInfo = reconstructionInfo.fetch_info[term.hash].find(
|
|
113516
|
+
(info) => info.range.start <= term.range.start && info.range.end >= term.range.end
|
|
113517
|
+
);
|
|
113518
|
+
if (!fetchInfo) {
|
|
113519
|
+
throw new Error(
|
|
113520
|
+
`Failed to find fetch info for term ${term.hash} and range ${term.range.start}-${term.range.end}`
|
|
113521
|
+
);
|
|
113522
|
+
}
|
|
113523
|
+
log("term", term);
|
|
113524
|
+
log("fetchinfo", fetchInfo);
|
|
113525
|
+
log("readBytesToSkip", readBytesToSkip);
|
|
113526
|
+
let resp = await customFetch(fetchInfo.url, {
|
|
113527
|
+
headers: {
|
|
113528
|
+
Range: `bytes=${fetchInfo.url_range.start}-${fetchInfo.url_range.end}`
|
|
113529
|
+
}
|
|
113530
|
+
});
|
|
113531
|
+
if (resp.status === 403) {
|
|
113532
|
+
reconstructionInfo = await reloadReconstructionInfo();
|
|
113533
|
+
resp = await customFetch(fetchInfo.url, {
|
|
113534
|
+
headers: {
|
|
113535
|
+
Range: `bytes=${fetchInfo.url_range.start}-${fetchInfo.url_range.end}`
|
|
113536
|
+
}
|
|
113537
|
+
});
|
|
113538
|
+
}
|
|
113539
|
+
if (!resp.ok) {
|
|
113540
|
+
throw await createApiError(resp);
|
|
113541
|
+
}
|
|
113542
|
+
log(
|
|
113543
|
+
"expected content length",
|
|
113544
|
+
resp.headers.get("content-length"),
|
|
113545
|
+
"range",
|
|
113546
|
+
fetchInfo.url_range,
|
|
113547
|
+
resp.headers.get("content-range")
|
|
113548
|
+
);
|
|
113549
|
+
const reader = resp.body?.getReader();
|
|
113550
|
+
if (!reader) {
|
|
113551
|
+
throw new Error("Failed to get reader from response body");
|
|
113552
|
+
}
|
|
113553
|
+
let done = false;
|
|
113554
|
+
let chunkIndex = fetchInfo.range.start;
|
|
113555
|
+
const ranges = rangeList.getRanges(fetchInfo.range.start, fetchInfo.range.end);
|
|
113556
|
+
let leftoverBytes = void 0;
|
|
113557
|
+
let totalFetchBytes = 0;
|
|
113558
|
+
fetchData:
|
|
113559
|
+
while (!done && totalBytesRead < maxBytes) {
|
|
113560
|
+
const result = await reader.read();
|
|
113561
|
+
listener?.({ event: "read" });
|
|
113562
|
+
done = result.done;
|
|
113563
|
+
log("read", result.value?.byteLength, "bytes", "total read", totalBytesRead, "toSkip", readBytesToSkip);
|
|
113564
|
+
if (!result.value) {
|
|
113565
|
+
log("no data in result, cancelled", result);
|
|
113566
|
+
continue;
|
|
113567
|
+
}
|
|
113568
|
+
totalFetchBytes += result.value.byteLength;
|
|
113569
|
+
if (leftoverBytes) {
|
|
113570
|
+
result.value = combineUint8Arrays(leftoverBytes, result.value);
|
|
113571
|
+
leftoverBytes = void 0;
|
|
113572
|
+
}
|
|
113573
|
+
while (totalBytesRead < maxBytes && result.value?.byteLength) {
|
|
113574
|
+
if (result.value.byteLength < 8) {
|
|
113575
|
+
leftoverBytes = result.value;
|
|
113576
|
+
continue fetchData;
|
|
113577
|
+
}
|
|
113578
|
+
const header = new DataView(result.value.buffer, result.value.byteOffset, XET_CHUNK_HEADER_BYTES);
|
|
113579
|
+
const chunkHeader = {
|
|
113580
|
+
version: header.getUint8(0),
|
|
113581
|
+
compressed_length: header.getUint8(1) | header.getUint8(2) << 8 | header.getUint8(3) << 16,
|
|
113582
|
+
compression_scheme: header.getUint8(4),
|
|
113583
|
+
uncompressed_length: header.getUint8(5) | header.getUint8(6) << 8 | header.getUint8(7) << 16
|
|
113584
|
+
};
|
|
113585
|
+
log("chunk header", chunkHeader, "to skip", readBytesToSkip);
|
|
113586
|
+
if (chunkHeader.version !== 0) {
|
|
113587
|
+
throw new Error(`Unsupported chunk version ${chunkHeader.version}`);
|
|
113588
|
+
}
|
|
113589
|
+
if (chunkHeader.compression_scheme !== 0 /* None */ && chunkHeader.compression_scheme !== 1 /* LZ4 */ && chunkHeader.compression_scheme !== 2 /* ByteGroupingLZ4 */) {
|
|
113590
|
+
throw new Error(
|
|
113591
|
+
`Unsupported compression scheme ${compressionSchemeLabels[chunkHeader.compression_scheme] ?? chunkHeader.compression_scheme}`
|
|
113592
|
+
);
|
|
113593
|
+
}
|
|
113594
|
+
if (result.value.byteLength < chunkHeader.compressed_length + XET_CHUNK_HEADER_BYTES) {
|
|
113595
|
+
leftoverBytes = result.value;
|
|
113596
|
+
continue fetchData;
|
|
113597
|
+
}
|
|
113598
|
+
result.value = result.value.slice(XET_CHUNK_HEADER_BYTES);
|
|
113599
|
+
let uncompressed = chunkHeader.compression_scheme === 1 /* LZ4 */ ? decompress(result.value.slice(0, chunkHeader.compressed_length), chunkHeader.uncompressed_length) : chunkHeader.compression_scheme === 2 /* ByteGroupingLZ4 */ ? bg4_regroup_bytes(
|
|
113600
|
+
decompress(
|
|
113601
|
+
result.value.slice(0, chunkHeader.compressed_length),
|
|
113602
|
+
chunkHeader.uncompressed_length
|
|
113603
|
+
)
|
|
113604
|
+
) : result.value.slice(0, chunkHeader.compressed_length);
|
|
113605
|
+
const range2 = ranges.find((range3) => chunkIndex >= range3.start && chunkIndex < range3.end);
|
|
113606
|
+
const shouldYield = chunkIndex >= term.range.start && chunkIndex < term.range.end;
|
|
113607
|
+
const minRefCountToStore = shouldYield ? 2 : 1;
|
|
113608
|
+
let stored = false;
|
|
113609
|
+
if (range2 && range2.refCount >= minRefCountToStore) {
|
|
113610
|
+
range2.data ??= [];
|
|
113611
|
+
range2.data.push(uncompressed);
|
|
113612
|
+
stored = true;
|
|
113613
|
+
}
|
|
113614
|
+
if (shouldYield) {
|
|
113615
|
+
if (readBytesToSkip) {
|
|
113616
|
+
const skipped = Math.min(readBytesToSkip, uncompressed.byteLength);
|
|
113617
|
+
uncompressed = uncompressed.slice(readBytesToSkip);
|
|
113618
|
+
readBytesToSkip -= skipped;
|
|
113619
|
+
}
|
|
113620
|
+
if (uncompressed.byteLength > maxBytes - totalBytesRead) {
|
|
113621
|
+
uncompressed = uncompressed.slice(0, maxBytes - totalBytesRead);
|
|
113622
|
+
}
|
|
113623
|
+
if (uncompressed.byteLength) {
|
|
113624
|
+
log(
|
|
113625
|
+
"yield",
|
|
113626
|
+
uncompressed.byteLength,
|
|
113627
|
+
"bytes",
|
|
113628
|
+
result.value.byteLength,
|
|
113629
|
+
"total read",
|
|
113630
|
+
totalBytesRead,
|
|
113631
|
+
stored
|
|
113632
|
+
);
|
|
113633
|
+
totalBytesRead += uncompressed.byteLength;
|
|
113634
|
+
yield stored ? uncompressed.slice() : uncompressed;
|
|
113635
|
+
listener?.({ event: "progress", progress: { read: totalBytesRead, total: maxBytes } });
|
|
113636
|
+
}
|
|
113637
|
+
}
|
|
113638
|
+
chunkIndex++;
|
|
113639
|
+
result.value = result.value.slice(chunkHeader.compressed_length);
|
|
113640
|
+
}
|
|
113641
|
+
}
|
|
113642
|
+
if (done && totalBytesRead < maxBytes && totalFetchBytes < fetchInfo.url_range.end - fetchInfo.url_range.start + 1) {
|
|
113643
|
+
log("done", done, "total read", totalBytesRead, maxBytes, totalFetchBytes);
|
|
113644
|
+
log("failed to fetch all data for term", term.hash);
|
|
113645
|
+
throw new Error(
|
|
113646
|
+
`Failed to fetch all data for term ${term.hash}, fetched ${totalFetchBytes} bytes out of ${fetchInfo.url_range.end - fetchInfo.url_range.start + 1}`
|
|
113647
|
+
);
|
|
113648
|
+
}
|
|
113649
|
+
log("done", done, "total read", totalBytesRead, maxBytes, totalFetchBytes);
|
|
113650
|
+
log("cancel reader");
|
|
113651
|
+
await reader.cancel();
|
|
113652
|
+
}
|
|
113653
|
+
}
|
|
113654
|
+
const iterator = readData(
|
|
113655
|
+
this.reconstructionInfo,
|
|
113656
|
+
this.fetch,
|
|
113657
|
+
this.end - this.start,
|
|
113658
|
+
this.#loadReconstructionInfo.bind(this)
|
|
113659
|
+
);
|
|
113660
|
+
return new ReadableStream(
|
|
113661
|
+
{
|
|
113662
|
+
// todo: when Safari supports it, type controller as ReadableByteStreamController
|
|
113663
|
+
async pull(controller) {
|
|
113664
|
+
const result = await iterator.next();
|
|
113665
|
+
if (result.value) {
|
|
113666
|
+
controller.enqueue(result.value);
|
|
113667
|
+
}
|
|
113668
|
+
if (result.done) {
|
|
113669
|
+
controller.close();
|
|
113670
|
+
}
|
|
113671
|
+
},
|
|
113672
|
+
type: "bytes"
|
|
113673
|
+
// todo: when Safari supports it, add autoAllocateChunkSize param
|
|
113674
|
+
},
|
|
113675
|
+
// todo : use ByteLengthQueuingStrategy when there's good support for it, currently in Node.js it fails due to size being a function
|
|
113676
|
+
{
|
|
113677
|
+
highWaterMark: 1e3
|
|
113678
|
+
// 1_000 chunks for ~1MB of RAM
|
|
113679
|
+
}
|
|
113680
|
+
);
|
|
113681
|
+
}
|
|
113682
|
+
async arrayBuffer() {
|
|
113683
|
+
const result = await this.#fetch();
|
|
113684
|
+
return new Response(result).arrayBuffer();
|
|
113685
|
+
}
|
|
113686
|
+
async text() {
|
|
113687
|
+
const result = await this.#fetch();
|
|
113688
|
+
return new Response(result).text();
|
|
113689
|
+
}
|
|
113690
|
+
async response() {
|
|
113691
|
+
const result = await this.#fetch();
|
|
113692
|
+
return new Response(result);
|
|
113693
|
+
}
|
|
113694
|
+
stream() {
|
|
113695
|
+
const stream = new TransformStream();
|
|
113696
|
+
this.#fetch().then((response) => response.pipeThrough(stream)).catch((error) => stream.writable.abort(error.message));
|
|
113697
|
+
return stream.readable;
|
|
113698
|
+
}
|
|
113699
|
+
};
|
|
113700
|
+
var jwtPromises = /* @__PURE__ */ new Map();
|
|
113701
|
+
var jwts = /* @__PURE__ */ new Map();
|
|
113702
|
+
function cacheKey(params) {
|
|
113703
|
+
return JSON.stringify([params.refreshUrl, params.initialAccessToken]);
|
|
113704
|
+
}
|
|
113705
|
+
function bg4_regroup_bytes(bytes) {
|
|
113706
|
+
const split = Math.floor(bytes.byteLength / 4);
|
|
113707
|
+
const rem = bytes.byteLength % 4;
|
|
113708
|
+
const g1_pos = split + (rem >= 1 ? 1 : 0);
|
|
113709
|
+
const g2_pos = g1_pos + split + (rem >= 2 ? 1 : 0);
|
|
113710
|
+
const g3_pos = g2_pos + split + (rem == 3 ? 1 : 0);
|
|
113711
|
+
const ret = new Uint8Array(bytes.byteLength);
|
|
113712
|
+
for (let i = 0, j = 0; i < bytes.byteLength; i += 4, j++) {
|
|
113713
|
+
ret[i] = bytes[j];
|
|
113714
|
+
}
|
|
113715
|
+
for (let i = 1, j = g1_pos; i < bytes.byteLength; i += 4, j++) {
|
|
113716
|
+
ret[i] = bytes[j];
|
|
113717
|
+
}
|
|
113718
|
+
for (let i = 2, j = g2_pos; i < bytes.byteLength; i += 4, j++) {
|
|
113719
|
+
ret[i] = bytes[j];
|
|
113720
|
+
}
|
|
113721
|
+
for (let i = 3, j = g3_pos; i < bytes.byteLength; i += 4, j++) {
|
|
113722
|
+
ret[i] = bytes[j];
|
|
113723
|
+
}
|
|
113724
|
+
return ret;
|
|
113725
|
+
}
|
|
113726
|
+
async function getAccessToken(initialAccessToken, customFetch, refreshUrl) {
|
|
113727
|
+
const key = cacheKey({ refreshUrl, initialAccessToken });
|
|
113728
|
+
const jwt = jwts.get(key);
|
|
113729
|
+
if (jwt && jwt.expiresAt > new Date(Date.now() + JWT_SAFETY_PERIOD)) {
|
|
113730
|
+
return { accessToken: jwt.accessToken, casUrl: jwt.casUrl };
|
|
113731
|
+
}
|
|
113732
|
+
const existingPromise = jwtPromises.get(key);
|
|
113733
|
+
if (existingPromise) {
|
|
113734
|
+
return existingPromise;
|
|
113735
|
+
}
|
|
113736
|
+
const promise = (async () => {
|
|
113737
|
+
const resp = await customFetch(refreshUrl, {
|
|
113738
|
+
headers: {
|
|
113739
|
+
...initialAccessToken ? {
|
|
113740
|
+
Authorization: `Bearer ${initialAccessToken}`
|
|
113741
|
+
} : {}
|
|
113742
|
+
}
|
|
113743
|
+
});
|
|
113744
|
+
if (!resp.ok) {
|
|
113745
|
+
throw new Error(`Failed to get JWT token: ${resp.status} ${await resp.text()}`);
|
|
113746
|
+
}
|
|
113747
|
+
const json = await resp.json();
|
|
113748
|
+
const jwt2 = {
|
|
113749
|
+
accessToken: json.accessToken,
|
|
113750
|
+
expiresAt: new Date(json.exp * 1e3),
|
|
113751
|
+
casUrl: json.casUrl
|
|
113752
|
+
};
|
|
113753
|
+
jwtPromises.delete(key);
|
|
113754
|
+
for (const [key2, value] of jwts.entries()) {
|
|
113755
|
+
if (value.expiresAt < new Date(Date.now() + JWT_SAFETY_PERIOD)) {
|
|
113756
|
+
jwts.delete(key2);
|
|
113757
|
+
} else {
|
|
113758
|
+
break;
|
|
113759
|
+
}
|
|
113760
|
+
}
|
|
113761
|
+
if (jwts.size >= JWT_CACHE_SIZE) {
|
|
113762
|
+
const keyToDelete = jwts.keys().next().value;
|
|
113763
|
+
if (keyToDelete) {
|
|
113764
|
+
jwts.delete(keyToDelete);
|
|
113765
|
+
}
|
|
113766
|
+
}
|
|
113767
|
+
jwts.set(key, jwt2);
|
|
113768
|
+
return {
|
|
113769
|
+
accessToken: json.accessToken,
|
|
113770
|
+
casUrl: json.casUrl
|
|
113771
|
+
};
|
|
113772
|
+
})();
|
|
113773
|
+
jwtPromises.set(key, promise);
|
|
113774
|
+
return promise;
|
|
113775
|
+
}
|
|
113776
|
+
|
|
113777
|
+
// src/utils/WebBlob.ts
|
|
113778
|
+
var WebBlob = class extends Blob {
|
|
113779
|
+
static async create(url, opts) {
|
|
113780
|
+
const customFetch = opts?.fetch ?? fetch;
|
|
113781
|
+
const response = await customFetch(url, {
|
|
113782
|
+
method: "HEAD",
|
|
113783
|
+
...opts?.accessToken && {
|
|
113784
|
+
headers: {
|
|
113785
|
+
Authorization: `Bearer ${opts.accessToken}`
|
|
113786
|
+
}
|
|
113787
|
+
}
|
|
113788
|
+
});
|
|
113789
|
+
const size = Number(response.headers.get("content-length"));
|
|
113790
|
+
const contentType = response.headers.get("content-type") || "";
|
|
113791
|
+
const supportRange = response.headers.get("accept-ranges") === "bytes";
|
|
113792
|
+
if (!supportRange || size < (opts?.cacheBelow ?? 1e6)) {
|
|
113793
|
+
return await (await customFetch(url)).blob();
|
|
113794
|
+
}
|
|
113795
|
+
return new WebBlob(url, 0, size, contentType, true, customFetch, opts?.accessToken);
|
|
113796
|
+
}
|
|
113797
|
+
url;
|
|
113798
|
+
start;
|
|
113799
|
+
end;
|
|
113800
|
+
contentType;
|
|
113801
|
+
full;
|
|
113802
|
+
fetch;
|
|
113803
|
+
accessToken;
|
|
113804
|
+
constructor(url, start, end, contentType, full, customFetch, accessToken) {
|
|
113805
|
+
super([]);
|
|
113806
|
+
this.url = url;
|
|
113807
|
+
this.start = start;
|
|
113808
|
+
this.end = end;
|
|
113809
|
+
this.contentType = contentType;
|
|
113810
|
+
this.full = full;
|
|
113811
|
+
this.fetch = customFetch;
|
|
113812
|
+
this.accessToken = accessToken;
|
|
113813
|
+
}
|
|
113814
|
+
get size() {
|
|
113815
|
+
return this.end - this.start;
|
|
113816
|
+
}
|
|
113817
|
+
get type() {
|
|
113818
|
+
return this.contentType;
|
|
113819
|
+
}
|
|
113820
|
+
slice(start = 0, end = this.size) {
|
|
113821
|
+
const slice = new WebBlob(
|
|
113822
|
+
this.url,
|
|
113823
|
+
this.start + start,
|
|
113824
|
+
Math.min(this.start + end, this.end),
|
|
113825
|
+
this.contentType,
|
|
113826
|
+
start === 0 && end === this.size ? this.full : false,
|
|
113827
|
+
this.fetch,
|
|
113828
|
+
this.accessToken
|
|
113829
|
+
);
|
|
113830
|
+
return slice;
|
|
113831
|
+
}
|
|
113832
|
+
async arrayBuffer() {
|
|
113833
|
+
const result = await this.fetchRange();
|
|
113834
|
+
return result.arrayBuffer();
|
|
113835
|
+
}
|
|
113836
|
+
async text() {
|
|
113837
|
+
const result = await this.fetchRange();
|
|
113838
|
+
return result.text();
|
|
113839
|
+
}
|
|
113840
|
+
stream() {
|
|
113841
|
+
const stream = new TransformStream();
|
|
113842
|
+
this.fetchRange().then((response) => response.body?.pipeThrough(stream)).catch((error) => stream.writable.abort(error.message));
|
|
113843
|
+
return stream.readable;
|
|
113844
|
+
}
|
|
113845
|
+
fetchRange() {
|
|
113846
|
+
const fetch2 = this.fetch;
|
|
113847
|
+
if (this.full) {
|
|
113848
|
+
return fetch2(this.url, {
|
|
113849
|
+
...this.accessToken && {
|
|
113850
|
+
headers: {
|
|
113851
|
+
Authorization: `Bearer ${this.accessToken}`
|
|
113852
|
+
}
|
|
113853
|
+
}
|
|
113854
|
+
}).then((resp) => resp.ok ? resp : createApiError(resp));
|
|
113855
|
+
}
|
|
113856
|
+
return fetch2(this.url, {
|
|
113857
|
+
headers: {
|
|
113858
|
+
Range: `bytes=${this.start}-${this.end - 1}`,
|
|
113859
|
+
...this.accessToken && { Authorization: `Bearer ${this.accessToken}` }
|
|
113860
|
+
}
|
|
113861
|
+
}).then((resp) => resp.ok ? resp : createApiError(resp));
|
|
113862
|
+
}
|
|
113863
|
+
};
|
|
113864
|
+
|
|
113865
|
+
// src/utils/parseLinkHeader.ts
|
|
113866
|
+
function parseLinkHeader(header) {
|
|
113867
|
+
const regex = /<(https?:[/][/][^>]+)>;\s+rel="([^"]+)"/g;
|
|
113868
|
+
return Object.fromEntries([...header.matchAll(regex)].map(([, url, rel]) => [rel, url]));
|
|
113869
|
+
}
|
|
113870
|
+
|
|
113871
|
+
// src/lib/file-download-info.ts
|
|
113872
|
+
async function fileDownloadInfo(params) {
|
|
113873
|
+
const accessToken = checkCredentials(params);
|
|
113874
|
+
const repoId = toRepoId(params.repo);
|
|
113875
|
+
const hubUrl = params.hubUrl ?? HUB_URL;
|
|
113876
|
+
const url = `${hubUrl}/${repoId.type === "model" ? "" : `${repoId.type}s/`}${repoId.name}/${params.raw ? "raw" : "resolve"}/${encodeURIComponent(params.revision ?? "main")}/${params.path}` + (params.noContentDisposition ? "?noContentDisposition=1" : "");
|
|
113877
|
+
const resp = await (params.fetch ?? fetch)(url, {
|
|
113878
|
+
method: "GET",
|
|
113879
|
+
headers: {
|
|
113880
|
+
...accessToken && {
|
|
113881
|
+
Authorization: `Bearer ${accessToken}`
|
|
113882
|
+
},
|
|
113883
|
+
Range: "bytes=0-0",
|
|
113884
|
+
Accept: "application/vnd.xet-fileinfo+json, */*"
|
|
113885
|
+
}
|
|
113886
|
+
});
|
|
113887
|
+
if (resp.status === 404 && resp.headers.get("X-Error-Code") === "EntryNotFound") {
|
|
113888
|
+
return null;
|
|
113889
|
+
}
|
|
113890
|
+
if (!resp.ok) {
|
|
113891
|
+
throw await createApiError(resp);
|
|
113892
|
+
}
|
|
113893
|
+
let size;
|
|
113894
|
+
let xetInfo;
|
|
113895
|
+
if (resp.headers.get("Content-Type")?.includes("application/vnd.xet-fileinfo+json")) {
|
|
113896
|
+
size = parseInt(resp.headers.get("X-Linked-Size") ?? "invalid");
|
|
113897
|
+
if (isNaN(size)) {
|
|
113898
|
+
throw new InvalidApiResponseFormatError("Invalid file size received in X-Linked-Size header");
|
|
113899
|
+
}
|
|
113900
|
+
const hash2 = resp.headers.get("X-Xet-Hash");
|
|
113901
|
+
const links = parseLinkHeader(resp.headers.get("Link") ?? "");
|
|
113902
|
+
const reconstructionUrl = (() => {
|
|
113903
|
+
try {
|
|
113904
|
+
return new URL(links["xet-reconstruction-info"]);
|
|
113905
|
+
} catch {
|
|
113906
|
+
return null;
|
|
113907
|
+
}
|
|
113908
|
+
})();
|
|
113909
|
+
const refreshUrl = (() => {
|
|
113910
|
+
try {
|
|
113911
|
+
return new URL(links["xet-auth"]);
|
|
113912
|
+
} catch {
|
|
113913
|
+
return null;
|
|
113914
|
+
}
|
|
113915
|
+
})();
|
|
113916
|
+
if (!hash2) {
|
|
113917
|
+
throw new InvalidApiResponseFormatError("No hash received in X-Xet-Hash header");
|
|
113918
|
+
}
|
|
113919
|
+
if (!reconstructionUrl || !refreshUrl) {
|
|
113920
|
+
throw new InvalidApiResponseFormatError("No xet-reconstruction-info or xet-auth link header");
|
|
113921
|
+
}
|
|
113922
|
+
xetInfo = {
|
|
113923
|
+
hash: hash2,
|
|
113924
|
+
refreshUrl,
|
|
113925
|
+
reconstructionUrl
|
|
113926
|
+
};
|
|
113927
|
+
}
|
|
113928
|
+
if (size === void 0 || isNaN(size)) {
|
|
113929
|
+
const contentRangeHeader = resp.headers.get("content-range");
|
|
113930
|
+
if (!contentRangeHeader) {
|
|
113931
|
+
throw new InvalidApiResponseFormatError("Expected size information");
|
|
113932
|
+
}
|
|
113933
|
+
const [, parsedSize] = contentRangeHeader.split("/");
|
|
113934
|
+
size = parseInt(parsedSize);
|
|
113935
|
+
if (isNaN(size)) {
|
|
113936
|
+
throw new InvalidApiResponseFormatError("Invalid file size received");
|
|
113937
|
+
}
|
|
113938
|
+
}
|
|
113939
|
+
const etag = resp.headers.get("X-Linked-ETag") ?? resp.headers.get("ETag") ?? void 0;
|
|
113940
|
+
if (!etag) {
|
|
113941
|
+
throw new InvalidApiResponseFormatError("Expected ETag");
|
|
113942
|
+
}
|
|
113943
|
+
return {
|
|
113944
|
+
etag,
|
|
113945
|
+
size,
|
|
113946
|
+
xet: xetInfo,
|
|
113947
|
+
// Cannot use resp.url in case it's a S3 url and the user adds an Authorization header to it.
|
|
113948
|
+
url: resp.url && (new URL(resp.url).origin === new URL(hubUrl).origin || resp.headers.get("X-Cache")?.endsWith(" cloudfront")) ? resp.url : url
|
|
113949
|
+
};
|
|
113950
|
+
}
|
|
113951
|
+
|
|
113952
|
+
// src/lib/download-file.ts
|
|
113953
|
+
async function downloadFile(params) {
|
|
113954
|
+
const accessToken = checkCredentials(params);
|
|
113955
|
+
const info = params.downloadInfo ?? await fileDownloadInfo({
|
|
113956
|
+
accessToken,
|
|
113957
|
+
repo: params.repo,
|
|
113958
|
+
path: params.path,
|
|
113959
|
+
revision: params.revision,
|
|
113960
|
+
hubUrl: params.hubUrl,
|
|
113961
|
+
fetch: params.fetch,
|
|
113962
|
+
raw: params.raw
|
|
113963
|
+
});
|
|
113964
|
+
if (!info) {
|
|
113965
|
+
return null;
|
|
113966
|
+
}
|
|
113967
|
+
if (info.xet && params.xet) {
|
|
113968
|
+
return new XetBlob({
|
|
113969
|
+
refreshUrl: info.xet.refreshUrl.href,
|
|
113970
|
+
reconstructionUrl: info.xet.reconstructionUrl.href,
|
|
113971
|
+
fetch: params.fetch,
|
|
113972
|
+
accessToken,
|
|
113973
|
+
size: info.size
|
|
113974
|
+
});
|
|
113975
|
+
}
|
|
113976
|
+
return new WebBlob(new URL(info.url), 0, info.size, "", true, params.fetch ?? fetch, accessToken);
|
|
113977
|
+
}
|
|
113978
|
+
|
|
113979
|
+
// src/lib/list-files.ts
|
|
113980
|
+
async function* listFiles(params) {
|
|
113981
|
+
const accessToken = checkCredentials(params);
|
|
113982
|
+
const repoId = toRepoId(params.repo);
|
|
113983
|
+
let url = `${params.hubUrl || HUB_URL}/api/${repoId.type}s/${repoId.name}/tree/${params.revision || "main"}${params.path ? "/" + params.path : ""}?recursive=${!!params.recursive}&expand=${!!params.expand}`;
|
|
113984
|
+
while (url) {
|
|
113985
|
+
const res = await (params.fetch ?? fetch)(url, {
|
|
113986
|
+
headers: {
|
|
113987
|
+
accept: "application/json",
|
|
113988
|
+
...accessToken ? { Authorization: `Bearer ${accessToken}` } : void 0
|
|
113989
|
+
}
|
|
113990
|
+
});
|
|
113991
|
+
if (!res.ok) {
|
|
113992
|
+
throw await createApiError(res);
|
|
113993
|
+
}
|
|
113994
|
+
const items = await res.json();
|
|
113995
|
+
for (const item of items) {
|
|
113996
|
+
yield item;
|
|
113997
|
+
}
|
|
113998
|
+
const linkHeader = res.headers.get("Link");
|
|
113999
|
+
url = linkHeader ? parseLinkHeader(linkHeader).next : void 0;
|
|
114000
|
+
}
|
|
114001
|
+
}
|
|
114002
|
+
|
|
114003
|
+
const DIR_BASED_ENGINES = new Set(["exllamav3", "mlx-lm"]);
|
|
114004
|
+
const FLAG_BASED_ENGINE_ARGS = {
|
|
114005
|
+
"llama.cpp": "--chat-template-file",
|
|
114006
|
+
sglang: "--chat-template",
|
|
114007
|
+
vllm: "--chat-template"
|
|
114008
|
+
};
|
|
114009
|
+
function getChatTemplateLocalPath(targetDirectory) {
|
|
114010
|
+
return path$1.join(targetDirectory, CHAT_TEMPLATE_LOCAL_FILE_NAME);
|
|
114011
|
+
}
|
|
114012
|
+
async function fetchTemplateContent({ huggingFaceToken, override }) {
|
|
114013
|
+
const accessToken = huggingFaceToken ?? process.env.HF_TOKEN ?? undefined;
|
|
114014
|
+
const filePath = override.filePath || CHAT_TEMPLATE_DEFAULT_FILE_PATH;
|
|
114015
|
+
const blob = await downloadFile({
|
|
114016
|
+
accessToken,
|
|
114017
|
+
path: filePath,
|
|
114018
|
+
repo: override.repo
|
|
114019
|
+
});
|
|
114020
|
+
if (!blob) {
|
|
114021
|
+
throw new Error(`Chat template file not found: ${override.repo}/${filePath}`);
|
|
114022
|
+
}
|
|
114023
|
+
const content = await blob.text();
|
|
114024
|
+
if (!content.trim()) {
|
|
114025
|
+
throw new Error(`Chat template file is empty: ${override.repo}/${filePath}`);
|
|
114026
|
+
}
|
|
114027
|
+
return content;
|
|
114028
|
+
}
|
|
114029
|
+
/**
|
|
114030
|
+
* Materializes the model's chat template override into the model directory:
|
|
114031
|
+
* - Always writes the canonical copy for flag-based engines.
|
|
114032
|
+
* - For engines that read the model directory (exllamav3, mlx-lm), also writes
|
|
114033
|
+
* the transformers-style `chat_template.jinja` drop-in.
|
|
114034
|
+
* - When no override is configured, removes any previously materialized files,
|
|
114035
|
+
* restoring the model repo's own `chat_template.jinja` if we replaced it.
|
|
114036
|
+
*/
|
|
114037
|
+
async function materializeChatTemplate({ engine, huggingFaceToken, model, targetDirectory }) {
|
|
114038
|
+
const override = model.chatTemplate ?? null;
|
|
114039
|
+
const canonicalPath = getChatTemplateLocalPath(targetDirectory);
|
|
114040
|
+
const dropInPath = path$1.join(targetDirectory, CHAT_TEMPLATE_DEFAULT_FILE_PATH);
|
|
114041
|
+
if (!override) {
|
|
114042
|
+
const markerPath = `${canonicalPath}.override`;
|
|
114043
|
+
if (require$$3$4.existsSync(markerPath)) {
|
|
114044
|
+
await require$$0$m.rm(dropInPath, { force: true });
|
|
114045
|
+
await require$$0$m.rm(markerPath, { force: true });
|
|
114046
|
+
if (model.source.type === "huggingface") {
|
|
114047
|
+
await restoreOriginalTemplate({
|
|
114048
|
+
huggingFaceToken,
|
|
114049
|
+
modelSlug: model.source.slug,
|
|
114050
|
+
targetDirectory
|
|
114051
|
+
});
|
|
114052
|
+
}
|
|
114053
|
+
}
|
|
114054
|
+
await require$$0$m.rm(canonicalPath, { force: true });
|
|
114055
|
+
return;
|
|
114056
|
+
}
|
|
114057
|
+
const content = override.type === "inline"
|
|
114058
|
+
? override.content
|
|
114059
|
+
: await fetchTemplateContent({ huggingFaceToken, override });
|
|
114060
|
+
await require$$0$m.mkdir(targetDirectory, { recursive: true });
|
|
114061
|
+
await require$$0$m.writeFile(canonicalPath, content, "utf8");
|
|
114062
|
+
if (DIR_BASED_ENGINES.has(engine)) {
|
|
114063
|
+
await require$$0$m.writeFile(dropInPath, content, "utf8");
|
|
114064
|
+
await require$$0$m.writeFile(`${canonicalPath}.override`, "1", "utf8");
|
|
114065
|
+
}
|
|
114066
|
+
}
|
|
114067
|
+
async function restoreOriginalTemplate({ huggingFaceToken, modelSlug, targetDirectory }) {
|
|
114068
|
+
const accessToken = huggingFaceToken ?? process.env.HF_TOKEN ?? undefined;
|
|
114069
|
+
try {
|
|
114070
|
+
const blob = await downloadFile({
|
|
114071
|
+
accessToken,
|
|
114072
|
+
path: CHAT_TEMPLATE_DEFAULT_FILE_PATH,
|
|
114073
|
+
repo: modelSlug.split(":")[0].split("@")[0]
|
|
114074
|
+
});
|
|
114075
|
+
if (blob) {
|
|
114076
|
+
const content = await blob.text();
|
|
114077
|
+
if (content.trim()) {
|
|
114078
|
+
await require$$0$m.writeFile(path$1.join(targetDirectory, CHAT_TEMPLATE_DEFAULT_FILE_PATH), content, "utf8");
|
|
114079
|
+
}
|
|
114080
|
+
}
|
|
114081
|
+
}
|
|
114082
|
+
catch (error) {
|
|
114083
|
+
console.warn("[chatTemplate] Failed to restore original chat_template.jinja after override removal:", asError(error).message);
|
|
114084
|
+
}
|
|
114085
|
+
}
|
|
114086
|
+
/**
|
|
114087
|
+
* CLI arguments applying the materialized chat template for flag-based engines.
|
|
114088
|
+
* Returns an empty array when no override exists, the engine applies templates
|
|
114089
|
+
* from the model directory, or the engine does not support overrides.
|
|
114090
|
+
*/
|
|
114091
|
+
async function getChatTemplateEngineArgs({ engine, model, targetDirectory }) {
|
|
114092
|
+
if (!model.chatTemplate)
|
|
114093
|
+
return [];
|
|
114094
|
+
const flag = FLAG_BASED_ENGINE_ARGS[engine];
|
|
114095
|
+
if (!flag) {
|
|
114096
|
+
if (engine === "tensorrt-llm") {
|
|
114097
|
+
console.warn("[chatTemplate] TensorRT-LLM does not support chat template overrides; ignoring");
|
|
114098
|
+
}
|
|
114099
|
+
return [];
|
|
114100
|
+
}
|
|
114101
|
+
const templatePath = getChatTemplateLocalPath(targetDirectory);
|
|
114102
|
+
if (!require$$3$4.existsSync(templatePath)) {
|
|
114103
|
+
console.warn(`[chatTemplate] Template file missing for ${engine}; continuing with embedded template`);
|
|
114104
|
+
return [];
|
|
114105
|
+
}
|
|
114106
|
+
return [flag, templatePath];
|
|
114107
|
+
}
|
|
114108
|
+
/**
|
|
114109
|
+
* Post-start verification for llama.cpp: compares the template the server
|
|
114110
|
+
* reports via `/props` against the materialized override file. Returns a
|
|
114111
|
+
* warning message on mismatch, or null when the template applied cleanly
|
|
114112
|
+
* (or verification is not applicable).
|
|
114113
|
+
*/
|
|
114114
|
+
async function verifyEngineChatTemplate({ engine, enginePort, logger, model, targetDirectory }) {
|
|
114115
|
+
if (!model.chatTemplate || engine !== "llama.cpp")
|
|
114116
|
+
return null;
|
|
114117
|
+
try {
|
|
114118
|
+
const templatePath = getChatTemplateLocalPath(targetDirectory);
|
|
114119
|
+
if (!require$$3$4.existsSync(templatePath)) {
|
|
114120
|
+
return "Chat template override file missing on disk";
|
|
114121
|
+
}
|
|
114122
|
+
const [propsResponse, expected] = await Promise.all([
|
|
114123
|
+
fetch(`http://localhost:${enginePort}/props`, {
|
|
114124
|
+
signal: AbortSignal.timeout(5000)
|
|
114125
|
+
}),
|
|
114126
|
+
require$$0$m.readFile(templatePath, "utf8")
|
|
114127
|
+
]);
|
|
114128
|
+
if (!propsResponse.ok) {
|
|
114129
|
+
return `Chat template verification unavailable: /props returned ${propsResponse.status}`;
|
|
114130
|
+
}
|
|
114131
|
+
const props = (await propsResponse.json());
|
|
114132
|
+
const served = typeof props.chat_template === "string" ? props.chat_template.trim() : "";
|
|
114133
|
+
if (served !== expected.trim()) {
|
|
114134
|
+
return "Chat template override did not apply: served template differs from configured template";
|
|
114135
|
+
}
|
|
114136
|
+
return null;
|
|
114137
|
+
}
|
|
114138
|
+
catch (error) {
|
|
114139
|
+
logger.warn("Chat template verification failed", {
|
|
114140
|
+
error: asError(error)
|
|
114141
|
+
});
|
|
114142
|
+
return null;
|
|
114143
|
+
}
|
|
114144
|
+
}
|
|
114145
|
+
|
|
114146
|
+
const SECRET_FLAGS = new Set([
|
|
114147
|
+
"api-key",
|
|
114148
|
+
"auth-token",
|
|
114149
|
+
"hf-token",
|
|
114150
|
+
"key",
|
|
114151
|
+
"password",
|
|
114152
|
+
"secret",
|
|
114153
|
+
"token"
|
|
114154
|
+
]);
|
|
114155
|
+
function redactSecretArgs(args) {
|
|
114156
|
+
return args.map((arg, index) => {
|
|
114157
|
+
const equalsIndex = arg.indexOf("=");
|
|
114158
|
+
if (arg.startsWith("--") && equalsIndex > 0) {
|
|
114159
|
+
const flag = arg.slice(2, equalsIndex);
|
|
114160
|
+
if (SECRET_FLAGS.has(flag)) {
|
|
114161
|
+
return `${arg.slice(0, equalsIndex + 1)}***`;
|
|
114162
|
+
}
|
|
114163
|
+
}
|
|
114164
|
+
const previous = args[index - 1];
|
|
114165
|
+
if (previous &&
|
|
114166
|
+
previous.startsWith("--") &&
|
|
114167
|
+
!previous.includes("=") &&
|
|
114168
|
+
SECRET_FLAGS.has(previous.slice(2))) {
|
|
114169
|
+
return "***";
|
|
114170
|
+
}
|
|
114171
|
+
return arg;
|
|
114172
|
+
});
|
|
114173
|
+
}
|
|
114174
|
+
async function createEngineProcess({ args, bin, logger }) {
|
|
114175
|
+
logger.info("Starting engine process", {
|
|
114176
|
+
command: { args: redactSecretArgs(args), bin }
|
|
114177
|
+
});
|
|
114178
|
+
const processManager = new ProcessManager({ args, command: bin });
|
|
114179
|
+
await processManager.start();
|
|
114180
|
+
return processManager;
|
|
114181
|
+
}
|
|
114182
|
+
|
|
114183
|
+
const balanced = (a, b, str) => {
|
|
114184
|
+
const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
|
|
114185
|
+
const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
|
|
114186
|
+
const r = ma !== null && mb != null && range(ma, mb, str);
|
|
114187
|
+
return (r && {
|
|
114188
|
+
start: r[0],
|
|
114189
|
+
end: r[1],
|
|
114190
|
+
pre: str.slice(0, r[0]),
|
|
114191
|
+
body: str.slice(r[0] + ma.length, r[1]),
|
|
114192
|
+
post: str.slice(r[1] + mb.length),
|
|
114193
|
+
});
|
|
114194
|
+
};
|
|
114195
|
+
const maybeMatch = (reg, str) => {
|
|
114196
|
+
const m = str.match(reg);
|
|
114197
|
+
return m ? m[0] : null;
|
|
114198
|
+
};
|
|
114199
|
+
const range = (a, b, str) => {
|
|
114200
|
+
let begs, beg, left, right = undefined, result;
|
|
114201
|
+
let ai = str.indexOf(a);
|
|
114202
|
+
let bi = str.indexOf(b, ai + 1);
|
|
114203
|
+
let i = ai;
|
|
114204
|
+
if (ai >= 0 && bi > 0) {
|
|
114205
|
+
if (a === b) {
|
|
114206
|
+
return [ai, bi];
|
|
114207
|
+
}
|
|
114208
|
+
begs = [];
|
|
114209
|
+
left = str.length;
|
|
114210
|
+
while (i >= 0 && !result) {
|
|
114211
|
+
if (i === ai) {
|
|
114212
|
+
begs.push(i);
|
|
114213
|
+
ai = str.indexOf(a, i + 1);
|
|
114214
|
+
}
|
|
114215
|
+
else if (begs.length === 1) {
|
|
114216
|
+
const r = begs.pop();
|
|
114217
|
+
if (r !== undefined)
|
|
114218
|
+
result = [r, bi];
|
|
114219
|
+
}
|
|
114220
|
+
else {
|
|
114221
|
+
beg = begs.pop();
|
|
114222
|
+
if (beg !== undefined && beg < left) {
|
|
114223
|
+
left = beg;
|
|
114224
|
+
right = bi;
|
|
114225
|
+
}
|
|
114226
|
+
bi = str.indexOf(b, i + 1);
|
|
114227
|
+
}
|
|
114228
|
+
i = ai < bi && ai >= 0 ? ai : bi;
|
|
114229
|
+
}
|
|
114230
|
+
if (begs.length && right !== undefined) {
|
|
114231
|
+
result = [left, right];
|
|
114232
|
+
}
|
|
114233
|
+
}
|
|
114234
|
+
return result;
|
|
114235
|
+
};
|
|
114236
|
+
|
|
114237
|
+
const escSlash = '\0SLASH' + Math.random() + '\0';
|
|
114238
|
+
const escOpen = '\0OPEN' + Math.random() + '\0';
|
|
114239
|
+
const escClose = '\0CLOSE' + Math.random() + '\0';
|
|
114240
|
+
const escComma = '\0COMMA' + Math.random() + '\0';
|
|
114241
|
+
const escPeriod = '\0PERIOD' + Math.random() + '\0';
|
|
114242
|
+
const escSlashPattern = new RegExp(escSlash, 'g');
|
|
114243
|
+
const escOpenPattern = new RegExp(escOpen, 'g');
|
|
114244
|
+
const escClosePattern = new RegExp(escClose, 'g');
|
|
114245
|
+
const escCommaPattern = new RegExp(escComma, 'g');
|
|
114246
|
+
const escPeriodPattern = new RegExp(escPeriod, 'g');
|
|
114247
|
+
const slashPattern = /\\\\/g;
|
|
114248
|
+
const openPattern = /\\{/g;
|
|
114249
|
+
const closePattern = /\\}/g;
|
|
114250
|
+
const commaPattern = /\\,/g;
|
|
114251
|
+
const periodPattern = /\\\./g;
|
|
114252
|
+
const EXPANSION_MAX = 100_000;
|
|
114253
|
+
// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
|
|
114254
|
+
// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
|
|
114255
|
+
// truncated to 100k results - while making every result ~1500 characters
|
|
114256
|
+
// long. The result set, and the intermediate arrays built while combining
|
|
114257
|
+
// brace sets, then grow large enough to exhaust memory and crash the process
|
|
114258
|
+
// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
|
|
114259
|
+
// characters the accumulator may hold at any point, so memory stays flat no
|
|
114260
|
+
// matter how many brace groups are chained. The limit sits well above any
|
|
114261
|
+
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
|
114262
|
+
// characters) so legitimate input is unaffected.
|
|
114263
|
+
const EXPANSION_MAX_LENGTH = 4_000_000;
|
|
114264
|
+
function numeric(str) {
|
|
114265
|
+
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
|
114266
|
+
}
|
|
114267
|
+
function escapeBraces(str) {
|
|
114268
|
+
return str
|
|
114269
|
+
.replace(slashPattern, escSlash)
|
|
114270
|
+
.replace(openPattern, escOpen)
|
|
114271
|
+
.replace(closePattern, escClose)
|
|
114272
|
+
.replace(commaPattern, escComma)
|
|
114273
|
+
.replace(periodPattern, escPeriod);
|
|
114274
|
+
}
|
|
114275
|
+
function unescapeBraces(str) {
|
|
114276
|
+
return str
|
|
114277
|
+
.replace(escSlashPattern, '\\')
|
|
114278
|
+
.replace(escOpenPattern, '{')
|
|
114279
|
+
.replace(escClosePattern, '}')
|
|
114280
|
+
.replace(escCommaPattern, ',')
|
|
114281
|
+
.replace(escPeriodPattern, '.');
|
|
114282
|
+
}
|
|
114283
|
+
/**
|
|
114284
|
+
* Basically just str.split(","), but handling cases
|
|
114285
|
+
* where we have nested braced sections, which should be
|
|
114286
|
+
* treated as individual members, like {a,{b,c},d}
|
|
114287
|
+
*/
|
|
114288
|
+
function parseCommaParts(str) {
|
|
114289
|
+
if (!str) {
|
|
114290
|
+
return [''];
|
|
114291
|
+
}
|
|
114292
|
+
const parts = [];
|
|
114293
|
+
const m = balanced('{', '}', str);
|
|
114294
|
+
if (!m) {
|
|
114295
|
+
return str.split(',');
|
|
114296
|
+
}
|
|
114297
|
+
const { pre, body, post } = m;
|
|
114298
|
+
const p = pre.split(',');
|
|
114299
|
+
p[p.length - 1] += '{' + body + '}';
|
|
114300
|
+
const postParts = parseCommaParts(post);
|
|
114301
|
+
if (post.length) {
|
|
114302
|
+
p[p.length - 1] += postParts.shift();
|
|
114303
|
+
p.push.apply(p, postParts);
|
|
114304
|
+
}
|
|
114305
|
+
parts.push.apply(parts, p);
|
|
114306
|
+
return parts;
|
|
114307
|
+
}
|
|
114308
|
+
function expand(str, options = {}) {
|
|
114309
|
+
if (!str) {
|
|
114310
|
+
return [];
|
|
114311
|
+
}
|
|
114312
|
+
const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options;
|
|
114313
|
+
// I don't know why Bash 4.3 does this, but it does.
|
|
114314
|
+
// Anything starting with {} will have the first two bytes preserved
|
|
114315
|
+
// but *only* at the top level, so {},a}b will not expand to anything,
|
|
114316
|
+
// but a{},b}c will be expanded to [a}c,abc].
|
|
114317
|
+
// One could argue that this is a bug in Bash, but since the goal of
|
|
114318
|
+
// this module is to match Bash's rules, we escape a leading {}
|
|
114319
|
+
if (str.slice(0, 2) === '{}') {
|
|
114320
|
+
str = '\\{\\}' + str.slice(2);
|
|
114321
|
+
}
|
|
114322
|
+
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
|
114323
|
+
}
|
|
114324
|
+
function embrace(str) {
|
|
114325
|
+
return '{' + str + '}';
|
|
114326
|
+
}
|
|
114327
|
+
function isPadded(el) {
|
|
114328
|
+
return /^-?0\d/.test(el);
|
|
114329
|
+
}
|
|
114330
|
+
function lte(i, y) {
|
|
114331
|
+
return i <= y;
|
|
114332
|
+
}
|
|
114333
|
+
function gte(i, y) {
|
|
114334
|
+
return i >= y;
|
|
114335
|
+
}
|
|
114336
|
+
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
|
|
114337
|
+
// number of results at `max` and the total number of characters at `maxLength`.
|
|
114338
|
+
// This is the one place output grows, so bounding it here keeps the single
|
|
114339
|
+
// accumulator - and therefore memory - flat regardless of how many brace groups
|
|
114340
|
+
// are combined (CVE-2026-14257).
|
|
114341
|
+
function combine(acc, pre, values, max, maxLength, dropEmpties) {
|
|
114342
|
+
const out = [];
|
|
114343
|
+
let length = 0;
|
|
114344
|
+
for (let a = 0; a < acc.length; a++) {
|
|
114345
|
+
for (let v = 0; v < values.length; v++) {
|
|
114346
|
+
if (out.length >= max)
|
|
114347
|
+
return out;
|
|
114348
|
+
const expansion = acc[a] + pre + values[v];
|
|
114349
|
+
// Bash drops empty results at the top level. Skip them before they count
|
|
114350
|
+
// against `max`, so `max` bounds the number of *kept* results.
|
|
114351
|
+
if (dropEmpties && !expansion)
|
|
114352
|
+
continue;
|
|
114353
|
+
if (length + expansion.length > maxLength)
|
|
114354
|
+
return out;
|
|
114355
|
+
out.push(expansion);
|
|
114356
|
+
length += expansion.length;
|
|
114357
|
+
}
|
|
114358
|
+
}
|
|
114359
|
+
return out;
|
|
114360
|
+
}
|
|
114361
|
+
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
|
|
114362
|
+
// sequence body.
|
|
114363
|
+
function expandSequence(body, isAlphaSequence, max, maxLength) {
|
|
114364
|
+
const n = body.split(/\.\./);
|
|
114365
|
+
const N = [];
|
|
114366
|
+
// A sequence body always splits into two or three parts, but the compiler
|
|
114367
|
+
// can't know that.
|
|
114368
|
+
/* c8 ignore start */
|
|
114369
|
+
if (n[0] === undefined || n[1] === undefined) {
|
|
114370
|
+
return N;
|
|
114371
|
+
}
|
|
114372
|
+
/* c8 ignore stop */
|
|
114373
|
+
const x = numeric(n[0]);
|
|
114374
|
+
const y = numeric(n[1]);
|
|
114375
|
+
const width = Math.max(n[0].length, n[1].length);
|
|
114376
|
+
let incr = n.length === 3 && n[2] !== undefined ?
|
|
114377
|
+
Math.max(Math.abs(numeric(n[2])), 1)
|
|
114378
|
+
: 1;
|
|
114379
|
+
let test = lte;
|
|
114380
|
+
const reverse = y < x;
|
|
114381
|
+
if (reverse) {
|
|
114382
|
+
incr *= -1;
|
|
114383
|
+
test = gte;
|
|
114384
|
+
}
|
|
114385
|
+
const pad = n.some(isPadded);
|
|
114386
|
+
let length = 0;
|
|
114387
|
+
for (let i = x; test(i, y) && N.length < max; i += incr) {
|
|
114388
|
+
let c;
|
|
114389
|
+
if (isAlphaSequence) {
|
|
114390
|
+
c = String.fromCharCode(i);
|
|
114391
|
+
if (c === '\\') {
|
|
114392
|
+
c = '';
|
|
114393
|
+
}
|
|
114394
|
+
}
|
|
114395
|
+
else {
|
|
114396
|
+
c = String(i);
|
|
114397
|
+
if (pad) {
|
|
114398
|
+
const need = width - c.length;
|
|
114399
|
+
if (need > 0) {
|
|
114400
|
+
const z = new Array(need + 1).join('0');
|
|
114401
|
+
if (i < 0) {
|
|
114402
|
+
c = '-' + z + c.slice(1);
|
|
114403
|
+
}
|
|
114404
|
+
else {
|
|
114405
|
+
c = z + c;
|
|
114406
|
+
}
|
|
114407
|
+
}
|
|
114408
|
+
}
|
|
114409
|
+
}
|
|
114410
|
+
if (length + c.length > maxLength)
|
|
114411
|
+
break;
|
|
114412
|
+
N.push(c);
|
|
114413
|
+
length += c.length;
|
|
114414
|
+
}
|
|
114415
|
+
return N;
|
|
114416
|
+
}
|
|
114417
|
+
function expand_(str, max, maxLength, isTop) {
|
|
114418
|
+
// Consume the string's top-level brace groups left to right, threading a
|
|
114419
|
+
// running set of combined prefixes (`acc`). Expanding the tail iteratively -
|
|
114420
|
+
// rather than recursing on `m.post` once per group - keeps the native stack
|
|
114421
|
+
// depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no
|
|
114422
|
+
// longer overflow the stack, and leaves a single accumulator whose size
|
|
114423
|
+
// `maxLength` bounds directly (CVE-2026-14257).
|
|
114424
|
+
let acc = [''];
|
|
114425
|
+
// Bash drops empty results, but only when the *first* top-level group is a
|
|
114426
|
+
// comma set - a sequence like `{a..\}` may legitimately yield ''. The drop
|
|
114427
|
+
// is on the final strings, so it is applied to whichever `combine` produces
|
|
114428
|
+
// them (the one with no brace set left in the tail).
|
|
114429
|
+
let dropEmpties = false;
|
|
114430
|
+
let firstGroup = true;
|
|
114431
|
+
for (;;) {
|
|
114432
|
+
const m = balanced('{', '}', str);
|
|
114433
|
+
// No brace set left: the rest of the string is literal.
|
|
114434
|
+
if (!m) {
|
|
114435
|
+
return combine(acc, str, [''], max, maxLength, dropEmpties);
|
|
114436
|
+
}
|
|
114437
|
+
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
114438
|
+
const pre = m.pre;
|
|
114439
|
+
if (/\$$/.test(pre)) {
|
|
114440
|
+
acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
|
|
114441
|
+
firstGroup = false;
|
|
114442
|
+
if (!m.post.length)
|
|
114443
|
+
break;
|
|
114444
|
+
str = m.post;
|
|
114445
|
+
continue;
|
|
114446
|
+
}
|
|
114447
|
+
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
114448
|
+
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
114449
|
+
const isSequence = isNumericSequence || isAlphaSequence;
|
|
114450
|
+
const isOptions = m.body.indexOf(',') >= 0;
|
|
114451
|
+
if (!isSequence && !isOptions) {
|
|
114452
|
+
// {a},b}
|
|
114453
|
+
if (m.post.match(/,(?!,).*\}/)) {
|
|
114454
|
+
str = m.pre + '{' + m.body + escClose + m.post;
|
|
114455
|
+
isTop = true;
|
|
114456
|
+
continue;
|
|
114457
|
+
}
|
|
114458
|
+
// Nothing here expands, so the whole remaining string is literal.
|
|
114459
|
+
return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
|
|
114460
|
+
}
|
|
114461
|
+
if (firstGroup) {
|
|
114462
|
+
dropEmpties = isTop && !isSequence;
|
|
114463
|
+
firstGroup = false;
|
|
114464
|
+
}
|
|
114465
|
+
let values;
|
|
114466
|
+
if (isSequence) {
|
|
114467
|
+
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
|
|
114468
|
+
}
|
|
114469
|
+
else {
|
|
114470
|
+
let n = parseCommaParts(m.body);
|
|
114471
|
+
if (n.length === 1 && n[0] !== undefined) {
|
|
114472
|
+
// x{{a,b}}y ==> x{a}y x{b}y
|
|
114473
|
+
n = expand_(n[0], max, maxLength, false).map(embrace);
|
|
114474
|
+
//XXX is this necessary? Can't seem to hit it in tests.
|
|
114475
|
+
/* c8 ignore start */
|
|
114476
|
+
if (n.length === 1) {
|
|
114477
|
+
acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
|
|
114478
|
+
if (!m.post.length)
|
|
114479
|
+
break;
|
|
114480
|
+
str = m.post;
|
|
114481
|
+
continue;
|
|
114482
|
+
}
|
|
114483
|
+
/* c8 ignore stop */
|
|
114484
|
+
}
|
|
114485
|
+
// Values that `combine` is going to drop as empty produce no result, so
|
|
114486
|
+
// they must not count against `max` - otherwise `{a,,b}` with `max: 2`
|
|
114487
|
+
// would stop at `['a', '']` and yield one result instead of two. Skipping
|
|
114488
|
+
// them outright keeps `values` bounded while leaving `max` a bound on
|
|
114489
|
+
// *kept* results.
|
|
114490
|
+
let dropsEmpties = dropEmpties && !m.post.length && !pre;
|
|
114491
|
+
for (let d = 0; dropsEmpties && d < acc.length; d++) {
|
|
114492
|
+
if (acc[d]) {
|
|
114493
|
+
dropsEmpties = false;
|
|
114494
|
+
}
|
|
114495
|
+
}
|
|
114496
|
+
values = [];
|
|
114497
|
+
let valuesLength = 0;
|
|
114498
|
+
outer: for (let j = 0; j < n.length; j++) {
|
|
114499
|
+
const expanded = expand_(n[j], max, maxLength, false);
|
|
114500
|
+
for (let k = 0; k < expanded.length; k++) {
|
|
114501
|
+
const v = expanded[k];
|
|
114502
|
+
if (dropsEmpties && !v)
|
|
114503
|
+
continue;
|
|
114504
|
+
if (values.length >= max || valuesLength + v.length > maxLength) {
|
|
114505
|
+
break outer;
|
|
114506
|
+
}
|
|
114507
|
+
values.push(v);
|
|
114508
|
+
valuesLength += v.length;
|
|
114509
|
+
}
|
|
114510
|
+
}
|
|
114511
|
+
}
|
|
114512
|
+
acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
|
|
114513
|
+
if (!m.post.length)
|
|
114514
|
+
break;
|
|
114515
|
+
str = m.post;
|
|
114516
|
+
}
|
|
114517
|
+
return acc;
|
|
114518
|
+
}
|
|
114519
|
+
|
|
114520
|
+
const MAX_PATTERN_LENGTH = 1024 * 64;
|
|
114521
|
+
const assertValidPattern = (pattern) => {
|
|
114522
|
+
if (typeof pattern !== 'string') {
|
|
114523
|
+
throw new TypeError('invalid pattern');
|
|
114524
|
+
}
|
|
114525
|
+
if (pattern.length > MAX_PATTERN_LENGTH) {
|
|
114526
|
+
throw new TypeError('pattern is too long');
|
|
114527
|
+
}
|
|
114528
|
+
};
|
|
114529
|
+
|
|
114530
|
+
// translate the various posix character classes into unicode properties
|
|
114531
|
+
// this works across all unicode locales
|
|
114532
|
+
// { <posix class>: [<translation>, /u flag required, negated]
|
|
114533
|
+
const posixClasses = {
|
|
114534
|
+
'[:alnum:]': ['\\p{L}\\p{Nl}\\p{Nd}', true],
|
|
114535
|
+
'[:alpha:]': ['\\p{L}\\p{Nl}', true],
|
|
114536
|
+
'[:ascii:]': ['\\x' + '00-\\x' + '7f', false],
|
|
114537
|
+
'[:blank:]': ['\\p{Zs}\\t', true],
|
|
114538
|
+
'[:cntrl:]': ['\\p{Cc}', true],
|
|
114539
|
+
'[:digit:]': ['\\p{Nd}', true],
|
|
114540
|
+
'[:graph:]': ['\\p{Z}\\p{C}', true, true],
|
|
114541
|
+
'[:lower:]': ['\\p{Ll}', true],
|
|
114542
|
+
'[:print:]': ['\\p{C}', true],
|
|
114543
|
+
'[:punct:]': ['\\p{P}', true],
|
|
114544
|
+
'[:space:]': ['\\p{Z}\\t\\r\\n\\v\\f', true],
|
|
114545
|
+
'[:upper:]': ['\\p{Lu}', true],
|
|
114546
|
+
'[:word:]': ['\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}', true],
|
|
114547
|
+
'[:xdigit:]': ['A-Fa-f0-9', false],
|
|
114548
|
+
};
|
|
114549
|
+
// only need to escape a few things inside of brace expressions
|
|
114550
|
+
// escapes: [ \ ] -
|
|
114551
|
+
const braceEscape = (s) => s.replace(/[[\]\\-]/g, '\\$&');
|
|
114552
|
+
// escape all regexp magic characters
|
|
113402
114553
|
const regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
|
113403
114554
|
// everything has already been escaped, we just have to join
|
|
113404
114555
|
const rangesToString = (ranges) => ranges.join('');
|
|
@@ -120982,1551 +122133,491 @@ class GlobUtil {
|
|
|
120982
122133
|
cb();
|
|
120983
122134
|
};
|
|
120984
122135
|
for (const [m, absolute, ifDir] of processor.matches.entries()) {
|
|
120985
|
-
if (this.#ignored(m))
|
|
120986
|
-
continue;
|
|
120987
|
-
this.matchSync(m, absolute, ifDir);
|
|
120988
|
-
}
|
|
120989
|
-
for (const [target, patterns] of processor.subwalks.entries()) {
|
|
120990
|
-
tasks++;
|
|
120991
|
-
this.walkCB2Sync(target, patterns, processor.child(), next);
|
|
120992
|
-
}
|
|
120993
|
-
next();
|
|
120994
|
-
}
|
|
120995
|
-
}
|
|
120996
|
-
class GlobWalker extends GlobUtil {
|
|
120997
|
-
matches = new Set();
|
|
120998
|
-
constructor(patterns, path, opts) {
|
|
120999
|
-
super(patterns, path, opts);
|
|
121000
|
-
}
|
|
121001
|
-
matchEmit(e) {
|
|
121002
|
-
this.matches.add(e);
|
|
121003
|
-
}
|
|
121004
|
-
async walk() {
|
|
121005
|
-
if (this.signal?.aborted)
|
|
121006
|
-
throw this.signal.reason;
|
|
121007
|
-
if (this.path.isUnknown()) {
|
|
121008
|
-
await this.path.lstat();
|
|
121009
|
-
}
|
|
121010
|
-
await new Promise((res, rej) => {
|
|
121011
|
-
this.walkCB(this.path, this.patterns, () => {
|
|
121012
|
-
if (this.signal?.aborted) {
|
|
121013
|
-
rej(this.signal.reason);
|
|
121014
|
-
}
|
|
121015
|
-
else {
|
|
121016
|
-
res(this.matches);
|
|
121017
|
-
}
|
|
121018
|
-
});
|
|
121019
|
-
});
|
|
121020
|
-
return this.matches;
|
|
121021
|
-
}
|
|
121022
|
-
walkSync() {
|
|
121023
|
-
if (this.signal?.aborted)
|
|
121024
|
-
throw this.signal.reason;
|
|
121025
|
-
if (this.path.isUnknown()) {
|
|
121026
|
-
this.path.lstatSync();
|
|
121027
|
-
}
|
|
121028
|
-
// nothing for the callback to do, because this never pauses
|
|
121029
|
-
this.walkCBSync(this.path, this.patterns, () => {
|
|
121030
|
-
if (this.signal?.aborted)
|
|
121031
|
-
throw this.signal.reason;
|
|
121032
|
-
});
|
|
121033
|
-
return this.matches;
|
|
121034
|
-
}
|
|
121035
|
-
}
|
|
121036
|
-
class GlobStream extends GlobUtil {
|
|
121037
|
-
results;
|
|
121038
|
-
constructor(patterns, path, opts) {
|
|
121039
|
-
super(patterns, path, opts);
|
|
121040
|
-
this.results = new Minipass({
|
|
121041
|
-
signal: this.signal,
|
|
121042
|
-
objectMode: true,
|
|
121043
|
-
});
|
|
121044
|
-
this.results.on('drain', () => this.resume());
|
|
121045
|
-
this.results.on('resume', () => this.resume());
|
|
121046
|
-
}
|
|
121047
|
-
matchEmit(e) {
|
|
121048
|
-
this.results.write(e);
|
|
121049
|
-
if (!this.results.flowing)
|
|
121050
|
-
this.pause();
|
|
121051
|
-
}
|
|
121052
|
-
stream() {
|
|
121053
|
-
const target = this.path;
|
|
121054
|
-
if (target.isUnknown()) {
|
|
121055
|
-
target.lstat().then(() => {
|
|
121056
|
-
this.walkCB(target, this.patterns, () => this.results.end());
|
|
121057
|
-
});
|
|
121058
|
-
}
|
|
121059
|
-
else {
|
|
121060
|
-
this.walkCB(target, this.patterns, () => this.results.end());
|
|
121061
|
-
}
|
|
121062
|
-
return this.results;
|
|
121063
|
-
}
|
|
121064
|
-
streamSync() {
|
|
121065
|
-
if (this.path.isUnknown()) {
|
|
121066
|
-
this.path.lstatSync();
|
|
121067
|
-
}
|
|
121068
|
-
this.walkCBSync(this.path, this.patterns, () => this.results.end());
|
|
121069
|
-
return this.results;
|
|
121070
|
-
}
|
|
121071
|
-
}
|
|
121072
|
-
|
|
121073
|
-
// if no process global, just call it linux.
|
|
121074
|
-
// so we default to case-sensitive, / separators
|
|
121075
|
-
const defaultPlatform = (typeof process === 'object' &&
|
|
121076
|
-
process &&
|
|
121077
|
-
typeof process.platform === 'string') ?
|
|
121078
|
-
process.platform
|
|
121079
|
-
: 'linux';
|
|
121080
|
-
/**
|
|
121081
|
-
* An object that can perform glob pattern traversals.
|
|
121082
|
-
*/
|
|
121083
|
-
class Glob {
|
|
121084
|
-
absolute;
|
|
121085
|
-
cwd;
|
|
121086
|
-
root;
|
|
121087
|
-
dot;
|
|
121088
|
-
dotRelative;
|
|
121089
|
-
follow;
|
|
121090
|
-
ignore;
|
|
121091
|
-
magicalBraces;
|
|
121092
|
-
mark;
|
|
121093
|
-
matchBase;
|
|
121094
|
-
maxDepth;
|
|
121095
|
-
nobrace;
|
|
121096
|
-
nocase;
|
|
121097
|
-
nodir;
|
|
121098
|
-
noext;
|
|
121099
|
-
noglobstar;
|
|
121100
|
-
pattern;
|
|
121101
|
-
platform;
|
|
121102
|
-
realpath;
|
|
121103
|
-
scurry;
|
|
121104
|
-
stat;
|
|
121105
|
-
signal;
|
|
121106
|
-
windowsPathsNoEscape;
|
|
121107
|
-
withFileTypes;
|
|
121108
|
-
includeChildMatches;
|
|
121109
|
-
/**
|
|
121110
|
-
* The options provided to the constructor.
|
|
121111
|
-
*/
|
|
121112
|
-
opts;
|
|
121113
|
-
/**
|
|
121114
|
-
* An array of parsed immutable {@link Pattern} objects.
|
|
121115
|
-
*/
|
|
121116
|
-
patterns;
|
|
121117
|
-
/**
|
|
121118
|
-
* All options are stored as properties on the `Glob` object.
|
|
121119
|
-
*
|
|
121120
|
-
* See {@link GlobOptions} for full options descriptions.
|
|
121121
|
-
*
|
|
121122
|
-
* Note that a previous `Glob` object can be passed as the
|
|
121123
|
-
* `GlobOptions` to another `Glob` instantiation to re-use settings
|
|
121124
|
-
* and caches with a new pattern.
|
|
121125
|
-
*
|
|
121126
|
-
* Traversal functions can be called multiple times to run the walk
|
|
121127
|
-
* again.
|
|
121128
|
-
*/
|
|
121129
|
-
constructor(pattern, opts) {
|
|
121130
|
-
/* c8 ignore start */
|
|
121131
|
-
if (!opts)
|
|
121132
|
-
throw new TypeError('glob options required');
|
|
121133
|
-
/* c8 ignore stop */
|
|
121134
|
-
this.withFileTypes = !!opts.withFileTypes;
|
|
121135
|
-
this.signal = opts.signal;
|
|
121136
|
-
this.follow = !!opts.follow;
|
|
121137
|
-
this.dot = !!opts.dot;
|
|
121138
|
-
this.dotRelative = !!opts.dotRelative;
|
|
121139
|
-
this.nodir = !!opts.nodir;
|
|
121140
|
-
this.mark = !!opts.mark;
|
|
121141
|
-
if (!opts.cwd) {
|
|
121142
|
-
this.cwd = '';
|
|
121143
|
-
}
|
|
121144
|
-
else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) {
|
|
121145
|
-
opts.cwd = require$$0$l.fileURLToPath(opts.cwd);
|
|
121146
|
-
}
|
|
121147
|
-
this.cwd = opts.cwd || '';
|
|
121148
|
-
this.root = opts.root;
|
|
121149
|
-
this.magicalBraces = !!opts.magicalBraces;
|
|
121150
|
-
this.nobrace = !!opts.nobrace;
|
|
121151
|
-
this.noext = !!opts.noext;
|
|
121152
|
-
this.realpath = !!opts.realpath;
|
|
121153
|
-
this.absolute = opts.absolute;
|
|
121154
|
-
this.includeChildMatches = opts.includeChildMatches !== false;
|
|
121155
|
-
this.noglobstar = !!opts.noglobstar;
|
|
121156
|
-
this.matchBase = !!opts.matchBase;
|
|
121157
|
-
this.maxDepth =
|
|
121158
|
-
typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity;
|
|
121159
|
-
this.stat = !!opts.stat;
|
|
121160
|
-
this.ignore = opts.ignore;
|
|
121161
|
-
if (this.withFileTypes && this.absolute !== undefined) {
|
|
121162
|
-
throw new Error('cannot set absolute and withFileTypes:true');
|
|
121163
|
-
}
|
|
121164
|
-
if (typeof pattern === 'string') {
|
|
121165
|
-
pattern = [pattern];
|
|
121166
|
-
}
|
|
121167
|
-
this.windowsPathsNoEscape =
|
|
121168
|
-
!!opts.windowsPathsNoEscape ||
|
|
121169
|
-
opts.allowWindowsEscape ===
|
|
121170
|
-
false;
|
|
121171
|
-
if (this.windowsPathsNoEscape) {
|
|
121172
|
-
pattern = pattern.map(p => p.replace(/\\/g, '/'));
|
|
121173
|
-
}
|
|
121174
|
-
if (this.matchBase) {
|
|
121175
|
-
if (opts.noglobstar) {
|
|
121176
|
-
throw new TypeError('base matching requires globstar');
|
|
121177
|
-
}
|
|
121178
|
-
pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`));
|
|
121179
|
-
}
|
|
121180
|
-
this.pattern = pattern;
|
|
121181
|
-
this.platform = opts.platform || defaultPlatform;
|
|
121182
|
-
this.opts = { ...opts, platform: this.platform };
|
|
121183
|
-
if (opts.scurry) {
|
|
121184
|
-
this.scurry = opts.scurry;
|
|
121185
|
-
if (opts.nocase !== undefined &&
|
|
121186
|
-
opts.nocase !== opts.scurry.nocase) {
|
|
121187
|
-
throw new Error('nocase option contradicts provided scurry option');
|
|
121188
|
-
}
|
|
121189
|
-
}
|
|
121190
|
-
else {
|
|
121191
|
-
const Scurry = opts.platform === 'win32' ? PathScurryWin32
|
|
121192
|
-
: opts.platform === 'darwin' ? PathScurryDarwin
|
|
121193
|
-
: opts.platform ? PathScurryPosix
|
|
121194
|
-
: PathScurry;
|
|
121195
|
-
this.scurry = new Scurry(this.cwd, {
|
|
121196
|
-
nocase: opts.nocase,
|
|
121197
|
-
fs: opts.fs,
|
|
121198
|
-
});
|
|
121199
|
-
}
|
|
121200
|
-
this.nocase = this.scurry.nocase;
|
|
121201
|
-
// If you do nocase:true on a case-sensitive file system, then
|
|
121202
|
-
// we need to use regexps instead of strings for non-magic
|
|
121203
|
-
// path portions, because statting `aBc` won't return results
|
|
121204
|
-
// for the file `AbC` for example.
|
|
121205
|
-
const nocaseMagicOnly = this.platform === 'darwin' || this.platform === 'win32';
|
|
121206
|
-
const mmo = {
|
|
121207
|
-
// default nocase based on platform
|
|
121208
|
-
...opts,
|
|
121209
|
-
dot: this.dot,
|
|
121210
|
-
matchBase: this.matchBase,
|
|
121211
|
-
nobrace: this.nobrace,
|
|
121212
|
-
nocase: this.nocase,
|
|
121213
|
-
nocaseMagicOnly,
|
|
121214
|
-
nocomment: true,
|
|
121215
|
-
noext: this.noext,
|
|
121216
|
-
nonegate: true,
|
|
121217
|
-
optimizationLevel: 2,
|
|
121218
|
-
platform: this.platform,
|
|
121219
|
-
windowsPathsNoEscape: this.windowsPathsNoEscape,
|
|
121220
|
-
debug: !!this.opts.debug,
|
|
121221
|
-
};
|
|
121222
|
-
const mms = this.pattern.map(p => new Minimatch(p, mmo));
|
|
121223
|
-
const [matchSet, globParts] = mms.reduce((set, m) => {
|
|
121224
|
-
set[0].push(...m.set);
|
|
121225
|
-
set[1].push(...m.globParts);
|
|
121226
|
-
return set;
|
|
121227
|
-
}, [[], []]);
|
|
121228
|
-
this.patterns = matchSet.map((set, i) => {
|
|
121229
|
-
const g = globParts[i];
|
|
121230
|
-
/* c8 ignore start */
|
|
121231
|
-
if (!g)
|
|
121232
|
-
throw new Error('invalid pattern object');
|
|
121233
|
-
/* c8 ignore stop */
|
|
121234
|
-
return new Pattern(set, g, 0, this.platform);
|
|
121235
|
-
});
|
|
121236
|
-
}
|
|
121237
|
-
async walk() {
|
|
121238
|
-
// Walkers always return array of Path objects, so we just have to
|
|
121239
|
-
// coerce them into the right shape. It will have already called
|
|
121240
|
-
// realpath() if the option was set to do so, so we know that's cached.
|
|
121241
|
-
// start out knowing the cwd, at least
|
|
121242
|
-
return [
|
|
121243
|
-
...(await new GlobWalker(this.patterns, this.scurry.cwd, {
|
|
121244
|
-
...this.opts,
|
|
121245
|
-
maxDepth: this.maxDepth !== Infinity ?
|
|
121246
|
-
this.maxDepth + this.scurry.cwd.depth()
|
|
121247
|
-
: Infinity,
|
|
121248
|
-
platform: this.platform,
|
|
121249
|
-
nocase: this.nocase,
|
|
121250
|
-
includeChildMatches: this.includeChildMatches,
|
|
121251
|
-
}).walk()),
|
|
121252
|
-
];
|
|
121253
|
-
}
|
|
121254
|
-
walkSync() {
|
|
121255
|
-
return [
|
|
121256
|
-
...new GlobWalker(this.patterns, this.scurry.cwd, {
|
|
121257
|
-
...this.opts,
|
|
121258
|
-
maxDepth: this.maxDepth !== Infinity ?
|
|
121259
|
-
this.maxDepth + this.scurry.cwd.depth()
|
|
121260
|
-
: Infinity,
|
|
121261
|
-
platform: this.platform,
|
|
121262
|
-
nocase: this.nocase,
|
|
121263
|
-
includeChildMatches: this.includeChildMatches,
|
|
121264
|
-
}).walkSync(),
|
|
121265
|
-
];
|
|
121266
|
-
}
|
|
121267
|
-
stream() {
|
|
121268
|
-
return new GlobStream(this.patterns, this.scurry.cwd, {
|
|
121269
|
-
...this.opts,
|
|
121270
|
-
maxDepth: this.maxDepth !== Infinity ?
|
|
121271
|
-
this.maxDepth + this.scurry.cwd.depth()
|
|
121272
|
-
: Infinity,
|
|
121273
|
-
platform: this.platform,
|
|
121274
|
-
nocase: this.nocase,
|
|
121275
|
-
includeChildMatches: this.includeChildMatches,
|
|
121276
|
-
}).stream();
|
|
121277
|
-
}
|
|
121278
|
-
streamSync() {
|
|
121279
|
-
return new GlobStream(this.patterns, this.scurry.cwd, {
|
|
121280
|
-
...this.opts,
|
|
121281
|
-
maxDepth: this.maxDepth !== Infinity ?
|
|
121282
|
-
this.maxDepth + this.scurry.cwd.depth()
|
|
121283
|
-
: Infinity,
|
|
121284
|
-
platform: this.platform,
|
|
121285
|
-
nocase: this.nocase,
|
|
121286
|
-
includeChildMatches: this.includeChildMatches,
|
|
121287
|
-
}).streamSync();
|
|
121288
|
-
}
|
|
121289
|
-
/**
|
|
121290
|
-
* Default sync iteration function. Returns a Generator that
|
|
121291
|
-
* iterates over the results.
|
|
121292
|
-
*/
|
|
121293
|
-
iterateSync() {
|
|
121294
|
-
return this.streamSync()[Symbol.iterator]();
|
|
121295
|
-
}
|
|
121296
|
-
[Symbol.iterator]() {
|
|
121297
|
-
return this.iterateSync();
|
|
121298
|
-
}
|
|
121299
|
-
/**
|
|
121300
|
-
* Default async iteration function. Returns an AsyncGenerator that
|
|
121301
|
-
* iterates over the results.
|
|
121302
|
-
*/
|
|
121303
|
-
iterate() {
|
|
121304
|
-
return this.stream()[Symbol.asyncIterator]();
|
|
121305
|
-
}
|
|
121306
|
-
[Symbol.asyncIterator]() {
|
|
121307
|
-
return this.iterate();
|
|
121308
|
-
}
|
|
121309
|
-
}
|
|
121310
|
-
|
|
121311
|
-
/**
|
|
121312
|
-
* Return true if the patterns provided contain any magic glob characters,
|
|
121313
|
-
* given the options provided.
|
|
121314
|
-
*
|
|
121315
|
-
* Brace expansion is not considered "magic" unless the `magicalBraces` option
|
|
121316
|
-
* is set, as brace expansion just turns one string into an array of strings.
|
|
121317
|
-
* So a pattern like `'x{a,b}y'` would return `false`, because `'xay'` and
|
|
121318
|
-
* `'xby'` both do not contain any magic glob characters, and it's treated the
|
|
121319
|
-
* same as if you had called it on `['xay', 'xby']`. When `magicalBraces:true`
|
|
121320
|
-
* is in the options, brace expansion _is_ treated as a pattern having magic.
|
|
121321
|
-
*/
|
|
121322
|
-
const hasMagic = (pattern, options = {}) => {
|
|
121323
|
-
if (!Array.isArray(pattern)) {
|
|
121324
|
-
pattern = [pattern];
|
|
121325
|
-
}
|
|
121326
|
-
for (const p of pattern) {
|
|
121327
|
-
if (new Minimatch(p, options).hasMagic())
|
|
121328
|
-
return true;
|
|
121329
|
-
}
|
|
121330
|
-
return false;
|
|
121331
|
-
};
|
|
121332
|
-
|
|
121333
|
-
function globStreamSync(pattern, options = {}) {
|
|
121334
|
-
return new Glob(pattern, options).streamSync();
|
|
121335
|
-
}
|
|
121336
|
-
function globStream(pattern, options = {}) {
|
|
121337
|
-
return new Glob(pattern, options).stream();
|
|
121338
|
-
}
|
|
121339
|
-
function globSync(pattern, options = {}) {
|
|
121340
|
-
return new Glob(pattern, options).walkSync();
|
|
121341
|
-
}
|
|
121342
|
-
async function glob_(pattern, options = {}) {
|
|
121343
|
-
return new Glob(pattern, options).walk();
|
|
121344
|
-
}
|
|
121345
|
-
function globIterateSync(pattern, options = {}) {
|
|
121346
|
-
return new Glob(pattern, options).iterateSync();
|
|
121347
|
-
}
|
|
121348
|
-
function globIterate(pattern, options = {}) {
|
|
121349
|
-
return new Glob(pattern, options).iterate();
|
|
121350
|
-
}
|
|
121351
|
-
// aliases: glob.sync.stream() glob.stream.sync() glob.sync() etc
|
|
121352
|
-
const streamSync = globStreamSync;
|
|
121353
|
-
const stream = Object.assign(globStream, { sync: globStreamSync });
|
|
121354
|
-
const iterateSync = globIterateSync;
|
|
121355
|
-
const iterate = Object.assign(globIterate, {
|
|
121356
|
-
sync: globIterateSync,
|
|
121357
|
-
});
|
|
121358
|
-
const sync = Object.assign(globSync, {
|
|
121359
|
-
stream: globStreamSync,
|
|
121360
|
-
iterate: globIterateSync,
|
|
121361
|
-
});
|
|
121362
|
-
const glob = Object.assign(glob_, {
|
|
121363
|
-
glob: glob_,
|
|
121364
|
-
globSync,
|
|
121365
|
-
sync,
|
|
121366
|
-
globStream,
|
|
121367
|
-
stream,
|
|
121368
|
-
globStreamSync,
|
|
121369
|
-
streamSync,
|
|
121370
|
-
globIterate,
|
|
121371
|
-
iterate,
|
|
121372
|
-
globIterateSync,
|
|
121373
|
-
iterateSync,
|
|
121374
|
-
Glob,
|
|
121375
|
-
hasMagic,
|
|
121376
|
-
escape: escape$1,
|
|
121377
|
-
unescape: unescape$1,
|
|
121378
|
-
});
|
|
121379
|
-
glob.glob = glob;
|
|
121380
|
-
|
|
121381
|
-
function matchesQuantizationVariant({ filePath, variant }) {
|
|
121382
|
-
if (!variant) {
|
|
121383
|
-
return false;
|
|
121384
|
-
}
|
|
121385
|
-
const escapedVariant = variant.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
121386
|
-
const matcher = new RegExp(`(^|[\\-./_])${escapedVariant}(?=[\\-./]|$)`, "i");
|
|
121387
|
-
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
121388
|
-
const segments = normalizedPath.split("/").filter(Boolean);
|
|
121389
|
-
if (segments.length === 0) {
|
|
121390
|
-
return false;
|
|
121391
|
-
}
|
|
121392
|
-
const filename = segments[segments.length - 1].replace(/\.gguf$/i, "");
|
|
121393
|
-
if (matcher.test(filename)) {
|
|
121394
|
-
return true;
|
|
121395
|
-
}
|
|
121396
|
-
return segments.slice(0, -1).some(segment => matcher.test(segment));
|
|
121397
|
-
}
|
|
121398
|
-
async function findQuantizedModelTarget({ model, path }) {
|
|
121399
|
-
if (model.source.type === "storage") {
|
|
121400
|
-
throw new Error("Model storage not supported yet");
|
|
121401
|
-
}
|
|
121402
|
-
if (model.format !== "gguf") {
|
|
121403
|
-
throw new Error(`Model format not supported: ${model.format}`);
|
|
121404
|
-
}
|
|
121405
|
-
const [, variant = null] = model.source.slug.split(":");
|
|
121406
|
-
const modelFiles = (await glob("**/*.gguf", {
|
|
121407
|
-
absolute: true,
|
|
121408
|
-
cwd: path,
|
|
121409
|
-
nodir: true
|
|
121410
|
-
})).filter(file => !/(mmproj|clip)/i.test(file));
|
|
121411
|
-
if (modelFiles.length <= 0) {
|
|
121412
|
-
throw new Error(`No models found for format: ${model.format}`);
|
|
121413
|
-
}
|
|
121414
|
-
modelFiles.sort((left, right) => left.localeCompare(right, undefined, { sensitivity: "base" }));
|
|
121415
|
-
if (!variant) {
|
|
121416
|
-
return modelFiles[0];
|
|
121417
|
-
}
|
|
121418
|
-
const matches = modelFiles.filter(fileName => matchesQuantizationVariant({ filePath: fileName, variant: variant ?? "" }));
|
|
121419
|
-
if (matches.length === 0) {
|
|
121420
|
-
throw new Error(`No model found for format and variant: ${model.format} / ${variant}`);
|
|
121421
|
-
}
|
|
121422
|
-
return matches[0];
|
|
121423
|
-
}
|
|
121424
|
-
|
|
121425
|
-
const VLLM_START_ARGS = ["-m", "vllm.entrypoints.openai.api_server", "--host", "0.0.0.0"];
|
|
121426
|
-
const VLLM_EXECUTABLE = "python3";
|
|
121427
|
-
const DEFAULT_VLLM_CONTEXT_LENGTH = 2048;
|
|
121428
|
-
async function startVLLM({ enginePort, targetDirectory }) {
|
|
121429
|
-
const contextLength = Math.max(1, this.contextLength ?? DEFAULT_VLLM_CONTEXT_LENGTH);
|
|
121430
|
-
let modelPath = targetDirectory;
|
|
121431
|
-
if (this.model.format === "gguf") {
|
|
121432
|
-
modelPath = await findQuantizedModelTarget({ model: this.model, path: targetDirectory });
|
|
121433
|
-
}
|
|
121434
|
-
const engineConfig = this.engineConfig;
|
|
121435
|
-
const device = typeof engineConfig?.device === "string" ? engineConfig.device : process.env.VLLM_DEVICE;
|
|
121436
|
-
const dtype = typeof engineConfig?.dtype === "string" ? engineConfig.dtype : process.env.VLLM_DTYPE;
|
|
121437
|
-
const tensorParallelSize = typeof engineConfig?.tensorParallelSize === "number" ? engineConfig.tensorParallelSize : 1;
|
|
121438
|
-
const args = [
|
|
121439
|
-
...VLLM_START_ARGS,
|
|
121440
|
-
"--port",
|
|
121441
|
-
String(enginePort),
|
|
121442
|
-
"--model",
|
|
121443
|
-
modelPath,
|
|
121444
|
-
"--served-model-name",
|
|
121445
|
-
SERVED_MODEL_NAME,
|
|
121446
|
-
"--max-model-len",
|
|
121447
|
-
String(contextLength),
|
|
121448
|
-
"--tensor-parallel-size",
|
|
121449
|
-
String(tensorParallelSize)
|
|
121450
|
-
];
|
|
121451
|
-
if (this.model.taskType === "embeddings") {
|
|
121452
|
-
args.push("--task", "embed");
|
|
121453
|
-
}
|
|
121454
|
-
if (device) {
|
|
121455
|
-
args.push("--device", device);
|
|
121456
|
-
}
|
|
121457
|
-
if (dtype) {
|
|
121458
|
-
args.push("--dtype", dtype);
|
|
121459
|
-
}
|
|
121460
|
-
args.push(...parseExtraArgs(engineConfig?.extraArgs));
|
|
121461
|
-
if (this.model.multimodalEnabled) {
|
|
121462
|
-
args.push("--limit-mm-per-prompt", process.env.VLLM_MM_LIMIT ?? '{"image":5}');
|
|
121463
|
-
}
|
|
121464
|
-
if (process.env.VLLM_TRUST_REMOTE_CODE === "true") {
|
|
121465
|
-
args.push("--trust-remote-code");
|
|
121466
|
-
}
|
|
121467
|
-
return createEngineProcess({ args, bin: VLLM_EXECUTABLE, logger: this.logger });
|
|
121468
|
-
}
|
|
121469
|
-
|
|
121470
|
-
// src/lib/cache-management.ts
|
|
121471
|
-
|
|
121472
|
-
// src/consts.ts
|
|
121473
|
-
var HUB_URL = "https://huggingface.co";
|
|
121474
|
-
|
|
121475
|
-
// src/error.ts
|
|
121476
|
-
async function createApiError(response, opts) {
|
|
121477
|
-
const error = new HubApiError(response.url, response.status, response.headers.get("X-Request-Id") ?? opts?.requestId);
|
|
121478
|
-
error.message = `Api error with status ${error.statusCode}${""}`;
|
|
121479
|
-
const trailer = [`URL: ${error.url}`, error.requestId ? `Request ID: ${error.requestId}` : void 0].filter(Boolean).join(". ");
|
|
121480
|
-
if (response.headers.get("Content-Type")?.startsWith("application/json")) {
|
|
121481
|
-
const json = await response.json();
|
|
121482
|
-
error.message = json.error || json.message || error.message;
|
|
121483
|
-
if (json.error_description) {
|
|
121484
|
-
error.message = error.message ? error.message + `: ${json.error_description}` : json.error_description;
|
|
121485
|
-
}
|
|
121486
|
-
error.data = json;
|
|
121487
|
-
} else {
|
|
121488
|
-
error.data = { message: await response.text() };
|
|
121489
|
-
}
|
|
121490
|
-
error.message += `. ${trailer}`;
|
|
121491
|
-
throw error;
|
|
121492
|
-
}
|
|
121493
|
-
var HubApiError = class extends Error {
|
|
121494
|
-
statusCode;
|
|
121495
|
-
url;
|
|
121496
|
-
requestId;
|
|
121497
|
-
data;
|
|
121498
|
-
constructor(url, statusCode, requestId, message) {
|
|
121499
|
-
super(message);
|
|
121500
|
-
this.statusCode = statusCode;
|
|
121501
|
-
this.requestId = requestId;
|
|
121502
|
-
this.url = url;
|
|
121503
|
-
}
|
|
121504
|
-
};
|
|
121505
|
-
var InvalidApiResponseFormatError = class extends Error {
|
|
121506
|
-
};
|
|
121507
|
-
|
|
121508
|
-
// src/utils/checkCredentials.ts
|
|
121509
|
-
function checkAccessToken(accessToken) {
|
|
121510
|
-
if (!accessToken.startsWith("hf_")) {
|
|
121511
|
-
throw new TypeError("Your access token must start with 'hf_'");
|
|
121512
|
-
}
|
|
121513
|
-
}
|
|
121514
|
-
function checkCredentials(params) {
|
|
121515
|
-
if (params.accessToken) {
|
|
121516
|
-
checkAccessToken(params.accessToken);
|
|
121517
|
-
return params.accessToken;
|
|
121518
|
-
}
|
|
121519
|
-
if (params.credentials?.accessToken) {
|
|
121520
|
-
checkAccessToken(params.credentials.accessToken);
|
|
121521
|
-
return params.credentials.accessToken;
|
|
121522
|
-
}
|
|
121523
|
-
}
|
|
121524
|
-
|
|
121525
|
-
// src/utils/toRepoId.ts
|
|
121526
|
-
function toRepoId(repo) {
|
|
121527
|
-
if (typeof repo !== "string") {
|
|
121528
|
-
return repo;
|
|
121529
|
-
}
|
|
121530
|
-
if (repo.startsWith("model/") || repo.startsWith("models/")) {
|
|
121531
|
-
throw new TypeError(
|
|
121532
|
-
"A repo designation for a model should not start with 'models/', directly specify the model namespace / name"
|
|
121533
|
-
);
|
|
121534
|
-
}
|
|
121535
|
-
if (repo.startsWith("space/")) {
|
|
121536
|
-
throw new TypeError("Spaces should start with 'spaces/', plural, not 'space/'");
|
|
121537
|
-
}
|
|
121538
|
-
if (repo.startsWith("dataset/")) {
|
|
121539
|
-
throw new TypeError("Datasets should start with 'dataset/', plural, not 'dataset/'");
|
|
121540
|
-
}
|
|
121541
|
-
const slashes = repo.split("/").length - 1;
|
|
121542
|
-
if (repo.startsWith("spaces/")) {
|
|
121543
|
-
if (slashes !== 2) {
|
|
121544
|
-
throw new TypeError("Space Id must include namespace and name of the space");
|
|
121545
|
-
}
|
|
121546
|
-
return {
|
|
121547
|
-
type: "space",
|
|
121548
|
-
name: repo.slice("spaces/".length)
|
|
121549
|
-
};
|
|
121550
|
-
}
|
|
121551
|
-
if (repo.startsWith("datasets/")) {
|
|
121552
|
-
if (slashes > 2) {
|
|
121553
|
-
throw new TypeError("Too many slashes in repo designation: " + repo);
|
|
121554
|
-
}
|
|
121555
|
-
return {
|
|
121556
|
-
type: "dataset",
|
|
121557
|
-
name: repo.slice("datasets/".length)
|
|
121558
|
-
};
|
|
121559
|
-
}
|
|
121560
|
-
if (slashes > 1) {
|
|
121561
|
-
throw new TypeError("Too many slashes in repo designation: " + repo);
|
|
121562
|
-
}
|
|
121563
|
-
return {
|
|
121564
|
-
type: "model",
|
|
121565
|
-
name: repo
|
|
121566
|
-
};
|
|
121567
|
-
}
|
|
121568
|
-
new Promise((r) => {
|
|
121569
|
-
});
|
|
121570
|
-
|
|
121571
|
-
// src/utils/combineUint8Arrays.ts
|
|
121572
|
-
function combineUint8Arrays(a, b) {
|
|
121573
|
-
const aLength = a.length;
|
|
121574
|
-
const combinedBytes = new Uint8Array(aLength + b.length);
|
|
121575
|
-
combinedBytes.set(a);
|
|
121576
|
-
combinedBytes.set(b, aLength);
|
|
121577
|
-
return combinedBytes;
|
|
121578
|
-
}
|
|
121579
|
-
function readU64(b, n) {
|
|
121580
|
-
let x = 0;
|
|
121581
|
-
x |= b[n++] << 0;
|
|
121582
|
-
x |= b[n++] << 8;
|
|
121583
|
-
x |= b[n++] << 16;
|
|
121584
|
-
x |= b[n++] << 24;
|
|
121585
|
-
x |= b[n++] << 32;
|
|
121586
|
-
x |= b[n++] << 40;
|
|
121587
|
-
x |= b[n++] << 48;
|
|
121588
|
-
x |= b[n++] << 56;
|
|
121589
|
-
return x;
|
|
121590
|
-
}
|
|
121591
|
-
function readU32(b, n) {
|
|
121592
|
-
let x = 0;
|
|
121593
|
-
x |= b[n++] << 0;
|
|
121594
|
-
x |= b[n++] << 8;
|
|
121595
|
-
x |= b[n++] << 16;
|
|
121596
|
-
x |= b[n++] << 24;
|
|
121597
|
-
return x;
|
|
121598
|
-
}
|
|
121599
|
-
|
|
121600
|
-
// src/vendor/lz4js/index.ts
|
|
121601
|
-
var minMatch = 4;
|
|
121602
|
-
var hashSize = 1 << 16;
|
|
121603
|
-
makeHashTable();
|
|
121604
|
-
var magicNum = 407708164;
|
|
121605
|
-
var fdContentChksum = 4;
|
|
121606
|
-
var fdContentSize = 8;
|
|
121607
|
-
var fdBlockChksum = 16;
|
|
121608
|
-
var fdVersion = 64;
|
|
121609
|
-
var fdVersionMask = 192;
|
|
121610
|
-
var bsUncompressed = 2147483648;
|
|
121611
|
-
var bsShift = 4;
|
|
121612
|
-
var bsMask = 7;
|
|
121613
|
-
var bsMap = {
|
|
121614
|
-
4: 65536,
|
|
121615
|
-
5: 262144,
|
|
121616
|
-
6: 1048576,
|
|
121617
|
-
7: 4194304
|
|
121618
|
-
};
|
|
121619
|
-
function makeHashTable() {
|
|
121620
|
-
try {
|
|
121621
|
-
return new Uint32Array(hashSize);
|
|
121622
|
-
} catch (error) {
|
|
121623
|
-
const hashTable2 = new Array(hashSize);
|
|
121624
|
-
for (let i = 0; i < hashSize; i++) {
|
|
121625
|
-
hashTable2[i] = 0;
|
|
121626
|
-
}
|
|
121627
|
-
return hashTable2;
|
|
121628
|
-
}
|
|
121629
|
-
}
|
|
121630
|
-
function makeBuffer(size) {
|
|
121631
|
-
return new Uint8Array(size);
|
|
121632
|
-
}
|
|
121633
|
-
function sliceArray(array, start, end) {
|
|
121634
|
-
return array.slice(start, end);
|
|
121635
|
-
}
|
|
121636
|
-
function decompressBound(src) {
|
|
121637
|
-
let sIndex = 0;
|
|
121638
|
-
if (readU32(src, sIndex) !== magicNum) {
|
|
121639
|
-
throw new Error("invalid magic number");
|
|
121640
|
-
}
|
|
121641
|
-
sIndex += 4;
|
|
121642
|
-
const descriptor = src[sIndex++];
|
|
121643
|
-
if ((descriptor & fdVersionMask) !== fdVersion) {
|
|
121644
|
-
throw new Error("incompatible descriptor version " + (descriptor & fdVersionMask));
|
|
121645
|
-
}
|
|
121646
|
-
const useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
121647
|
-
const useContentSize = (descriptor & fdContentSize) !== 0;
|
|
121648
|
-
const bsIdx = src[sIndex++] >> bsShift & bsMask;
|
|
121649
|
-
if (bsMap[bsIdx] === void 0) {
|
|
121650
|
-
throw new Error("invalid block size " + bsIdx);
|
|
121651
|
-
}
|
|
121652
|
-
const maxBlockSize = bsMap[bsIdx];
|
|
121653
|
-
if (useContentSize) {
|
|
121654
|
-
return readU64(src, sIndex);
|
|
121655
|
-
}
|
|
121656
|
-
sIndex++;
|
|
121657
|
-
let maxSize = 0;
|
|
121658
|
-
while (true) {
|
|
121659
|
-
let blockSize = readU32(src, sIndex);
|
|
121660
|
-
sIndex += 4;
|
|
121661
|
-
if (blockSize & bsUncompressed) {
|
|
121662
|
-
blockSize &= ~bsUncompressed;
|
|
121663
|
-
maxSize += blockSize;
|
|
121664
|
-
} else if (blockSize > 0) {
|
|
121665
|
-
maxSize += maxBlockSize;
|
|
121666
|
-
}
|
|
121667
|
-
if (blockSize === 0) {
|
|
121668
|
-
return maxSize;
|
|
121669
|
-
}
|
|
121670
|
-
if (useBlockSum) {
|
|
121671
|
-
sIndex += 4;
|
|
121672
|
-
}
|
|
121673
|
-
sIndex += blockSize;
|
|
121674
|
-
}
|
|
121675
|
-
}
|
|
121676
|
-
function decompressBlock(src, dst, sIndex, sLength, dIndex) {
|
|
121677
|
-
let mLength, mOffset, sEnd, n, i;
|
|
121678
|
-
const hasCopyWithin = dst.copyWithin !== void 0 && dst.fill !== void 0;
|
|
121679
|
-
sEnd = sIndex + sLength;
|
|
121680
|
-
while (sIndex < sEnd) {
|
|
121681
|
-
const token = src[sIndex++];
|
|
121682
|
-
let literalCount = token >> 4;
|
|
121683
|
-
if (literalCount > 0) {
|
|
121684
|
-
if (literalCount === 15) {
|
|
121685
|
-
while (true) {
|
|
121686
|
-
literalCount += src[sIndex];
|
|
121687
|
-
if (src[sIndex++] !== 255) {
|
|
121688
|
-
break;
|
|
121689
|
-
}
|
|
121690
|
-
}
|
|
121691
|
-
}
|
|
121692
|
-
for (n = sIndex + literalCount; sIndex < n; ) {
|
|
121693
|
-
dst[dIndex++] = src[sIndex++];
|
|
121694
|
-
}
|
|
121695
|
-
}
|
|
121696
|
-
if (sIndex >= sEnd) {
|
|
121697
|
-
break;
|
|
121698
|
-
}
|
|
121699
|
-
mLength = token & 15;
|
|
121700
|
-
mOffset = src[sIndex++] | src[sIndex++] << 8;
|
|
121701
|
-
if (mLength === 15) {
|
|
121702
|
-
while (true) {
|
|
121703
|
-
mLength += src[sIndex];
|
|
121704
|
-
if (src[sIndex++] !== 255) {
|
|
121705
|
-
break;
|
|
121706
|
-
}
|
|
121707
|
-
}
|
|
121708
|
-
}
|
|
121709
|
-
mLength += minMatch;
|
|
121710
|
-
if (hasCopyWithin && mOffset === 1) {
|
|
121711
|
-
dst.fill(dst[dIndex - 1] | 0, dIndex, dIndex + mLength);
|
|
121712
|
-
dIndex += mLength;
|
|
121713
|
-
} else if (hasCopyWithin && mOffset > mLength && mLength > 31) {
|
|
121714
|
-
dst.copyWithin(dIndex, dIndex - mOffset, dIndex - mOffset + mLength);
|
|
121715
|
-
dIndex += mLength;
|
|
121716
|
-
} else {
|
|
121717
|
-
for (i = dIndex - mOffset, n = i + mLength; i < n; ) {
|
|
121718
|
-
dst[dIndex++] = dst[i++] | 0;
|
|
121719
|
-
}
|
|
121720
|
-
}
|
|
121721
|
-
}
|
|
121722
|
-
return dIndex;
|
|
121723
|
-
}
|
|
121724
|
-
function decompressFrame(src, dst) {
|
|
121725
|
-
let useBlockSum, useContentSum, useContentSize, descriptor;
|
|
121726
|
-
let sIndex = 0;
|
|
121727
|
-
let dIndex = 0;
|
|
121728
|
-
if (readU32(src, sIndex) !== magicNum) {
|
|
121729
|
-
throw new Error("invalid magic number");
|
|
121730
|
-
}
|
|
121731
|
-
sIndex += 4;
|
|
121732
|
-
descriptor = src[sIndex++];
|
|
121733
|
-
if ((descriptor & fdVersionMask) !== fdVersion) {
|
|
121734
|
-
throw new Error("incompatible descriptor version");
|
|
121735
|
-
}
|
|
121736
|
-
useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
121737
|
-
useContentSum = (descriptor & fdContentChksum) !== 0;
|
|
121738
|
-
useContentSize = (descriptor & fdContentSize) !== 0;
|
|
121739
|
-
const bsIdx = src[sIndex++] >> bsShift & bsMask;
|
|
121740
|
-
if (bsMap[bsIdx] === void 0) {
|
|
121741
|
-
throw new Error("invalid block size");
|
|
121742
|
-
}
|
|
121743
|
-
if (useContentSize) {
|
|
121744
|
-
sIndex += 8;
|
|
121745
|
-
}
|
|
121746
|
-
sIndex++;
|
|
121747
|
-
while (true) {
|
|
121748
|
-
var compSize;
|
|
121749
|
-
compSize = readU32(src, sIndex);
|
|
121750
|
-
sIndex += 4;
|
|
121751
|
-
if (compSize === 0) {
|
|
121752
|
-
break;
|
|
121753
|
-
}
|
|
121754
|
-
if (useBlockSum) {
|
|
121755
|
-
sIndex += 4;
|
|
121756
|
-
}
|
|
121757
|
-
if ((compSize & bsUncompressed) !== 0) {
|
|
121758
|
-
compSize &= ~bsUncompressed;
|
|
121759
|
-
for (let j = 0; j < compSize; j++) {
|
|
121760
|
-
dst[dIndex++] = src[sIndex++];
|
|
121761
|
-
}
|
|
121762
|
-
} else {
|
|
121763
|
-
dIndex = decompressBlock(src, dst, sIndex, compSize, dIndex);
|
|
121764
|
-
sIndex += compSize;
|
|
121765
|
-
}
|
|
121766
|
-
}
|
|
121767
|
-
if (useContentSum) {
|
|
121768
|
-
sIndex += 4;
|
|
121769
|
-
}
|
|
121770
|
-
return dIndex;
|
|
121771
|
-
}
|
|
121772
|
-
function decompress(src, maxSize) {
|
|
121773
|
-
let dst, size;
|
|
121774
|
-
if (maxSize === void 0) {
|
|
121775
|
-
maxSize = decompressBound(src);
|
|
121776
|
-
}
|
|
121777
|
-
dst = makeBuffer(maxSize);
|
|
121778
|
-
size = decompressFrame(src, dst);
|
|
121779
|
-
if (size !== maxSize) {
|
|
121780
|
-
dst = sliceArray(dst, 0, size);
|
|
121781
|
-
}
|
|
121782
|
-
return dst;
|
|
121783
|
-
}
|
|
121784
|
-
|
|
121785
|
-
// src/utils/RangeList.ts
|
|
121786
|
-
var RangeList = class {
|
|
121787
|
-
ranges = [];
|
|
121788
|
-
/**
|
|
121789
|
-
* Add a range to the list. If it overlaps with existing ranges,
|
|
121790
|
-
* it will split them and increment reference counts accordingly.
|
|
121791
|
-
*/
|
|
121792
|
-
add(start, end) {
|
|
121793
|
-
if (end <= start) {
|
|
121794
|
-
throw new TypeError("End must be greater than start");
|
|
121795
|
-
}
|
|
121796
|
-
const overlappingRanges = [];
|
|
121797
|
-
for (let i = 0; i < this.ranges.length; i++) {
|
|
121798
|
-
const range2 = this.ranges[i];
|
|
121799
|
-
if (start < range2.end && end > range2.start) {
|
|
121800
|
-
overlappingRanges.push({ index: i, range: range2 });
|
|
121801
|
-
}
|
|
121802
|
-
if (range2.data !== null) {
|
|
121803
|
-
throw new Error("Overlapping range already has data");
|
|
121804
|
-
}
|
|
121805
|
-
}
|
|
121806
|
-
if (overlappingRanges.length === 0) {
|
|
121807
|
-
this.ranges.push({ start, end, refCount: 1, data: null });
|
|
121808
|
-
this.ranges.sort((a, b) => a.start - b.start);
|
|
121809
|
-
return;
|
|
121810
|
-
}
|
|
121811
|
-
const newRanges = [];
|
|
121812
|
-
let currentPos = start;
|
|
121813
|
-
for (let i = 0; i < overlappingRanges.length; i++) {
|
|
121814
|
-
const { range: range2 } = overlappingRanges[i];
|
|
121815
|
-
if (currentPos < range2.start) {
|
|
121816
|
-
newRanges.push({
|
|
121817
|
-
start: currentPos,
|
|
121818
|
-
end: range2.start,
|
|
121819
|
-
refCount: 1,
|
|
121820
|
-
data: null
|
|
121821
|
-
});
|
|
121822
|
-
} else if (range2.start < currentPos) {
|
|
121823
|
-
newRanges.push({
|
|
121824
|
-
start: range2.start,
|
|
121825
|
-
end: currentPos,
|
|
121826
|
-
refCount: range2.refCount,
|
|
121827
|
-
data: null
|
|
121828
|
-
});
|
|
121829
|
-
}
|
|
121830
|
-
newRanges.push({
|
|
121831
|
-
start: Math.max(currentPos, range2.start),
|
|
121832
|
-
end: Math.min(end, range2.end),
|
|
121833
|
-
refCount: range2.refCount + 1,
|
|
121834
|
-
data: null
|
|
121835
|
-
});
|
|
121836
|
-
if (range2.end > end) {
|
|
121837
|
-
newRanges.push({
|
|
121838
|
-
start: end,
|
|
121839
|
-
end: range2.end,
|
|
121840
|
-
refCount: range2.refCount,
|
|
121841
|
-
data: null
|
|
121842
|
-
});
|
|
121843
|
-
}
|
|
121844
|
-
currentPos = Math.max(currentPos, range2.end);
|
|
121845
|
-
}
|
|
121846
|
-
if (currentPos < end) {
|
|
121847
|
-
newRanges.push({
|
|
121848
|
-
start: currentPos,
|
|
121849
|
-
end,
|
|
121850
|
-
refCount: 1,
|
|
121851
|
-
data: null
|
|
121852
|
-
});
|
|
121853
|
-
}
|
|
121854
|
-
const firstIndex = overlappingRanges[0].index;
|
|
121855
|
-
const lastIndex = overlappingRanges[overlappingRanges.length - 1].index;
|
|
121856
|
-
this.ranges.splice(firstIndex, lastIndex - firstIndex + 1, ...newRanges);
|
|
121857
|
-
this.ranges.sort((a, b) => a.start - b.start);
|
|
121858
|
-
}
|
|
121859
|
-
/**
|
|
121860
|
-
* Remove a range from the list. The range must start and end at existing boundaries.
|
|
121861
|
-
*/
|
|
121862
|
-
remove(start, end) {
|
|
121863
|
-
if (end <= start) {
|
|
121864
|
-
throw new TypeError("End must be greater than start");
|
|
121865
|
-
}
|
|
121866
|
-
const affectedRanges = [];
|
|
121867
|
-
for (let i = 0; i < this.ranges.length; i++) {
|
|
121868
|
-
const range2 = this.ranges[i];
|
|
121869
|
-
if (start < range2.end && end > range2.start) {
|
|
121870
|
-
affectedRanges.push({ index: i, range: range2 });
|
|
121871
|
-
}
|
|
121872
|
-
}
|
|
121873
|
-
if (affectedRanges.length === 0) {
|
|
121874
|
-
throw new Error("No ranges found to remove");
|
|
121875
|
-
}
|
|
121876
|
-
if (start !== affectedRanges[0].range.start || end !== affectedRanges[affectedRanges.length - 1].range.end) {
|
|
121877
|
-
throw new Error("Range boundaries must match existing boundaries");
|
|
121878
|
-
}
|
|
121879
|
-
for (let i = 0; i < affectedRanges.length; i++) {
|
|
121880
|
-
const { range: range2 } = affectedRanges[i];
|
|
121881
|
-
range2.refCount--;
|
|
121882
|
-
}
|
|
121883
|
-
this.ranges = this.ranges.filter((range2) => range2.refCount > 0);
|
|
121884
|
-
}
|
|
121885
|
-
/**
|
|
121886
|
-
* Get all ranges within the specified boundaries.
|
|
121887
|
-
*/
|
|
121888
|
-
getRanges(start, end) {
|
|
121889
|
-
if (end <= start) {
|
|
121890
|
-
throw new TypeError("End must be greater than start");
|
|
121891
|
-
}
|
|
121892
|
-
return this.ranges.filter((range2) => start < range2.end && end > range2.start);
|
|
121893
|
-
}
|
|
121894
|
-
/**
|
|
121895
|
-
* Get all ranges in the list
|
|
121896
|
-
*/
|
|
121897
|
-
getAllRanges() {
|
|
121898
|
-
return [...this.ranges];
|
|
121899
|
-
}
|
|
121900
|
-
};
|
|
121901
|
-
|
|
121902
|
-
// src/utils/XetBlob.ts
|
|
121903
|
-
var JWT_SAFETY_PERIOD = 6e4;
|
|
121904
|
-
var JWT_CACHE_SIZE = 1e3;
|
|
121905
|
-
var compressionSchemeLabels = {
|
|
121906
|
-
[0 /* None */]: "None",
|
|
121907
|
-
[1 /* LZ4 */]: "LZ4",
|
|
121908
|
-
[2 /* ByteGroupingLZ4 */]: "ByteGroupingLZ4"
|
|
121909
|
-
};
|
|
121910
|
-
var XET_CHUNK_HEADER_BYTES = 8;
|
|
121911
|
-
var XetBlob = class extends Blob {
|
|
121912
|
-
fetch;
|
|
121913
|
-
accessToken;
|
|
121914
|
-
refreshUrl;
|
|
121915
|
-
reconstructionUrl;
|
|
121916
|
-
hash;
|
|
121917
|
-
start = 0;
|
|
121918
|
-
end = 0;
|
|
121919
|
-
internalLogging = false;
|
|
121920
|
-
reconstructionInfo;
|
|
121921
|
-
listener;
|
|
121922
|
-
constructor(params) {
|
|
121923
|
-
super([]);
|
|
121924
|
-
this.fetch = params.fetch ?? fetch.bind(globalThis);
|
|
121925
|
-
this.accessToken = checkCredentials(params);
|
|
121926
|
-
this.refreshUrl = params.refreshUrl;
|
|
121927
|
-
this.end = params.size;
|
|
121928
|
-
this.reconstructionUrl = params.reconstructionUrl;
|
|
121929
|
-
this.hash = params.hash;
|
|
121930
|
-
this.listener = params.listener;
|
|
121931
|
-
this.internalLogging = params.internalLogging ?? false;
|
|
121932
|
-
this.refreshUrl;
|
|
121933
|
-
}
|
|
121934
|
-
get size() {
|
|
121935
|
-
return this.end - this.start;
|
|
121936
|
-
}
|
|
121937
|
-
#clone() {
|
|
121938
|
-
const blob = new XetBlob({
|
|
121939
|
-
fetch: this.fetch,
|
|
121940
|
-
hash: this.hash,
|
|
121941
|
-
refreshUrl: this.refreshUrl,
|
|
121942
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
121943
|
-
reconstructionUrl: this.reconstructionUrl,
|
|
121944
|
-
size: this.size
|
|
121945
|
-
});
|
|
121946
|
-
blob.accessToken = this.accessToken;
|
|
121947
|
-
blob.start = this.start;
|
|
121948
|
-
blob.end = this.end;
|
|
121949
|
-
blob.reconstructionInfo = this.reconstructionInfo;
|
|
121950
|
-
blob.listener = this.listener;
|
|
121951
|
-
blob.internalLogging = this.internalLogging;
|
|
121952
|
-
return blob;
|
|
121953
|
-
}
|
|
121954
|
-
slice(start = 0, end = this.size) {
|
|
121955
|
-
const slice = this.#clone();
|
|
121956
|
-
slice.start = this.start + start;
|
|
121957
|
-
slice.end = Math.min(this.start + end, this.end);
|
|
121958
|
-
if (slice.start !== this.start || slice.end !== this.end) {
|
|
121959
|
-
slice.reconstructionInfo = void 0;
|
|
122136
|
+
if (this.#ignored(m))
|
|
122137
|
+
continue;
|
|
122138
|
+
this.matchSync(m, absolute, ifDir);
|
|
122139
|
+
}
|
|
122140
|
+
for (const [target, patterns] of processor.subwalks.entries()) {
|
|
122141
|
+
tasks++;
|
|
122142
|
+
this.walkCB2Sync(target, patterns, processor.child(), next);
|
|
122143
|
+
}
|
|
122144
|
+
next();
|
|
121960
122145
|
}
|
|
121961
|
-
|
|
121962
|
-
|
|
121963
|
-
|
|
121964
|
-
|
|
121965
|
-
|
|
121966
|
-
return this.#reconstructionInfoPromise;
|
|
122146
|
+
}
|
|
122147
|
+
class GlobWalker extends GlobUtil {
|
|
122148
|
+
matches = new Set();
|
|
122149
|
+
constructor(patterns, path, opts) {
|
|
122150
|
+
super(patterns, path, opts);
|
|
121967
122151
|
}
|
|
121968
|
-
|
|
121969
|
-
|
|
121970
|
-
|
|
121971
|
-
|
|
121972
|
-
|
|
121973
|
-
|
|
122152
|
+
matchEmit(e) {
|
|
122153
|
+
this.matches.add(e);
|
|
122154
|
+
}
|
|
122155
|
+
async walk() {
|
|
122156
|
+
if (this.signal?.aborted)
|
|
122157
|
+
throw this.signal.reason;
|
|
122158
|
+
if (this.path.isUnknown()) {
|
|
122159
|
+
await this.path.lstat();
|
|
121974
122160
|
}
|
|
121975
|
-
|
|
121976
|
-
|
|
121977
|
-
|
|
121978
|
-
|
|
121979
|
-
|
|
121980
|
-
|
|
121981
|
-
|
|
121982
|
-
|
|
121983
|
-
|
|
121984
|
-
|
|
121985
|
-
|
|
121986
|
-
await this.#loadReconstructionInfo();
|
|
122161
|
+
await new Promise((res, rej) => {
|
|
122162
|
+
this.walkCB(this.path, this.patterns, () => {
|
|
122163
|
+
if (this.signal?.aborted) {
|
|
122164
|
+
rej(this.signal.reason);
|
|
122165
|
+
}
|
|
122166
|
+
else {
|
|
122167
|
+
res(this.matches);
|
|
122168
|
+
}
|
|
122169
|
+
});
|
|
122170
|
+
});
|
|
122171
|
+
return this.matches;
|
|
121987
122172
|
}
|
|
121988
|
-
|
|
121989
|
-
|
|
121990
|
-
|
|
122173
|
+
walkSync() {
|
|
122174
|
+
if (this.signal?.aborted)
|
|
122175
|
+
throw this.signal.reason;
|
|
122176
|
+
if (this.path.isUnknown()) {
|
|
122177
|
+
this.path.lstatSync();
|
|
122178
|
+
}
|
|
122179
|
+
// nothing for the callback to do, because this never pauses
|
|
122180
|
+
this.walkCBSync(this.path, this.patterns, () => {
|
|
122181
|
+
if (this.signal?.aborted)
|
|
122182
|
+
throw this.signal.reason;
|
|
122183
|
+
});
|
|
122184
|
+
return this.matches;
|
|
121991
122185
|
}
|
|
121992
|
-
|
|
121993
|
-
|
|
121994
|
-
|
|
121995
|
-
|
|
121996
|
-
|
|
121997
|
-
|
|
121998
|
-
|
|
122186
|
+
}
|
|
122187
|
+
class GlobStream extends GlobUtil {
|
|
122188
|
+
results;
|
|
122189
|
+
constructor(patterns, path, opts) {
|
|
122190
|
+
super(patterns, path, opts);
|
|
122191
|
+
this.results = new Minipass({
|
|
122192
|
+
signal: this.signal,
|
|
122193
|
+
objectMode: true,
|
|
122194
|
+
});
|
|
122195
|
+
this.results.on('drain', () => this.resume());
|
|
122196
|
+
this.results.on('resume', () => this.resume());
|
|
121999
122197
|
}
|
|
122000
|
-
|
|
122001
|
-
|
|
122002
|
-
|
|
122003
|
-
|
|
122004
|
-
|
|
122005
|
-
|
|
122006
|
-
|
|
122007
|
-
if (
|
|
122008
|
-
|
|
122198
|
+
matchEmit(e) {
|
|
122199
|
+
this.results.write(e);
|
|
122200
|
+
if (!this.results.flowing)
|
|
122201
|
+
this.pause();
|
|
122202
|
+
}
|
|
122203
|
+
stream() {
|
|
122204
|
+
const target = this.path;
|
|
122205
|
+
if (target.isUnknown()) {
|
|
122206
|
+
target.lstat().then(() => {
|
|
122207
|
+
this.walkCB(target, this.patterns, () => this.results.end());
|
|
122208
|
+
});
|
|
122009
122209
|
}
|
|
122010
|
-
|
|
122011
|
-
|
|
122012
|
-
throw new Error(`Failed to find range list for term ${term.hash}`);
|
|
122210
|
+
else {
|
|
122211
|
+
this.walkCB(target, this.patterns, () => this.results.end());
|
|
122013
122212
|
}
|
|
122014
|
-
|
|
122015
|
-
|
|
122016
|
-
|
|
122017
|
-
|
|
122018
|
-
|
|
122019
|
-
for (const range2 of termRanges) {
|
|
122020
|
-
for (let chunk2 of range2.data) {
|
|
122021
|
-
if (readBytesToSkip) {
|
|
122022
|
-
const skipped = Math.min(readBytesToSkip, chunk2.byteLength);
|
|
122023
|
-
chunk2 = chunk2.slice(skipped);
|
|
122024
|
-
readBytesToSkip -= skipped;
|
|
122025
|
-
if (!chunk2.byteLength) {
|
|
122026
|
-
continue;
|
|
122027
|
-
}
|
|
122028
|
-
}
|
|
122029
|
-
if (chunk2.byteLength > maxBytes - totalBytesRead) {
|
|
122030
|
-
chunk2 = chunk2.slice(0, maxBytes - totalBytesRead);
|
|
122031
|
-
}
|
|
122032
|
-
totalBytesRead += chunk2.byteLength;
|
|
122033
|
-
yield range2.refCount > 1 ? chunk2.slice() : chunk2;
|
|
122034
|
-
listener?.({ event: "progress", progress: { read: totalBytesRead, total: maxBytes } });
|
|
122035
|
-
if (totalBytesRead >= maxBytes) {
|
|
122036
|
-
break rangeLoop;
|
|
122037
|
-
}
|
|
122038
|
-
}
|
|
122039
|
-
}
|
|
122040
|
-
rangeList.remove(term.range.start, term.range.end);
|
|
122041
|
-
continue;
|
|
122042
|
-
}
|
|
122213
|
+
return this.results;
|
|
122214
|
+
}
|
|
122215
|
+
streamSync() {
|
|
122216
|
+
if (this.path.isUnknown()) {
|
|
122217
|
+
this.path.lstatSync();
|
|
122043
122218
|
}
|
|
122044
|
-
|
|
122045
|
-
|
|
122046
|
-
|
|
122047
|
-
|
|
122048
|
-
|
|
122049
|
-
|
|
122050
|
-
|
|
122219
|
+
this.walkCBSync(this.path, this.patterns, () => this.results.end());
|
|
122220
|
+
return this.results;
|
|
122221
|
+
}
|
|
122222
|
+
}
|
|
122223
|
+
|
|
122224
|
+
// if no process global, just call it linux.
|
|
122225
|
+
// so we default to case-sensitive, / separators
|
|
122226
|
+
const defaultPlatform = (typeof process === 'object' &&
|
|
122227
|
+
process &&
|
|
122228
|
+
typeof process.platform === 'string') ?
|
|
122229
|
+
process.platform
|
|
122230
|
+
: 'linux';
|
|
122231
|
+
/**
|
|
122232
|
+
* An object that can perform glob pattern traversals.
|
|
122233
|
+
*/
|
|
122234
|
+
class Glob {
|
|
122235
|
+
absolute;
|
|
122236
|
+
cwd;
|
|
122237
|
+
root;
|
|
122238
|
+
dot;
|
|
122239
|
+
dotRelative;
|
|
122240
|
+
follow;
|
|
122241
|
+
ignore;
|
|
122242
|
+
magicalBraces;
|
|
122243
|
+
mark;
|
|
122244
|
+
matchBase;
|
|
122245
|
+
maxDepth;
|
|
122246
|
+
nobrace;
|
|
122247
|
+
nocase;
|
|
122248
|
+
nodir;
|
|
122249
|
+
noext;
|
|
122250
|
+
noglobstar;
|
|
122251
|
+
pattern;
|
|
122252
|
+
platform;
|
|
122253
|
+
realpath;
|
|
122254
|
+
scurry;
|
|
122255
|
+
stat;
|
|
122256
|
+
signal;
|
|
122257
|
+
windowsPathsNoEscape;
|
|
122258
|
+
withFileTypes;
|
|
122259
|
+
includeChildMatches;
|
|
122260
|
+
/**
|
|
122261
|
+
* The options provided to the constructor.
|
|
122262
|
+
*/
|
|
122263
|
+
opts;
|
|
122264
|
+
/**
|
|
122265
|
+
* An array of parsed immutable {@link Pattern} objects.
|
|
122266
|
+
*/
|
|
122267
|
+
patterns;
|
|
122268
|
+
/**
|
|
122269
|
+
* All options are stored as properties on the `Glob` object.
|
|
122270
|
+
*
|
|
122271
|
+
* See {@link GlobOptions} for full options descriptions.
|
|
122272
|
+
*
|
|
122273
|
+
* Note that a previous `Glob` object can be passed as the
|
|
122274
|
+
* `GlobOptions` to another `Glob` instantiation to re-use settings
|
|
122275
|
+
* and caches with a new pattern.
|
|
122276
|
+
*
|
|
122277
|
+
* Traversal functions can be called multiple times to run the walk
|
|
122278
|
+
* again.
|
|
122279
|
+
*/
|
|
122280
|
+
constructor(pattern, opts) {
|
|
122281
|
+
/* c8 ignore start */
|
|
122282
|
+
if (!opts)
|
|
122283
|
+
throw new TypeError('glob options required');
|
|
122284
|
+
/* c8 ignore stop */
|
|
122285
|
+
this.withFileTypes = !!opts.withFileTypes;
|
|
122286
|
+
this.signal = opts.signal;
|
|
122287
|
+
this.follow = !!opts.follow;
|
|
122288
|
+
this.dot = !!opts.dot;
|
|
122289
|
+
this.dotRelative = !!opts.dotRelative;
|
|
122290
|
+
this.nodir = !!opts.nodir;
|
|
122291
|
+
this.mark = !!opts.mark;
|
|
122292
|
+
if (!opts.cwd) {
|
|
122293
|
+
this.cwd = '';
|
|
122051
122294
|
}
|
|
122052
|
-
|
|
122053
|
-
|
|
122054
|
-
log("readBytesToSkip", readBytesToSkip);
|
|
122055
|
-
let resp = await customFetch(fetchInfo.url, {
|
|
122056
|
-
headers: {
|
|
122057
|
-
Range: `bytes=${fetchInfo.url_range.start}-${fetchInfo.url_range.end}`
|
|
122058
|
-
}
|
|
122059
|
-
});
|
|
122060
|
-
if (resp.status === 403) {
|
|
122061
|
-
reconstructionInfo = await reloadReconstructionInfo();
|
|
122062
|
-
resp = await customFetch(fetchInfo.url, {
|
|
122063
|
-
headers: {
|
|
122064
|
-
Range: `bytes=${fetchInfo.url_range.start}-${fetchInfo.url_range.end}`
|
|
122065
|
-
}
|
|
122066
|
-
});
|
|
122295
|
+
else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) {
|
|
122296
|
+
opts.cwd = require$$0$l.fileURLToPath(opts.cwd);
|
|
122067
122297
|
}
|
|
122068
|
-
|
|
122069
|
-
|
|
122298
|
+
this.cwd = opts.cwd || '';
|
|
122299
|
+
this.root = opts.root;
|
|
122300
|
+
this.magicalBraces = !!opts.magicalBraces;
|
|
122301
|
+
this.nobrace = !!opts.nobrace;
|
|
122302
|
+
this.noext = !!opts.noext;
|
|
122303
|
+
this.realpath = !!opts.realpath;
|
|
122304
|
+
this.absolute = opts.absolute;
|
|
122305
|
+
this.includeChildMatches = opts.includeChildMatches !== false;
|
|
122306
|
+
this.noglobstar = !!opts.noglobstar;
|
|
122307
|
+
this.matchBase = !!opts.matchBase;
|
|
122308
|
+
this.maxDepth =
|
|
122309
|
+
typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity;
|
|
122310
|
+
this.stat = !!opts.stat;
|
|
122311
|
+
this.ignore = opts.ignore;
|
|
122312
|
+
if (this.withFileTypes && this.absolute !== undefined) {
|
|
122313
|
+
throw new Error('cannot set absolute and withFileTypes:true');
|
|
122070
122314
|
}
|
|
122071
|
-
|
|
122072
|
-
|
|
122073
|
-
resp.headers.get("content-length"),
|
|
122074
|
-
"range",
|
|
122075
|
-
fetchInfo.url_range,
|
|
122076
|
-
resp.headers.get("content-range")
|
|
122077
|
-
);
|
|
122078
|
-
const reader = resp.body?.getReader();
|
|
122079
|
-
if (!reader) {
|
|
122080
|
-
throw new Error("Failed to get reader from response body");
|
|
122315
|
+
if (typeof pattern === 'string') {
|
|
122316
|
+
pattern = [pattern];
|
|
122081
122317
|
}
|
|
122082
|
-
|
|
122083
|
-
|
|
122084
|
-
|
|
122085
|
-
|
|
122086
|
-
|
|
122087
|
-
|
|
122088
|
-
|
|
122089
|
-
|
|
122090
|
-
|
|
122091
|
-
|
|
122092
|
-
log("read", result.value?.byteLength, "bytes", "total read", totalBytesRead, "toSkip", readBytesToSkip);
|
|
122093
|
-
if (!result.value) {
|
|
122094
|
-
log("no data in result, cancelled", result);
|
|
122095
|
-
continue;
|
|
122096
|
-
}
|
|
122097
|
-
totalFetchBytes += result.value.byteLength;
|
|
122098
|
-
if (leftoverBytes) {
|
|
122099
|
-
result.value = combineUint8Arrays(leftoverBytes, result.value);
|
|
122100
|
-
leftoverBytes = void 0;
|
|
122318
|
+
this.windowsPathsNoEscape =
|
|
122319
|
+
!!opts.windowsPathsNoEscape ||
|
|
122320
|
+
opts.allowWindowsEscape ===
|
|
122321
|
+
false;
|
|
122322
|
+
if (this.windowsPathsNoEscape) {
|
|
122323
|
+
pattern = pattern.map(p => p.replace(/\\/g, '/'));
|
|
122324
|
+
}
|
|
122325
|
+
if (this.matchBase) {
|
|
122326
|
+
if (opts.noglobstar) {
|
|
122327
|
+
throw new TypeError('base matching requires globstar');
|
|
122101
122328
|
}
|
|
122102
|
-
|
|
122103
|
-
|
|
122104
|
-
|
|
122105
|
-
|
|
122106
|
-
|
|
122107
|
-
|
|
122108
|
-
|
|
122109
|
-
|
|
122110
|
-
|
|
122111
|
-
|
|
122112
|
-
uncompressed_length: header.getUint8(5) | header.getUint8(6) << 8 | header.getUint8(7) << 16
|
|
122113
|
-
};
|
|
122114
|
-
log("chunk header", chunkHeader, "to skip", readBytesToSkip);
|
|
122115
|
-
if (chunkHeader.version !== 0) {
|
|
122116
|
-
throw new Error(`Unsupported chunk version ${chunkHeader.version}`);
|
|
122117
|
-
}
|
|
122118
|
-
if (chunkHeader.compression_scheme !== 0 /* None */ && chunkHeader.compression_scheme !== 1 /* LZ4 */ && chunkHeader.compression_scheme !== 2 /* ByteGroupingLZ4 */) {
|
|
122119
|
-
throw new Error(
|
|
122120
|
-
`Unsupported compression scheme ${compressionSchemeLabels[chunkHeader.compression_scheme] ?? chunkHeader.compression_scheme}`
|
|
122121
|
-
);
|
|
122122
|
-
}
|
|
122123
|
-
if (result.value.byteLength < chunkHeader.compressed_length + XET_CHUNK_HEADER_BYTES) {
|
|
122124
|
-
leftoverBytes = result.value;
|
|
122125
|
-
continue fetchData;
|
|
122126
|
-
}
|
|
122127
|
-
result.value = result.value.slice(XET_CHUNK_HEADER_BYTES);
|
|
122128
|
-
let uncompressed = chunkHeader.compression_scheme === 1 /* LZ4 */ ? decompress(result.value.slice(0, chunkHeader.compressed_length), chunkHeader.uncompressed_length) : chunkHeader.compression_scheme === 2 /* ByteGroupingLZ4 */ ? bg4_regroup_bytes(
|
|
122129
|
-
decompress(
|
|
122130
|
-
result.value.slice(0, chunkHeader.compressed_length),
|
|
122131
|
-
chunkHeader.uncompressed_length
|
|
122132
|
-
)
|
|
122133
|
-
) : result.value.slice(0, chunkHeader.compressed_length);
|
|
122134
|
-
const range2 = ranges.find((range3) => chunkIndex >= range3.start && chunkIndex < range3.end);
|
|
122135
|
-
const shouldYield = chunkIndex >= term.range.start && chunkIndex < term.range.end;
|
|
122136
|
-
const minRefCountToStore = shouldYield ? 2 : 1;
|
|
122137
|
-
let stored = false;
|
|
122138
|
-
if (range2 && range2.refCount >= minRefCountToStore) {
|
|
122139
|
-
range2.data ??= [];
|
|
122140
|
-
range2.data.push(uncompressed);
|
|
122141
|
-
stored = true;
|
|
122142
|
-
}
|
|
122143
|
-
if (shouldYield) {
|
|
122144
|
-
if (readBytesToSkip) {
|
|
122145
|
-
const skipped = Math.min(readBytesToSkip, uncompressed.byteLength);
|
|
122146
|
-
uncompressed = uncompressed.slice(readBytesToSkip);
|
|
122147
|
-
readBytesToSkip -= skipped;
|
|
122148
|
-
}
|
|
122149
|
-
if (uncompressed.byteLength > maxBytes - totalBytesRead) {
|
|
122150
|
-
uncompressed = uncompressed.slice(0, maxBytes - totalBytesRead);
|
|
122151
|
-
}
|
|
122152
|
-
if (uncompressed.byteLength) {
|
|
122153
|
-
log(
|
|
122154
|
-
"yield",
|
|
122155
|
-
uncompressed.byteLength,
|
|
122156
|
-
"bytes",
|
|
122157
|
-
result.value.byteLength,
|
|
122158
|
-
"total read",
|
|
122159
|
-
totalBytesRead,
|
|
122160
|
-
stored
|
|
122161
|
-
);
|
|
122162
|
-
totalBytesRead += uncompressed.byteLength;
|
|
122163
|
-
yield stored ? uncompressed.slice() : uncompressed;
|
|
122164
|
-
listener?.({ event: "progress", progress: { read: totalBytesRead, total: maxBytes } });
|
|
122165
|
-
}
|
|
122166
|
-
}
|
|
122167
|
-
chunkIndex++;
|
|
122168
|
-
result.value = result.value.slice(chunkHeader.compressed_length);
|
|
122329
|
+
pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`));
|
|
122330
|
+
}
|
|
122331
|
+
this.pattern = pattern;
|
|
122332
|
+
this.platform = opts.platform || defaultPlatform;
|
|
122333
|
+
this.opts = { ...opts, platform: this.platform };
|
|
122334
|
+
if (opts.scurry) {
|
|
122335
|
+
this.scurry = opts.scurry;
|
|
122336
|
+
if (opts.nocase !== undefined &&
|
|
122337
|
+
opts.nocase !== opts.scurry.nocase) {
|
|
122338
|
+
throw new Error('nocase option contradicts provided scurry option');
|
|
122169
122339
|
}
|
|
122170
|
-
}
|
|
122171
|
-
if (done && totalBytesRead < maxBytes && totalFetchBytes < fetchInfo.url_range.end - fetchInfo.url_range.start + 1) {
|
|
122172
|
-
log("done", done, "total read", totalBytesRead, maxBytes, totalFetchBytes);
|
|
122173
|
-
log("failed to fetch all data for term", term.hash);
|
|
122174
|
-
throw new Error(
|
|
122175
|
-
`Failed to fetch all data for term ${term.hash}, fetched ${totalFetchBytes} bytes out of ${fetchInfo.url_range.end - fetchInfo.url_range.start + 1}`
|
|
122176
|
-
);
|
|
122177
122340
|
}
|
|
122178
|
-
|
|
122179
|
-
|
|
122180
|
-
|
|
122181
|
-
|
|
122341
|
+
else {
|
|
122342
|
+
const Scurry = opts.platform === 'win32' ? PathScurryWin32
|
|
122343
|
+
: opts.platform === 'darwin' ? PathScurryDarwin
|
|
122344
|
+
: opts.platform ? PathScurryPosix
|
|
122345
|
+
: PathScurry;
|
|
122346
|
+
this.scurry = new Scurry(this.cwd, {
|
|
122347
|
+
nocase: opts.nocase,
|
|
122348
|
+
fs: opts.fs,
|
|
122349
|
+
});
|
|
122350
|
+
}
|
|
122351
|
+
this.nocase = this.scurry.nocase;
|
|
122352
|
+
// If you do nocase:true on a case-sensitive file system, then
|
|
122353
|
+
// we need to use regexps instead of strings for non-magic
|
|
122354
|
+
// path portions, because statting `aBc` won't return results
|
|
122355
|
+
// for the file `AbC` for example.
|
|
122356
|
+
const nocaseMagicOnly = this.platform === 'darwin' || this.platform === 'win32';
|
|
122357
|
+
const mmo = {
|
|
122358
|
+
// default nocase based on platform
|
|
122359
|
+
...opts,
|
|
122360
|
+
dot: this.dot,
|
|
122361
|
+
matchBase: this.matchBase,
|
|
122362
|
+
nobrace: this.nobrace,
|
|
122363
|
+
nocase: this.nocase,
|
|
122364
|
+
nocaseMagicOnly,
|
|
122365
|
+
nocomment: true,
|
|
122366
|
+
noext: this.noext,
|
|
122367
|
+
nonegate: true,
|
|
122368
|
+
optimizationLevel: 2,
|
|
122369
|
+
platform: this.platform,
|
|
122370
|
+
windowsPathsNoEscape: this.windowsPathsNoEscape,
|
|
122371
|
+
debug: !!this.opts.debug,
|
|
122372
|
+
};
|
|
122373
|
+
const mms = this.pattern.map(p => new Minimatch(p, mmo));
|
|
122374
|
+
const [matchSet, globParts] = mms.reduce((set, m) => {
|
|
122375
|
+
set[0].push(...m.set);
|
|
122376
|
+
set[1].push(...m.globParts);
|
|
122377
|
+
return set;
|
|
122378
|
+
}, [[], []]);
|
|
122379
|
+
this.patterns = matchSet.map((set, i) => {
|
|
122380
|
+
const g = globParts[i];
|
|
122381
|
+
/* c8 ignore start */
|
|
122382
|
+
if (!g)
|
|
122383
|
+
throw new Error('invalid pattern object');
|
|
122384
|
+
/* c8 ignore stop */
|
|
122385
|
+
return new Pattern(set, g, 0, this.platform);
|
|
122386
|
+
});
|
|
122182
122387
|
}
|
|
122183
|
-
|
|
122184
|
-
|
|
122185
|
-
|
|
122186
|
-
|
|
122187
|
-
|
|
122188
|
-
|
|
122189
|
-
|
|
122190
|
-
|
|
122191
|
-
|
|
122192
|
-
|
|
122193
|
-
|
|
122194
|
-
|
|
122195
|
-
|
|
122196
|
-
|
|
122197
|
-
|
|
122198
|
-
|
|
122199
|
-
}
|
|
122200
|
-
},
|
|
122201
|
-
type: "bytes"
|
|
122202
|
-
// todo: when Safari supports it, add autoAllocateChunkSize param
|
|
122203
|
-
},
|
|
122204
|
-
// todo : use ByteLengthQueuingStrategy when there's good support for it, currently in Node.js it fails due to size being a function
|
|
122205
|
-
{
|
|
122206
|
-
highWaterMark: 1e3
|
|
122207
|
-
// 1_000 chunks for ~1MB of RAM
|
|
122208
|
-
}
|
|
122209
|
-
);
|
|
122210
|
-
}
|
|
122211
|
-
async arrayBuffer() {
|
|
122212
|
-
const result = await this.#fetch();
|
|
122213
|
-
return new Response(result).arrayBuffer();
|
|
122214
|
-
}
|
|
122215
|
-
async text() {
|
|
122216
|
-
const result = await this.#fetch();
|
|
122217
|
-
return new Response(result).text();
|
|
122218
|
-
}
|
|
122219
|
-
async response() {
|
|
122220
|
-
const result = await this.#fetch();
|
|
122221
|
-
return new Response(result);
|
|
122222
|
-
}
|
|
122223
|
-
stream() {
|
|
122224
|
-
const stream = new TransformStream();
|
|
122225
|
-
this.#fetch().then((response) => response.pipeThrough(stream)).catch((error) => stream.writable.abort(error.message));
|
|
122226
|
-
return stream.readable;
|
|
122227
|
-
}
|
|
122228
|
-
};
|
|
122229
|
-
var jwtPromises = /* @__PURE__ */ new Map();
|
|
122230
|
-
var jwts = /* @__PURE__ */ new Map();
|
|
122231
|
-
function cacheKey(params) {
|
|
122232
|
-
return JSON.stringify([params.refreshUrl, params.initialAccessToken]);
|
|
122233
|
-
}
|
|
122234
|
-
function bg4_regroup_bytes(bytes) {
|
|
122235
|
-
const split = Math.floor(bytes.byteLength / 4);
|
|
122236
|
-
const rem = bytes.byteLength % 4;
|
|
122237
|
-
const g1_pos = split + (rem >= 1 ? 1 : 0);
|
|
122238
|
-
const g2_pos = g1_pos + split + (rem >= 2 ? 1 : 0);
|
|
122239
|
-
const g3_pos = g2_pos + split + (rem == 3 ? 1 : 0);
|
|
122240
|
-
const ret = new Uint8Array(bytes.byteLength);
|
|
122241
|
-
for (let i = 0, j = 0; i < bytes.byteLength; i += 4, j++) {
|
|
122242
|
-
ret[i] = bytes[j];
|
|
122243
|
-
}
|
|
122244
|
-
for (let i = 1, j = g1_pos; i < bytes.byteLength; i += 4, j++) {
|
|
122245
|
-
ret[i] = bytes[j];
|
|
122246
|
-
}
|
|
122247
|
-
for (let i = 2, j = g2_pos; i < bytes.byteLength; i += 4, j++) {
|
|
122248
|
-
ret[i] = bytes[j];
|
|
122249
|
-
}
|
|
122250
|
-
for (let i = 3, j = g3_pos; i < bytes.byteLength; i += 4, j++) {
|
|
122251
|
-
ret[i] = bytes[j];
|
|
122252
|
-
}
|
|
122253
|
-
return ret;
|
|
122254
|
-
}
|
|
122255
|
-
async function getAccessToken(initialAccessToken, customFetch, refreshUrl) {
|
|
122256
|
-
const key = cacheKey({ refreshUrl, initialAccessToken });
|
|
122257
|
-
const jwt = jwts.get(key);
|
|
122258
|
-
if (jwt && jwt.expiresAt > new Date(Date.now() + JWT_SAFETY_PERIOD)) {
|
|
122259
|
-
return { accessToken: jwt.accessToken, casUrl: jwt.casUrl };
|
|
122260
|
-
}
|
|
122261
|
-
const existingPromise = jwtPromises.get(key);
|
|
122262
|
-
if (existingPromise) {
|
|
122263
|
-
return existingPromise;
|
|
122264
|
-
}
|
|
122265
|
-
const promise = (async () => {
|
|
122266
|
-
const resp = await customFetch(refreshUrl, {
|
|
122267
|
-
headers: {
|
|
122268
|
-
...initialAccessToken ? {
|
|
122269
|
-
Authorization: `Bearer ${initialAccessToken}`
|
|
122270
|
-
} : {}
|
|
122271
|
-
}
|
|
122272
|
-
});
|
|
122273
|
-
if (!resp.ok) {
|
|
122274
|
-
throw new Error(`Failed to get JWT token: ${resp.status} ${await resp.text()}`);
|
|
122388
|
+
async walk() {
|
|
122389
|
+
// Walkers always return array of Path objects, so we just have to
|
|
122390
|
+
// coerce them into the right shape. It will have already called
|
|
122391
|
+
// realpath() if the option was set to do so, so we know that's cached.
|
|
122392
|
+
// start out knowing the cwd, at least
|
|
122393
|
+
return [
|
|
122394
|
+
...(await new GlobWalker(this.patterns, this.scurry.cwd, {
|
|
122395
|
+
...this.opts,
|
|
122396
|
+
maxDepth: this.maxDepth !== Infinity ?
|
|
122397
|
+
this.maxDepth + this.scurry.cwd.depth()
|
|
122398
|
+
: Infinity,
|
|
122399
|
+
platform: this.platform,
|
|
122400
|
+
nocase: this.nocase,
|
|
122401
|
+
includeChildMatches: this.includeChildMatches,
|
|
122402
|
+
}).walk()),
|
|
122403
|
+
];
|
|
122275
122404
|
}
|
|
122276
|
-
|
|
122277
|
-
|
|
122278
|
-
|
|
122279
|
-
|
|
122280
|
-
|
|
122281
|
-
|
|
122282
|
-
|
|
122283
|
-
|
|
122284
|
-
|
|
122285
|
-
|
|
122286
|
-
|
|
122287
|
-
|
|
122288
|
-
}
|
|
122405
|
+
walkSync() {
|
|
122406
|
+
return [
|
|
122407
|
+
...new GlobWalker(this.patterns, this.scurry.cwd, {
|
|
122408
|
+
...this.opts,
|
|
122409
|
+
maxDepth: this.maxDepth !== Infinity ?
|
|
122410
|
+
this.maxDepth + this.scurry.cwd.depth()
|
|
122411
|
+
: Infinity,
|
|
122412
|
+
platform: this.platform,
|
|
122413
|
+
nocase: this.nocase,
|
|
122414
|
+
includeChildMatches: this.includeChildMatches,
|
|
122415
|
+
}).walkSync(),
|
|
122416
|
+
];
|
|
122289
122417
|
}
|
|
122290
|
-
|
|
122291
|
-
|
|
122292
|
-
|
|
122293
|
-
|
|
122294
|
-
|
|
122418
|
+
stream() {
|
|
122419
|
+
return new GlobStream(this.patterns, this.scurry.cwd, {
|
|
122420
|
+
...this.opts,
|
|
122421
|
+
maxDepth: this.maxDepth !== Infinity ?
|
|
122422
|
+
this.maxDepth + this.scurry.cwd.depth()
|
|
122423
|
+
: Infinity,
|
|
122424
|
+
platform: this.platform,
|
|
122425
|
+
nocase: this.nocase,
|
|
122426
|
+
includeChildMatches: this.includeChildMatches,
|
|
122427
|
+
}).stream();
|
|
122428
|
+
}
|
|
122429
|
+
streamSync() {
|
|
122430
|
+
return new GlobStream(this.patterns, this.scurry.cwd, {
|
|
122431
|
+
...this.opts,
|
|
122432
|
+
maxDepth: this.maxDepth !== Infinity ?
|
|
122433
|
+
this.maxDepth + this.scurry.cwd.depth()
|
|
122434
|
+
: Infinity,
|
|
122435
|
+
platform: this.platform,
|
|
122436
|
+
nocase: this.nocase,
|
|
122437
|
+
includeChildMatches: this.includeChildMatches,
|
|
122438
|
+
}).streamSync();
|
|
122439
|
+
}
|
|
122440
|
+
/**
|
|
122441
|
+
* Default sync iteration function. Returns a Generator that
|
|
122442
|
+
* iterates over the results.
|
|
122443
|
+
*/
|
|
122444
|
+
iterateSync() {
|
|
122445
|
+
return this.streamSync()[Symbol.iterator]();
|
|
122446
|
+
}
|
|
122447
|
+
[Symbol.iterator]() {
|
|
122448
|
+
return this.iterateSync();
|
|
122449
|
+
}
|
|
122450
|
+
/**
|
|
122451
|
+
* Default async iteration function. Returns an AsyncGenerator that
|
|
122452
|
+
* iterates over the results.
|
|
122453
|
+
*/
|
|
122454
|
+
iterate() {
|
|
122455
|
+
return this.stream()[Symbol.asyncIterator]();
|
|
122456
|
+
}
|
|
122457
|
+
[Symbol.asyncIterator]() {
|
|
122458
|
+
return this.iterate();
|
|
122295
122459
|
}
|
|
122296
|
-
jwts.set(key, jwt2);
|
|
122297
|
-
return {
|
|
122298
|
-
accessToken: json.accessToken,
|
|
122299
|
-
casUrl: json.casUrl
|
|
122300
|
-
};
|
|
122301
|
-
})();
|
|
122302
|
-
jwtPromises.set(key, promise);
|
|
122303
|
-
return promise;
|
|
122304
122460
|
}
|
|
122305
122461
|
|
|
122306
|
-
|
|
122307
|
-
|
|
122308
|
-
|
|
122309
|
-
|
|
122310
|
-
|
|
122311
|
-
|
|
122312
|
-
|
|
122313
|
-
|
|
122314
|
-
|
|
122315
|
-
|
|
122316
|
-
|
|
122317
|
-
|
|
122318
|
-
|
|
122319
|
-
|
|
122320
|
-
const supportRange = response.headers.get("accept-ranges") === "bytes";
|
|
122321
|
-
if (!supportRange || size < (opts?.cacheBelow ?? 1e6)) {
|
|
122322
|
-
return await (await customFetch(url)).blob();
|
|
122462
|
+
/**
|
|
122463
|
+
* Return true if the patterns provided contain any magic glob characters,
|
|
122464
|
+
* given the options provided.
|
|
122465
|
+
*
|
|
122466
|
+
* Brace expansion is not considered "magic" unless the `magicalBraces` option
|
|
122467
|
+
* is set, as brace expansion just turns one string into an array of strings.
|
|
122468
|
+
* So a pattern like `'x{a,b}y'` would return `false`, because `'xay'` and
|
|
122469
|
+
* `'xby'` both do not contain any magic glob characters, and it's treated the
|
|
122470
|
+
* same as if you had called it on `['xay', 'xby']`. When `magicalBraces:true`
|
|
122471
|
+
* is in the options, brace expansion _is_ treated as a pattern having magic.
|
|
122472
|
+
*/
|
|
122473
|
+
const hasMagic = (pattern, options = {}) => {
|
|
122474
|
+
if (!Array.isArray(pattern)) {
|
|
122475
|
+
pattern = [pattern];
|
|
122323
122476
|
}
|
|
122324
|
-
|
|
122325
|
-
|
|
122326
|
-
|
|
122327
|
-
start;
|
|
122328
|
-
end;
|
|
122329
|
-
contentType;
|
|
122330
|
-
full;
|
|
122331
|
-
fetch;
|
|
122332
|
-
accessToken;
|
|
122333
|
-
constructor(url, start, end, contentType, full, customFetch, accessToken) {
|
|
122334
|
-
super([]);
|
|
122335
|
-
this.url = url;
|
|
122336
|
-
this.start = start;
|
|
122337
|
-
this.end = end;
|
|
122338
|
-
this.contentType = contentType;
|
|
122339
|
-
this.full = full;
|
|
122340
|
-
this.fetch = customFetch;
|
|
122341
|
-
this.accessToken = accessToken;
|
|
122342
|
-
}
|
|
122343
|
-
get size() {
|
|
122344
|
-
return this.end - this.start;
|
|
122345
|
-
}
|
|
122346
|
-
get type() {
|
|
122347
|
-
return this.contentType;
|
|
122348
|
-
}
|
|
122349
|
-
slice(start = 0, end = this.size) {
|
|
122350
|
-
const slice = new WebBlob(
|
|
122351
|
-
this.url,
|
|
122352
|
-
this.start + start,
|
|
122353
|
-
Math.min(this.start + end, this.end),
|
|
122354
|
-
this.contentType,
|
|
122355
|
-
start === 0 && end === this.size ? this.full : false,
|
|
122356
|
-
this.fetch,
|
|
122357
|
-
this.accessToken
|
|
122358
|
-
);
|
|
122359
|
-
return slice;
|
|
122360
|
-
}
|
|
122361
|
-
async arrayBuffer() {
|
|
122362
|
-
const result = await this.fetchRange();
|
|
122363
|
-
return result.arrayBuffer();
|
|
122364
|
-
}
|
|
122365
|
-
async text() {
|
|
122366
|
-
const result = await this.fetchRange();
|
|
122367
|
-
return result.text();
|
|
122368
|
-
}
|
|
122369
|
-
stream() {
|
|
122370
|
-
const stream = new TransformStream();
|
|
122371
|
-
this.fetchRange().then((response) => response.body?.pipeThrough(stream)).catch((error) => stream.writable.abort(error.message));
|
|
122372
|
-
return stream.readable;
|
|
122373
|
-
}
|
|
122374
|
-
fetchRange() {
|
|
122375
|
-
const fetch2 = this.fetch;
|
|
122376
|
-
if (this.full) {
|
|
122377
|
-
return fetch2(this.url, {
|
|
122378
|
-
...this.accessToken && {
|
|
122379
|
-
headers: {
|
|
122380
|
-
Authorization: `Bearer ${this.accessToken}`
|
|
122381
|
-
}
|
|
122382
|
-
}
|
|
122383
|
-
}).then((resp) => resp.ok ? resp : createApiError(resp));
|
|
122477
|
+
for (const p of pattern) {
|
|
122478
|
+
if (new Minimatch(p, options).hasMagic())
|
|
122479
|
+
return true;
|
|
122384
122480
|
}
|
|
122385
|
-
return
|
|
122386
|
-
headers: {
|
|
122387
|
-
Range: `bytes=${this.start}-${this.end - 1}`,
|
|
122388
|
-
...this.accessToken && { Authorization: `Bearer ${this.accessToken}` }
|
|
122389
|
-
}
|
|
122390
|
-
}).then((resp) => resp.ok ? resp : createApiError(resp));
|
|
122391
|
-
}
|
|
122481
|
+
return false;
|
|
122392
122482
|
};
|
|
122393
122483
|
|
|
122394
|
-
|
|
122395
|
-
|
|
122396
|
-
const regex = /<(https?:[/][/][^>]+)>;\s+rel="([^"]+)"/g;
|
|
122397
|
-
return Object.fromEntries([...header.matchAll(regex)].map(([, url, rel]) => [rel, url]));
|
|
122484
|
+
function globStreamSync(pattern, options = {}) {
|
|
122485
|
+
return new Glob(pattern, options).streamSync();
|
|
122398
122486
|
}
|
|
122487
|
+
function globStream(pattern, options = {}) {
|
|
122488
|
+
return new Glob(pattern, options).stream();
|
|
122489
|
+
}
|
|
122490
|
+
function globSync(pattern, options = {}) {
|
|
122491
|
+
return new Glob(pattern, options).walkSync();
|
|
122492
|
+
}
|
|
122493
|
+
async function glob_(pattern, options = {}) {
|
|
122494
|
+
return new Glob(pattern, options).walk();
|
|
122495
|
+
}
|
|
122496
|
+
function globIterateSync(pattern, options = {}) {
|
|
122497
|
+
return new Glob(pattern, options).iterateSync();
|
|
122498
|
+
}
|
|
122499
|
+
function globIterate(pattern, options = {}) {
|
|
122500
|
+
return new Glob(pattern, options).iterate();
|
|
122501
|
+
}
|
|
122502
|
+
// aliases: glob.sync.stream() glob.stream.sync() glob.sync() etc
|
|
122503
|
+
const streamSync = globStreamSync;
|
|
122504
|
+
const stream = Object.assign(globStream, { sync: globStreamSync });
|
|
122505
|
+
const iterateSync = globIterateSync;
|
|
122506
|
+
const iterate = Object.assign(globIterate, {
|
|
122507
|
+
sync: globIterateSync,
|
|
122508
|
+
});
|
|
122509
|
+
const sync = Object.assign(globSync, {
|
|
122510
|
+
stream: globStreamSync,
|
|
122511
|
+
iterate: globIterateSync,
|
|
122512
|
+
});
|
|
122513
|
+
const glob = Object.assign(glob_, {
|
|
122514
|
+
glob: glob_,
|
|
122515
|
+
globSync,
|
|
122516
|
+
sync,
|
|
122517
|
+
globStream,
|
|
122518
|
+
stream,
|
|
122519
|
+
globStreamSync,
|
|
122520
|
+
streamSync,
|
|
122521
|
+
globIterate,
|
|
122522
|
+
iterate,
|
|
122523
|
+
globIterateSync,
|
|
122524
|
+
iterateSync,
|
|
122525
|
+
Glob,
|
|
122526
|
+
hasMagic,
|
|
122527
|
+
escape: escape$1,
|
|
122528
|
+
unescape: unescape$1,
|
|
122529
|
+
});
|
|
122530
|
+
glob.glob = glob;
|
|
122399
122531
|
|
|
122400
|
-
|
|
122401
|
-
|
|
122402
|
-
|
|
122403
|
-
const repoId = toRepoId(params.repo);
|
|
122404
|
-
const hubUrl = params.hubUrl ?? HUB_URL;
|
|
122405
|
-
const url = `${hubUrl}/${repoId.type === "model" ? "" : `${repoId.type}s/`}${repoId.name}/${params.raw ? "raw" : "resolve"}/${encodeURIComponent(params.revision ?? "main")}/${params.path}` + (params.noContentDisposition ? "?noContentDisposition=1" : "");
|
|
122406
|
-
const resp = await (params.fetch ?? fetch)(url, {
|
|
122407
|
-
method: "GET",
|
|
122408
|
-
headers: {
|
|
122409
|
-
...accessToken && {
|
|
122410
|
-
Authorization: `Bearer ${accessToken}`
|
|
122411
|
-
},
|
|
122412
|
-
Range: "bytes=0-0",
|
|
122413
|
-
Accept: "application/vnd.xet-fileinfo+json, */*"
|
|
122532
|
+
function matchesQuantizationVariant({ filePath, variant }) {
|
|
122533
|
+
if (!variant) {
|
|
122534
|
+
return false;
|
|
122414
122535
|
}
|
|
122415
|
-
|
|
122416
|
-
|
|
122417
|
-
|
|
122418
|
-
|
|
122419
|
-
|
|
122420
|
-
|
|
122421
|
-
}
|
|
122422
|
-
let size;
|
|
122423
|
-
let xetInfo;
|
|
122424
|
-
if (resp.headers.get("Content-Type")?.includes("application/vnd.xet-fileinfo+json")) {
|
|
122425
|
-
size = parseInt(resp.headers.get("X-Linked-Size") ?? "invalid");
|
|
122426
|
-
if (isNaN(size)) {
|
|
122427
|
-
throw new InvalidApiResponseFormatError("Invalid file size received in X-Linked-Size header");
|
|
122536
|
+
const escapedVariant = variant.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
122537
|
+
const matcher = new RegExp(`(^|[\\-./_])${escapedVariant}(?=[\\-./]|$)`, "i");
|
|
122538
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
122539
|
+
const segments = normalizedPath.split("/").filter(Boolean);
|
|
122540
|
+
if (segments.length === 0) {
|
|
122541
|
+
return false;
|
|
122428
122542
|
}
|
|
122429
|
-
const
|
|
122430
|
-
|
|
122431
|
-
|
|
122432
|
-
try {
|
|
122433
|
-
return new URL(links["xet-reconstruction-info"]);
|
|
122434
|
-
} catch {
|
|
122435
|
-
return null;
|
|
122436
|
-
}
|
|
122437
|
-
})();
|
|
122438
|
-
const refreshUrl = (() => {
|
|
122439
|
-
try {
|
|
122440
|
-
return new URL(links["xet-auth"]);
|
|
122441
|
-
} catch {
|
|
122442
|
-
return null;
|
|
122443
|
-
}
|
|
122444
|
-
})();
|
|
122445
|
-
if (!hash2) {
|
|
122446
|
-
throw new InvalidApiResponseFormatError("No hash received in X-Xet-Hash header");
|
|
122543
|
+
const filename = segments[segments.length - 1].replace(/\.gguf$/i, "");
|
|
122544
|
+
if (matcher.test(filename)) {
|
|
122545
|
+
return true;
|
|
122447
122546
|
}
|
|
122448
|
-
|
|
122449
|
-
|
|
122547
|
+
return segments.slice(0, -1).some(segment => matcher.test(segment));
|
|
122548
|
+
}
|
|
122549
|
+
async function findQuantizedModelTarget({ model, path }) {
|
|
122550
|
+
if (model.source.type === "storage") {
|
|
122551
|
+
throw new Error("Model storage not supported yet");
|
|
122450
122552
|
}
|
|
122451
|
-
|
|
122452
|
-
|
|
122453
|
-
refreshUrl,
|
|
122454
|
-
reconstructionUrl
|
|
122455
|
-
};
|
|
122456
|
-
}
|
|
122457
|
-
if (size === void 0 || isNaN(size)) {
|
|
122458
|
-
const contentRangeHeader = resp.headers.get("content-range");
|
|
122459
|
-
if (!contentRangeHeader) {
|
|
122460
|
-
throw new InvalidApiResponseFormatError("Expected size information");
|
|
122553
|
+
if (model.format !== "gguf") {
|
|
122554
|
+
throw new Error(`Model format not supported: ${model.format}`);
|
|
122461
122555
|
}
|
|
122462
|
-
const [,
|
|
122463
|
-
|
|
122464
|
-
|
|
122465
|
-
|
|
122556
|
+
const [, variant = null] = model.source.slug.split(":");
|
|
122557
|
+
const modelFiles = (await glob("**/*.gguf", {
|
|
122558
|
+
absolute: true,
|
|
122559
|
+
cwd: path,
|
|
122560
|
+
nodir: true
|
|
122561
|
+
})).filter(file => !/(mmproj|clip)/i.test(file));
|
|
122562
|
+
if (modelFiles.length <= 0) {
|
|
122563
|
+
throw new Error(`No models found for format: ${model.format}`);
|
|
122466
122564
|
}
|
|
122467
|
-
|
|
122468
|
-
|
|
122469
|
-
|
|
122470
|
-
|
|
122471
|
-
|
|
122472
|
-
|
|
122473
|
-
|
|
122474
|
-
|
|
122475
|
-
|
|
122476
|
-
// Cannot use resp.url in case it's a S3 url and the user adds an Authorization header to it.
|
|
122477
|
-
url: resp.url && (new URL(resp.url).origin === new URL(hubUrl).origin || resp.headers.get("X-Cache")?.endsWith(" cloudfront")) ? resp.url : url
|
|
122478
|
-
};
|
|
122479
|
-
}
|
|
122480
|
-
|
|
122481
|
-
// src/lib/download-file.ts
|
|
122482
|
-
async function downloadFile(params) {
|
|
122483
|
-
const accessToken = checkCredentials(params);
|
|
122484
|
-
const info = params.downloadInfo ?? await fileDownloadInfo({
|
|
122485
|
-
accessToken,
|
|
122486
|
-
repo: params.repo,
|
|
122487
|
-
path: params.path,
|
|
122488
|
-
revision: params.revision,
|
|
122489
|
-
hubUrl: params.hubUrl,
|
|
122490
|
-
fetch: params.fetch,
|
|
122491
|
-
raw: params.raw
|
|
122492
|
-
});
|
|
122493
|
-
if (!info) {
|
|
122494
|
-
return null;
|
|
122495
|
-
}
|
|
122496
|
-
if (info.xet && params.xet) {
|
|
122497
|
-
return new XetBlob({
|
|
122498
|
-
refreshUrl: info.xet.refreshUrl.href,
|
|
122499
|
-
reconstructionUrl: info.xet.reconstructionUrl.href,
|
|
122500
|
-
fetch: params.fetch,
|
|
122501
|
-
accessToken,
|
|
122502
|
-
size: info.size
|
|
122503
|
-
});
|
|
122504
|
-
}
|
|
122505
|
-
return new WebBlob(new URL(info.url), 0, info.size, "", true, params.fetch ?? fetch, accessToken);
|
|
122565
|
+
modelFiles.sort((left, right) => left.localeCompare(right, undefined, { sensitivity: "base" }));
|
|
122566
|
+
if (!variant) {
|
|
122567
|
+
return modelFiles[0];
|
|
122568
|
+
}
|
|
122569
|
+
const matches = modelFiles.filter(fileName => matchesQuantizationVariant({ filePath: fileName, variant: variant ?? "" }));
|
|
122570
|
+
if (matches.length === 0) {
|
|
122571
|
+
throw new Error(`No model found for format and variant: ${model.format} / ${variant}`);
|
|
122572
|
+
}
|
|
122573
|
+
return matches[0];
|
|
122506
122574
|
}
|
|
122507
122575
|
|
|
122508
|
-
|
|
122509
|
-
|
|
122510
|
-
|
|
122511
|
-
|
|
122512
|
-
|
|
122513
|
-
|
|
122514
|
-
|
|
122515
|
-
|
|
122516
|
-
accept: "application/json",
|
|
122517
|
-
...accessToken ? { Authorization: `Bearer ${accessToken}` } : void 0
|
|
122518
|
-
}
|
|
122519
|
-
});
|
|
122520
|
-
if (!res.ok) {
|
|
122521
|
-
throw await createApiError(res);
|
|
122576
|
+
const VLLM_START_ARGS = ["-m", "vllm.entrypoints.openai.api_server", "--host", "0.0.0.0"];
|
|
122577
|
+
const VLLM_EXECUTABLE = "python3";
|
|
122578
|
+
const DEFAULT_VLLM_CONTEXT_LENGTH = 2048;
|
|
122579
|
+
async function startVLLM({ enginePort, targetDirectory }) {
|
|
122580
|
+
const contextLength = Math.max(1, this.contextLength ?? DEFAULT_VLLM_CONTEXT_LENGTH);
|
|
122581
|
+
let modelPath = targetDirectory;
|
|
122582
|
+
if (this.model.format === "gguf") {
|
|
122583
|
+
modelPath = await findQuantizedModelTarget({ model: this.model, path: targetDirectory });
|
|
122522
122584
|
}
|
|
122523
|
-
const
|
|
122524
|
-
|
|
122525
|
-
|
|
122585
|
+
const engineConfig = this.engineConfig;
|
|
122586
|
+
const device = process.env.VLLM_DEVICE;
|
|
122587
|
+
const dtype = process.env.VLLM_DTYPE;
|
|
122588
|
+
const args = [
|
|
122589
|
+
...VLLM_START_ARGS,
|
|
122590
|
+
"--port",
|
|
122591
|
+
String(enginePort),
|
|
122592
|
+
"--model",
|
|
122593
|
+
modelPath,
|
|
122594
|
+
"--served-model-name",
|
|
122595
|
+
SERVED_MODEL_NAME,
|
|
122596
|
+
"--max-model-len",
|
|
122597
|
+
String(contextLength)
|
|
122598
|
+
];
|
|
122599
|
+
if (this.model.taskType === "embeddings") {
|
|
122600
|
+
args.push("--task", "embed");
|
|
122526
122601
|
}
|
|
122527
|
-
|
|
122528
|
-
|
|
122529
|
-
|
|
122602
|
+
args.push(...(await getChatTemplateEngineArgs({
|
|
122603
|
+
engine: this.engine,
|
|
122604
|
+
model: this.model,
|
|
122605
|
+
targetDirectory
|
|
122606
|
+
})));
|
|
122607
|
+
if (device) {
|
|
122608
|
+
args.push("--device", device);
|
|
122609
|
+
}
|
|
122610
|
+
if (dtype) {
|
|
122611
|
+
args.push("--dtype", dtype);
|
|
122612
|
+
}
|
|
122613
|
+
args.push(...parseExtraArgs(engineConfig?.extraArgs));
|
|
122614
|
+
if (this.model.multimodalEnabled) {
|
|
122615
|
+
args.push("--limit-mm-per-prompt", process.env.VLLM_MM_LIMIT ?? '{"image":5}');
|
|
122616
|
+
}
|
|
122617
|
+
if (process.env.VLLM_TRUST_REMOTE_CODE === "true") {
|
|
122618
|
+
args.push("--trust-remote-code");
|
|
122619
|
+
}
|
|
122620
|
+
return createEngineProcess({ args, bin: VLLM_EXECUTABLE, logger: this.logger });
|
|
122530
122621
|
}
|
|
122531
122622
|
|
|
122532
122623
|
const ModelDownloadProgressSchema = object$1({
|
|
@@ -123073,9 +123164,6 @@ const DEFAULT_EXLLAMAV3_CONTEXT_LENGTH = 4096;
|
|
|
123073
123164
|
async function startExllamav3({ enginePort, targetDirectory }) {
|
|
123074
123165
|
const contextLength = Math.max(1, this.contextLength ?? DEFAULT_EXLLAMAV3_CONTEXT_LENGTH);
|
|
123075
123166
|
const engineConfig = this.engineConfig;
|
|
123076
|
-
const cacheMode = typeof engineConfig?.cacheMode === "string" ? engineConfig.cacheMode : "q4";
|
|
123077
|
-
const gpuSplit = typeof engineConfig?.gpuSplit === "string" ? engineConfig.gpuSplit : null;
|
|
123078
|
-
const maxSeqLen = typeof engineConfig?.maxSeqLen === "number" ? engineConfig.maxSeqLen : contextLength;
|
|
123079
123167
|
const args = [
|
|
123080
123168
|
SERVER_SCRIPT,
|
|
123081
123169
|
"--model",
|
|
@@ -123084,20 +123172,15 @@ async function startExllamav3({ enginePort, targetDirectory }) {
|
|
|
123084
123172
|
"127.0.0.1",
|
|
123085
123173
|
"--port",
|
|
123086
123174
|
String(enginePort),
|
|
123087
|
-
"--cache-mode",
|
|
123088
|
-
cacheMode,
|
|
123089
123175
|
"--max-seq-len",
|
|
123090
|
-
String(
|
|
123176
|
+
String(contextLength)
|
|
123091
123177
|
];
|
|
123092
|
-
if (gpuSplit) {
|
|
123093
|
-
args.push("--gpu-split", gpuSplit);
|
|
123094
|
-
}
|
|
123095
123178
|
args.push(...parseExtraArgs(engineConfig?.extraArgs));
|
|
123096
123179
|
return createEngineProcess({ args, bin: EXLLAMAV3_EXECUTABLE, logger: this.logger });
|
|
123097
123180
|
}
|
|
123098
123181
|
|
|
123099
123182
|
const DEFAULT_LLAMACPP_GPU_LAYERS = 999;
|
|
123100
|
-
const LLAMACPP_START_ARGS = ["--host", "0.0.0.0", "--jinja"];
|
|
123183
|
+
const LLAMACPP_START_ARGS = ["--host", "0.0.0.0", "--jinja", "--flash-attn", "on"];
|
|
123101
123184
|
const LLAMACPP_EXECUTABLE = process.env.LLAMACPP_EXECUTABLE ?? "llama-server";
|
|
123102
123185
|
const DEFAULT_LLAMACPP_CONTEXT_LENGTH = 131072;
|
|
123103
123186
|
async function findMultimodalProjector({ path }) {
|
|
@@ -123119,7 +123202,6 @@ async function startLlamacpp({ enginePort, targetDirectory }) {
|
|
|
123119
123202
|
const target = await findQuantizedModelTarget({ model: this.model, path: targetDirectory });
|
|
123120
123203
|
const contextLength = Math.max(1, this.contextLength ?? DEFAULT_LLAMACPP_CONTEXT_LENGTH);
|
|
123121
123204
|
const engineConfig = this.engineConfig;
|
|
123122
|
-
const parallelism = typeof engineConfig?.parallelism === "number" ? engineConfig.parallelism : null;
|
|
123123
123205
|
const args = [
|
|
123124
123206
|
...LLAMACPP_START_ARGS,
|
|
123125
123207
|
"--port",
|
|
@@ -123129,46 +123211,18 @@ async function startLlamacpp({ enginePort, targetDirectory }) {
|
|
|
123129
123211
|
"--ctx-size",
|
|
123130
123212
|
String(contextLength)
|
|
123131
123213
|
];
|
|
123214
|
+
args.push(...(await getChatTemplateEngineArgs({
|
|
123215
|
+
engine: this.engine,
|
|
123216
|
+
model: this.model,
|
|
123217
|
+
targetDirectory
|
|
123218
|
+
})));
|
|
123132
123219
|
if (this.model.taskType === "embeddings") {
|
|
123133
123220
|
args.push("--embedding");
|
|
123134
123221
|
}
|
|
123135
|
-
const gpuLayers =
|
|
123136
|
-
? engineConfig.gpuLayers
|
|
123137
|
-
: Number.parseInt(process.env.LLAMACPP_GPU_LAYERS ?? String(DEFAULT_LLAMACPP_GPU_LAYERS), 10);
|
|
123222
|
+
const gpuLayers = Number.parseInt(process.env.LLAMACPP_GPU_LAYERS ?? String(DEFAULT_LLAMACPP_GPU_LAYERS), 10);
|
|
123138
123223
|
if (Number.isFinite(gpuLayers) && gpuLayers > 0) {
|
|
123139
123224
|
args.push("--n-gpu-layers", String(gpuLayers));
|
|
123140
123225
|
}
|
|
123141
|
-
if (typeof parallelism === "number") {
|
|
123142
|
-
args.push("--parallel", String(Math.max(1, parallelism)));
|
|
123143
|
-
}
|
|
123144
|
-
const flashAttn = engineConfig?.flashAttn;
|
|
123145
|
-
if (flashAttn === true || flashAttn === undefined) {
|
|
123146
|
-
args.push("--flash-attn", "on");
|
|
123147
|
-
}
|
|
123148
|
-
const cacheTypeK = typeof engineConfig?.cacheTypeK === "string" ? engineConfig.cacheTypeK : null;
|
|
123149
|
-
if (cacheTypeK) {
|
|
123150
|
-
args.push("--cache-type-k", cacheTypeK);
|
|
123151
|
-
}
|
|
123152
|
-
const cacheTypeV = typeof engineConfig?.cacheTypeV === "string" ? engineConfig.cacheTypeV : null;
|
|
123153
|
-
if (cacheTypeV) {
|
|
123154
|
-
args.push("--cache-type-v", cacheTypeV);
|
|
123155
|
-
}
|
|
123156
|
-
const batchSize = typeof engineConfig?.batchSize === "number" ? engineConfig.batchSize : null;
|
|
123157
|
-
if (batchSize !== null) {
|
|
123158
|
-
args.push("--batch-size", String(batchSize));
|
|
123159
|
-
}
|
|
123160
|
-
const ubatchSize = typeof engineConfig?.ubatchSize === "number" ? engineConfig.ubatchSize : null;
|
|
123161
|
-
if (ubatchSize !== null) {
|
|
123162
|
-
args.push("--ubatch-size", String(ubatchSize));
|
|
123163
|
-
}
|
|
123164
|
-
const tensorSplit = typeof engineConfig?.tensorSplit === "string" ? engineConfig.tensorSplit : null;
|
|
123165
|
-
if (tensorSplit) {
|
|
123166
|
-
args.push("--tensor-split", tensorSplit);
|
|
123167
|
-
}
|
|
123168
|
-
const mainGpu = typeof engineConfig?.mainGpu === "number" ? engineConfig.mainGpu : null;
|
|
123169
|
-
if (mainGpu !== null) {
|
|
123170
|
-
args.push("--main-gpu", String(mainGpu));
|
|
123171
|
-
}
|
|
123172
123226
|
args.push(...parseExtraArgs(engineConfig?.extraArgs));
|
|
123173
123227
|
if (this.model.multimodalEnabled) {
|
|
123174
123228
|
const projector = await findMultimodalProjector({ path: targetDirectory });
|
|
@@ -123207,12 +123261,7 @@ async function startMLXLM({ enginePort, targetDirectory }) {
|
|
|
123207
123261
|
"--context-length",
|
|
123208
123262
|
String(contextLength)
|
|
123209
123263
|
];
|
|
123210
|
-
|
|
123211
|
-
if (maxKvSize !== null) {
|
|
123212
|
-
args.push("--max-kv-size", String(maxKvSize));
|
|
123213
|
-
}
|
|
123214
|
-
const trustRemoteCode = engineConfig?.trustRemoteCode === true;
|
|
123215
|
-
if (trustRemoteCode || process.env.MLXLM_TRUST_REMOTE_CODE === "true") {
|
|
123264
|
+
if (process.env.MLXLM_TRUST_REMOTE_CODE === "true") {
|
|
123216
123265
|
args.push("--trust-remote-code");
|
|
123217
123266
|
}
|
|
123218
123267
|
args.push(...parseExtraArgs(engineConfig?.extraArgs));
|
|
@@ -123249,9 +123298,6 @@ const DEFAULT_SGLANG_CONTEXT_LENGTH = 2048;
|
|
|
123249
123298
|
async function startSGLang({ enginePort, targetDirectory }) {
|
|
123250
123299
|
const contextLength = Math.max(1, this.contextLength ?? DEFAULT_SGLANG_CONTEXT_LENGTH);
|
|
123251
123300
|
const engineConfig = this.engineConfig;
|
|
123252
|
-
const device = typeof engineConfig?.device === "string" ? engineConfig.device : undefined;
|
|
123253
|
-
const dtype = typeof engineConfig?.dtype === "string" ? engineConfig.dtype : undefined;
|
|
123254
|
-
const tensorParallelSize = typeof engineConfig?.tensorParallelSize === "number" ? engineConfig.tensorParallelSize : 1;
|
|
123255
123301
|
const args = [
|
|
123256
123302
|
...SGLANG_START_ARGS,
|
|
123257
123303
|
"--port",
|
|
@@ -123261,19 +123307,16 @@ async function startSGLang({ enginePort, targetDirectory }) {
|
|
|
123261
123307
|
"--served-model-name",
|
|
123262
123308
|
SERVED_MODEL_NAME,
|
|
123263
123309
|
"--context-length",
|
|
123264
|
-
String(contextLength)
|
|
123265
|
-
"--tp-size",
|
|
123266
|
-
String(tensorParallelSize)
|
|
123310
|
+
String(contextLength)
|
|
123267
123311
|
];
|
|
123268
123312
|
if (this.model.taskType === "embeddings") {
|
|
123269
123313
|
args.push("--task", "embed");
|
|
123270
123314
|
}
|
|
123271
|
-
|
|
123272
|
-
|
|
123273
|
-
|
|
123274
|
-
|
|
123275
|
-
|
|
123276
|
-
}
|
|
123315
|
+
args.push(...(await getChatTemplateEngineArgs({
|
|
123316
|
+
engine: this.engine,
|
|
123317
|
+
model: this.model,
|
|
123318
|
+
targetDirectory
|
|
123319
|
+
})));
|
|
123277
123320
|
args.push(...parseExtraArgs(engineConfig?.extraArgs));
|
|
123278
123321
|
if (this.model.multimodalEnabled) {
|
|
123279
123322
|
args.push("--limit-mm-per-prompt", process.env.SGLANG_MM_LIMIT ?? '{"image":5}');
|
|
@@ -123289,9 +123332,6 @@ const DEFAULT_TRTLLM_CONTEXT_LENGTH = 2048;
|
|
|
123289
123332
|
async function startTensorRTLLM({ enginePort, targetDirectory }) {
|
|
123290
123333
|
const contextLength = Math.max(1, this.contextLength ?? DEFAULT_TRTLLM_CONTEXT_LENGTH);
|
|
123291
123334
|
const engineConfig = this.engineConfig;
|
|
123292
|
-
const backend = typeof engineConfig?.backend === "string" ? engineConfig.backend : "pytorch";
|
|
123293
|
-
const dtype = typeof engineConfig?.dtype === "string" ? engineConfig.dtype : undefined;
|
|
123294
|
-
const tensorParallelSize = typeof engineConfig?.tensorParallelSize === "number" ? engineConfig.tensorParallelSize : 1;
|
|
123295
123335
|
const args = [
|
|
123296
123336
|
"serve",
|
|
123297
123337
|
targetDirectory,
|
|
@@ -123299,19 +123339,12 @@ async function startTensorRTLLM({ enginePort, targetDirectory }) {
|
|
|
123299
123339
|
"127.0.0.1",
|
|
123300
123340
|
"--port",
|
|
123301
123341
|
String(enginePort),
|
|
123302
|
-
"--backend",
|
|
123303
|
-
backend,
|
|
123304
123342
|
"--max-seq-len",
|
|
123305
|
-
String(contextLength)
|
|
123306
|
-
"--tp-size",
|
|
123307
|
-
String(tensorParallelSize)
|
|
123343
|
+
String(contextLength)
|
|
123308
123344
|
];
|
|
123309
123345
|
if (this.model.taskType === "embeddings") {
|
|
123310
123346
|
args.push("--task", "embed");
|
|
123311
123347
|
}
|
|
123312
|
-
if (dtype) {
|
|
123313
|
-
args.push("--dtype", dtype);
|
|
123314
|
-
}
|
|
123315
123348
|
args.push(...parseExtraArgs(engineConfig?.extraArgs));
|
|
123316
123349
|
return createEngineProcess({ args, bin: TRTLLM_EXECUTABLE, logger: this.logger });
|
|
123317
123350
|
}
|
|
@@ -123348,6 +123381,15 @@ class ModelManager extends EventEmitter {
|
|
|
123348
123381
|
this.uniqueName = createModelStorageKey(this.model);
|
|
123349
123382
|
this.modelsDirectory = path$1.join(root, "models");
|
|
123350
123383
|
}
|
|
123384
|
+
async verifyChatTemplate() {
|
|
123385
|
+
return verifyEngineChatTemplate({
|
|
123386
|
+
engine: this.engine,
|
|
123387
|
+
enginePort: this.enginePort,
|
|
123388
|
+
logger: this.logger,
|
|
123389
|
+
model: this.model,
|
|
123390
|
+
targetDirectory: path$1.join(this.modelsDirectory, this.uniqueName)
|
|
123391
|
+
});
|
|
123392
|
+
}
|
|
123351
123393
|
async fetchOpenAI(path, opts) {
|
|
123352
123394
|
switch (this.engine) {
|
|
123353
123395
|
case "exllamav3":
|
|
@@ -123425,6 +123467,12 @@ class ModelManager extends EventEmitter {
|
|
|
123425
123467
|
finally {
|
|
123426
123468
|
await this.releaseDownloadLock();
|
|
123427
123469
|
}
|
|
123470
|
+
await materializeChatTemplate({
|
|
123471
|
+
engine: this.engine,
|
|
123472
|
+
huggingFaceToken: this.model.source.modelSecret,
|
|
123473
|
+
model: this.model,
|
|
123474
|
+
targetDirectory: path$1.join(this.modelsDirectory, this.uniqueName)
|
|
123475
|
+
});
|
|
123428
123476
|
break;
|
|
123429
123477
|
default: {
|
|
123430
123478
|
const engineType = this.engine;
|
|
@@ -124408,7 +124456,50 @@ function stripImagesFromBody(body) {
|
|
|
124408
124456
|
function isPlainObject$3(value) {
|
|
124409
124457
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
124410
124458
|
}
|
|
124411
|
-
|
|
124459
|
+
/**
|
|
124460
|
+
* Builds `chat_template_kwargs` for engines that read template variables at
|
|
124461
|
+
* render time. Only active when the model carries a template override or
|
|
124462
|
+
* thinking config; otherwise the body forwards untouched (engines like vLLM
|
|
124463
|
+
* consume top-level `reasoning_effort` natively for supported models).
|
|
124464
|
+
*
|
|
124465
|
+
* Precedence (highest wins):
|
|
124466
|
+
* 1. Request `chat_template_kwargs` (per key)
|
|
124467
|
+
* 2. Request top-level `reasoning_effort`
|
|
124468
|
+
* 3. Model thinking config defaults
|
|
124469
|
+
*/
|
|
124470
|
+
function applyChatTemplateKwargs({ body, model }) {
|
|
124471
|
+
const hasTemplateOverride = Boolean(model.chatTemplate);
|
|
124472
|
+
const thinkingConfig = model.thinkingConfig ?? null;
|
|
124473
|
+
if (!hasTemplateOverride && !thinkingConfig)
|
|
124474
|
+
return body;
|
|
124475
|
+
const requestKwargs = isPlainObject$3(body.chat_template_kwargs)
|
|
124476
|
+
? body.chat_template_kwargs
|
|
124477
|
+
: null;
|
|
124478
|
+
const requestEffort = typeof body.reasoning_effort === "string" ? body.reasoning_effort : null;
|
|
124479
|
+
const mergedKwargs = {};
|
|
124480
|
+
if (thinkingConfig?.enabled === false) {
|
|
124481
|
+
mergedKwargs.enable_thinking = false;
|
|
124482
|
+
}
|
|
124483
|
+
if (thinkingConfig?.effort) {
|
|
124484
|
+
mergedKwargs.reasoning_effort = thinkingConfig.effort;
|
|
124485
|
+
}
|
|
124486
|
+
if (requestKwargs) {
|
|
124487
|
+
Object.assign(mergedKwargs, requestKwargs);
|
|
124488
|
+
}
|
|
124489
|
+
const hasRequestReasoningEffort = requestKwargs !== null && "reasoning_effort" in requestKwargs;
|
|
124490
|
+
if (requestEffort && !hasRequestReasoningEffort) {
|
|
124491
|
+
mergedKwargs.reasoning_effort = requestEffort;
|
|
124492
|
+
}
|
|
124493
|
+
const payload = { ...body };
|
|
124494
|
+
if (Object.keys(mergedKwargs).length > 0) {
|
|
124495
|
+
payload.chat_template_kwargs = mergedKwargs;
|
|
124496
|
+
}
|
|
124497
|
+
if (requestEffort !== null) {
|
|
124498
|
+
delete payload.reasoning_effort;
|
|
124499
|
+
}
|
|
124500
|
+
return payload;
|
|
124501
|
+
}
|
|
124502
|
+
function serializeRequestBody$1(body, { model, path } = {}) {
|
|
124412
124503
|
if (!isPlainObject$3(body)) {
|
|
124413
124504
|
const payload = typeof body === "string" ? body : JSON.stringify(body);
|
|
124414
124505
|
return {
|
|
@@ -124416,7 +124507,10 @@ function serializeRequestBody$1(body) {
|
|
|
124416
124507
|
payload
|
|
124417
124508
|
};
|
|
124418
124509
|
}
|
|
124419
|
-
|
|
124510
|
+
let requestPayload = { ...body };
|
|
124511
|
+
if (path === "/v1/chat/completions" && model) {
|
|
124512
|
+
requestPayload = applyChatTemplateKwargs({ body: requestPayload, model });
|
|
124513
|
+
}
|
|
124420
124514
|
if (requestPayload.stream === true) {
|
|
124421
124515
|
const streamOptions = requestPayload.stream_options;
|
|
124422
124516
|
const normalizedStreamOptions = isPlainObject$3(streamOptions)
|
|
@@ -124469,7 +124563,7 @@ async function proxyEmbeddingsRoute({ body, conduitConfiguration, endpointId, lo
|
|
|
124469
124563
|
});
|
|
124470
124564
|
}
|
|
124471
124565
|
const engineType = conduitConfiguration.engineConfig?.type ?? null;
|
|
124472
|
-
const engineConfig = conduitConfiguration.engineConfig
|
|
124566
|
+
const engineConfig = conduitConfiguration.engineConfig ?? null;
|
|
124473
124567
|
const serializedBody = isPlainObject$3(body)
|
|
124474
124568
|
? JSON.stringify(body)
|
|
124475
124569
|
: typeof body === "string"
|
|
@@ -124613,9 +124707,9 @@ async function proxyOpenAIStreamingRoute({ body, conduitConfiguration, endpointI
|
|
|
124613
124707
|
});
|
|
124614
124708
|
}
|
|
124615
124709
|
const engineType = conduitConfiguration.engineConfig?.type ?? null;
|
|
124616
|
-
const engineConfig = conduitConfiguration.engineConfig
|
|
124710
|
+
const engineConfig = conduitConfiguration.engineConfig ?? null;
|
|
124617
124711
|
const effectiveBody = modelManager.model.multimodalEnabled ? body : stripImagesFromBody(body);
|
|
124618
|
-
const { bytes: requestBodyBytes, payload: serializedBody } = serializeRequestBody$1(effectiveBody);
|
|
124712
|
+
const { bytes: requestBodyBytes, payload: serializedBody } = serializeRequestBody$1(effectiveBody, { model: modelManager.model, path });
|
|
124619
124713
|
const requestStartedAt = Date.now();
|
|
124620
124714
|
const requestBody = JSON.parse(serializedBody);
|
|
124621
124715
|
const streamRequested = requestBody.stream === true;
|
|
@@ -124862,7 +124956,7 @@ function createConduitOpenAIAPIReferenceHandlers({ apiClient, conduitConfigurati
|
|
|
124862
124956
|
const currentConfig = conduitConfiguration();
|
|
124863
124957
|
const effectiveContextLength = getEffectiveContextLength({
|
|
124864
124958
|
contextLength: modelManager.contextLength,
|
|
124865
|
-
engineConfig: currentConfig.engineConfig
|
|
124959
|
+
engineConfig: currentConfig.engineConfig ?? null,
|
|
124866
124960
|
engineType: currentConfig.engineConfig?.type ?? null
|
|
124867
124961
|
});
|
|
124868
124962
|
return {
|
|
@@ -125001,6 +125095,17 @@ function translateAnthropicRequestToOpenAI(body) {
|
|
|
125001
125095
|
result.top_p = parsed.top_p;
|
|
125002
125096
|
if (Array.isArray(parsed.stop_sequences))
|
|
125003
125097
|
result.stop = parsed.stop_sequences;
|
|
125098
|
+
if (parsed.thinking && typeof parsed.thinking === "object") {
|
|
125099
|
+
const thinking = parsed.thinking;
|
|
125100
|
+
if (thinking.type === "enabled") {
|
|
125101
|
+
const budgetTokens = typeof thinking.budget_tokens === "number" ? thinking.budget_tokens : null;
|
|
125102
|
+
result.chat_template_kwargs = {
|
|
125103
|
+
reasoning_effort: budgetTokens
|
|
125104
|
+
? reasoningEffortForAnthropicBudget(budgetTokens)
|
|
125105
|
+
: "high"
|
|
125106
|
+
};
|
|
125107
|
+
}
|
|
125108
|
+
}
|
|
125004
125109
|
if (Array.isArray(parsed.tools)) {
|
|
125005
125110
|
result.tools = parsed.tools.map((tool) => {
|
|
125006
125111
|
const t = tool;
|
|
@@ -125272,11 +125377,13 @@ async function proxyAnthropicStreamingRoute({ body, conduitConfiguration, endpoi
|
|
|
125272
125377
|
const requestStartedAt = Date.now();
|
|
125273
125378
|
const requestBody = JSON.parse(serializedBody);
|
|
125274
125379
|
const streamRequested = requestBody.stream === true;
|
|
125275
|
-
const
|
|
125276
|
-
|
|
125277
|
-
|
|
125278
|
-
|
|
125279
|
-
|
|
125380
|
+
const translated = needsTranslation ? translateAnthropicRequestToOpenAI(serializedBody) : null;
|
|
125381
|
+
const targetPath = translated?.path ?? "/v1/messages";
|
|
125382
|
+
const targetBody = translated
|
|
125383
|
+
? JSON.stringify(applyChatTemplateKwargs({
|
|
125384
|
+
body: JSON.parse(translated.body),
|
|
125385
|
+
model: modelManager.model
|
|
125386
|
+
}))
|
|
125280
125387
|
: serializedBody;
|
|
125281
125388
|
const onMonitoringComplete = ({ durationMs, error, responseBytes, timeToFirstTokenMs, usage }) => {
|
|
125282
125389
|
const promptTokens = normalizeTokenCount(usage?.inputTokens);
|
|
@@ -156174,13 +156281,14 @@ async function createApplication({ abortController, apiClient, configuration, lo
|
|
|
156174
156281
|
});
|
|
156175
156282
|
conduitStateReportManager.reportStateChange();
|
|
156176
156283
|
};
|
|
156177
|
-
const setOnlineState = () => {
|
|
156178
|
-
if (conduitStateManager.getState().state === "online") {
|
|
156284
|
+
const setOnlineState = ({ warnings } = {}) => {
|
|
156285
|
+
if (conduitStateManager.getState().state === "online" && warnings === undefined) {
|
|
156179
156286
|
return;
|
|
156180
156287
|
}
|
|
156181
156288
|
conduitStateManager.setState({
|
|
156182
156289
|
modelName,
|
|
156183
|
-
state: "online"
|
|
156290
|
+
state: "online",
|
|
156291
|
+
...(warnings !== undefined ? { warnings } : {})
|
|
156184
156292
|
});
|
|
156185
156293
|
conduitStateReportManager.reportStateChange();
|
|
156186
156294
|
};
|
|
@@ -156202,6 +156310,23 @@ async function createApplication({ abortController, apiClient, configuration, lo
|
|
|
156202
156310
|
});
|
|
156203
156311
|
modelManager.on("engineReady", () => {
|
|
156204
156312
|
setOnlineState();
|
|
156313
|
+
const readyModelManager = modelManager;
|
|
156314
|
+
readyModelManager
|
|
156315
|
+
.verifyChatTemplate()
|
|
156316
|
+
.then(warning => {
|
|
156317
|
+
if (modelManager !== readyModelManager) {
|
|
156318
|
+
return;
|
|
156319
|
+
}
|
|
156320
|
+
if (warning) {
|
|
156321
|
+
logger.warn("Chat template verification", { warning });
|
|
156322
|
+
setOnlineState({ warnings: [warning] });
|
|
156323
|
+
}
|
|
156324
|
+
})
|
|
156325
|
+
.catch(error => {
|
|
156326
|
+
logger.warn("Chat template verification failed", {
|
|
156327
|
+
error: asError(error)
|
|
156328
|
+
});
|
|
156329
|
+
});
|
|
156205
156330
|
});
|
|
156206
156331
|
modelManager.on("engineTerminated", () => {
|
|
156207
156332
|
if (stopRequestedByControl) {
|
|
@@ -156513,7 +156638,9 @@ function createModelManagerFromConfig(conduitConfiguration, configuration, logge
|
|
|
156513
156638
|
const engineConfig = conduitConfiguration.engineConfig;
|
|
156514
156639
|
return new ModelManager({
|
|
156515
156640
|
contextLength: conduitConfiguration.contextLength ?? null,
|
|
156516
|
-
engineConfig: engineConfig
|
|
156641
|
+
engineConfig: engineConfig
|
|
156642
|
+
? { extraArgs: engineConfig.extraArgs, type: engineConfig.type }
|
|
156643
|
+
: null,
|
|
156517
156644
|
enginePort: configuration.enginePort,
|
|
156518
156645
|
engineType: engineConfig?.type ?? "llama.cpp",
|
|
156519
156646
|
logger,
|