Repository: xenova/transformers.js
File: src/pipelines.js (JavaScript)

Code before:
 * **Example:** Calculating binary embeddings with `sentence-transformers` models.
 * ```javascript
 * const extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
 * const output = await extractor('This is a simple test.', { pooling: 'mean', quantize: true, precision: 'binary' });
 * // Tensor {
 * //   type: 'int8',
 * //   data: Int8Array [49, 108, 24, ...],
 * //   dims: [1, 48]
 * // }
 * ```
 */
export class FeatureExtractionPipeline extends (/** @type {new (options: TextPipelineConstructorArgs) => FeatureExtractionPipelineType} */ (Pipeline)) {
    /**
     * Create a new FeatureExtractionPipeline.
     * @param {TextPipelineConstructorArgs} options An object used to instantiate the pipeline.
     */
    constructor(options) {
        super(options);
    }

    /** @type {FeatureExtractionPipelineCallback} */
    async _call(texts, {
        pooling = /** @type {'none'} */('none'),
        normalize = false,
        quantize = false,
        precision = /** @type {'binary'|'ubinary'} */('binary'),
    } = {}) {

        // Run tokenization
        const model_inputs = this.tokenizer(texts, {
            padding: true,
            truncation: true,
        });

        // Run model
        const outputs = await this.model(model_inputs)

        // TODO: Provide warning to the user that they might be using model which was not exported
        // specifically for feature extraction
        // console.log(this.model.config)
        // console.log(outputs)

        /** @type {Tensor} */
        let result = outputs.last_hidden_state ?? outputs.logits;
        if (pooling === 'none') {
            // Skip pooling
        } else if (pooling === 'mean') {
            result = mean_pooling(result, model_inputs.attention_mask);
        } else if (pooling === 'cls') {
            result = result.slice(null, 0);
        } else {

Review comment (suggestion):
```suggestion
        precision = /** @type {'binary'} */('binary'),
```

This is just to make the type-checker happy, and says the default value is of type `'binary'` and not `string`. Even without `'ubinary'` set here, the type is correct.
![image](https://github.com/xenova/transformers.js/assets/26504141/252e2676-0b1c-4bb5-8fbb-ce1041565e7f)


Code after:
 * **Example:** Calculating binary embeddings with `sentence-transformers` models.
 * ```javascript
 * const extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
 * const output = await extractor('This is a simple test.', { pooling: 'mean', quantize: true, precision: 'binary' });
 * // Tensor {
 * //   type: 'int8',
 * //   data: Int8Array [49, 108, 24, ...],
 * //   dims: [1, 48]
 * // }
 * ```
 */
export class FeatureExtractionPipeline extends (/** @type {new (options: TextPipelineConstructorArgs) => FeatureExtractionPipelineType} */ (Pipeline)) {
    /**
     * Create a new FeatureExtractionPipeline.
     * @param {TextPipelineConstructorArgs} options An object used to instantiate the pipeline.
     */
    constructor(options) {
        super(options);
    }

    /** @type {FeatureExtractionPipelineCallback} */
    async _call(texts, {
        pooling = /** @type {'none'} */('none'),
        normalize = false,
        quantize = false,
        precision = /** @type {'binary'} */('binary'),
    } = {}) {

        // Run tokenization
        const model_inputs = this.tokenizer(texts, {
            padding: true,
            truncation: true,
        });

        // Run model
        const outputs = await this.model(model_inputs)

        // TODO: Provide warning to the user that they might be using model which was not exported
        // specifically for feature extraction
        // console.log(this.model.config)
        // console.log(outputs)

        /** @type {Tensor} */
        let result = outputs.last_hidden_state ?? outputs.logits;
        if (pooling === 'none') {
            // Skip pooling
        } else if (pooling === 'mean') {
            result = mean_pooling(result, model_inputs.attention_mask);
        } else if (pooling === 'cls') {
            result = result.slice(null, 0);
        } else {