Repository: ollama/ollama
File: server/routes.go (Go)

Code before:
		}

		var serr api.StatusError
		if !errors.As(err, &serr) || serr.StatusCode != http.StatusBadRequest {
			return nil, 0, err
		}
		if req.Truncate != nil && !*req.Truncate {
			return nil, 0, err
		}

		tokens, err := r.Tokenize(ctx, text)
		if err != nil {
			return nil, 0, err
		}

		// TODO: avoid reaching into kvData here; pass required tokenizer metadata via model/options instead
		ctxLen := min(opts.NumCtx, int(kvData.ContextLength()))
		if bos := kvData.Uint("tokenizer.ggml.bos_token_id"); len(tokens) > 0 && tokens[0] != int(bos) && kvData.Bool("add_bos_token", true) {
			ctxLen--
		}
		if eos := kvData.Uint("tokenizer.ggml.eos_token_id"); len(tokens) > 0 && tokens[len(tokens)-1] != int(eos) && kvData.Bool("add_eos_token", true) {
			ctxLen--
		}

		if len(tokens) <= ctxLen {
			return nil, 0, err
		}
		if ctxLen <= 0 {
			return nil, 0, fmt.Errorf("input after truncation exceeds maximum context length")
		}

		truncatedTokens := tokens[:ctxLen]
		truncated, err := r.Detokenize(ctx, truncatedTokens)
		if err != nil {
			return nil, 0, err
		}
		return r.Embedding(ctx, truncated)
	}

	var g errgroup.Group
	embeddings := make([][]float32, len(input))
	var totalTokens uint64
	for i, text := range input {
		g.Go(func() error {
			embedding, tokenCount, err := embedWithRetry(text)
			if err != nil {
				return err
			}
			// TODO: this first normalization should be done by the model
			embedding = normalize(embedding)
			if req.Dimensions > 0 && req.Dimensions < len(embedding) {

Review comment (suggestion):
I think `err` will be nil here since we checked it previously. I believe that you want to return a real error since we aren't able to either get embeddings or truncate.

Code after:
		}

		var serr api.StatusError
		if !errors.As(err, &serr) || serr.StatusCode != http.StatusBadRequest {
			return nil, 0, err
		}
		if req.Truncate != nil && !*req.Truncate {
			return nil, 0, err
		}

		tokens, err := r.Tokenize(ctx, text)
		if err != nil {
			return nil, 0, err
		}

		// TODO @nicolepardal: avoid reaching into kvData here; pass required tokenizer metadata via model/options instead
		ctxLen := min(opts.NumCtx, int(kvData.ContextLength()))
		if bos := kvData.Uint("tokenizer.ggml.bos_token_id"); len(tokens) > 0 && tokens[0] != int(bos) && kvData.Bool("add_bos_token", true) {
			ctxLen--
		}
		if eos := kvData.Uint("tokenizer.ggml.eos_token_id"); len(tokens) > 0 && tokens[len(tokens)-1] != int(eos) && kvData.Bool("add_eos_token", true) {
			ctxLen--
		}

		if len(tokens) <= ctxLen {
			return nil, 0, fmt.Errorf("input exceeds maximum context length and cannot be truncated further")
		}
		if ctxLen <= 0 {
			return nil, 0, fmt.Errorf("input after truncation exceeds maximum context length")
		}

		truncatedTokens := tokens[:ctxLen]
		truncated, err := r.Detokenize(ctx, truncatedTokens)
		if err != nil {
			return nil, 0, err
		}
		return r.Embedding(ctx, truncated)
	}

	var g errgroup.Group
	embeddings := make([][]float32, len(input))
	var totalTokens uint64
	for i, text := range input {
		g.Go(func() error {
			embedding, tokenCount, err := embedWithRetry(text)
			if err != nil {
				return err
			}
			// TODO: this first normalization should be done by the model
			embedding = normalize(embedding)
			if req.Dimensions > 0 && req.Dimensions < len(embedding) {