(text: string)
| 654 | } |
| 655 | |
| 656 | export async function getEmbedding(text: string) { |
| 657 | const targetDim = await getEmbeddingDimensions(); |
| 658 | const embeddingInfo = await getDefaultEmbeddingInfo(); |
| 659 | const embeddingProviderType = embeddingInfo?.providerType ?? "openai"; |
| 660 | const embeddingModelId = embeddingInfo?.modelId ?? "text-embedding-3-small"; |
| 661 | |
| 662 | const maxRetries = 3; |
| 663 | let lastEmbedding: number[] = []; |
| 664 | let textForEmbedding = (text ?? "").toString(); |
| 665 | |
| 666 | const embeddingModel = await getEmbeddingModel(); |
| 667 | |
| 668 | for (let attempt = 1; attempt <= maxRetries; attempt++) { |
| 669 | try { |
| 670 | const { embedding } = await embed({ |
| 671 | model: embeddingModel, |
| 672 | value: textForEmbedding, |
| 673 | ...(targetDim && embeddingProviderType === "google" && { |
| 674 | providerOptions: { |
| 675 | google: { outputDimensionality: targetDim }, |
| 676 | }, |
| 677 | }), |
| 678 | }); |
| 679 | lastEmbedding = embedding; |
| 680 | |
| 681 | if (lastEmbedding.length > 0) { |
| 682 | if (targetDim && targetDim > 0) { |
| 683 | if (lastEmbedding.length < targetDim) { |
| 684 | logger.warn( |
| 685 | `Embedding dimension mismatch: got ${lastEmbedding.length}, expected ${targetDim}. Padding with zeros; update embedding model dimensions to fix permanently.`, |
| 686 | ); |
| 687 | lastEmbedding = lastEmbedding.concat( |
| 688 | new Array(targetDim - lastEmbedding.length).fill(0), |
| 689 | ); |
| 690 | } else if (lastEmbedding.length > targetDim) { |
| 691 | throw new Error( |
| 692 | `Embedding dimension mismatch: got ${lastEmbedding.length}, expected ${targetDim}. Update embedding model dimensions and re-embed/migrate vectors.`, |
| 693 | ); |
| 694 | } |
| 695 | } |
| 696 | return lastEmbedding; |
| 697 | } |
| 698 | |
| 699 | if (attempt < maxRetries) { |
| 700 | logger.warn( |
| 701 | `Attempt ${attempt}/${maxRetries}: Got empty embedding, retrying...`, |
| 702 | ); |
| 703 | } |
| 704 | } catch (error) { |
| 705 | const errorString = |
| 706 | error instanceof Error ? error.message : String(error); |
| 707 | const isContextLengthError = |
| 708 | /context length/i.test(errorString) || |
| 709 | /exceeds the context length/i.test(errorString); |
| 710 | |
| 711 | if ( |
| 712 | isContextLengthError && |
| 713 | attempt < maxRetries && |
no test coverage detected