@superlinked/sie-llamaindex 0.8.3 → 0.9.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/index.cjs CHANGED
@@ -91,12 +91,17 @@ var SIENodePostprocessor = class {
91
91
  return nodes;
92
92
  }
93
93
  const queryItem = { text: queryText };
94
- const docItems = nodes.map((n) => ({ text: n.node.getContent(import_llamaindex.MetadataMode.NONE) }));
94
+ const docItems = nodes.map((n, idx) => ({
95
+ id: String(idx),
96
+ text: n.node.getContent(import_llamaindex.MetadataMode.NONE)
97
+ }));
95
98
  const result = await this.client.score(this.modelName, queryItem, docItems);
99
+ const positions = new Map(docItems.map((item, idx) => [item.id, idx]));
96
100
  const reranked = [];
97
101
  for (const entry of result.scores) {
98
- const idx = Number.parseInt(entry.itemId, 10);
99
- const original = nodes[idx];
102
+ const idx = positions.get(entry.itemId);
103
+ positions.delete(entry.itemId);
104
+ const original = idx === void 0 ? void 0 : nodes[idx];
100
105
  if (original) {
101
106
  reranked.push({
102
107
  node: original.node,
@@ -157,6 +162,14 @@ var _SIEExtractor = class {
157
162
  { text },
158
163
  extractOptions
159
164
  );
165
+ if (result.error) {
166
+ throw new import_sie_sdk2.RequestError(
167
+ `Extraction failed: ${result.error.message}`,
168
+ result.error.code,
169
+ void 0,
170
+ result.request?.id
171
+ );
172
+ }
160
173
  return JSON.stringify({
161
174
  entities: result.entities.map((e) => ({
162
175
  text: e.text,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/rerankers.ts","../src/extractors.ts"],"sourcesContent":["/**\n * SIE embeddings integration for LlamaIndex.TS\n *\n * Provides embedding generation using SIE's encode endpoint:\n * - SIEEmbedding: Dense embeddings implementing BaseEmbedding\n * - SIESparseEmbeddingFunction: Sparse embeddings for hybrid search\n * - SIENodePostprocessor: Cross-encoder reranking for query pipelines\n * - createSIEExtractorTool: Entity extraction tool for agents\n *\n * @example\n * ```typescript\n * import { Settings } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n * ```\n */\n\nimport {\n type DType,\n type EncodeOptions,\n type EncodeResult,\n SIEClient,\n type SIEClientOptions,\n denseEmbedding,\n sparseEmbedding,\n} from \"@superlinked/sie-sdk\";\nimport { BaseEmbedding } from \"llamaindex\";\n\n/**\n * Configuration options for SIEEmbedding.\n */\nexport interface SIEEmbeddingOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n */\n client?: SIEClient;\n\n /**\n * Optional instruction prefix for embedding (model-dependent).\n */\n instruction?: string;\n\n /**\n * Output dtype: \"float32\" (default), \"float16\", \"int8\", \"binary\".\n */\n outputDtype?: DType;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Batch size for embedding multiple texts.\n * @default 10\n */\n embedBatchSize?: number;\n}\n\n/**\n * LlamaIndex BaseEmbedding implementation using SIE.\n *\n * Wraps SIEClient.encode() to implement the LlamaIndex BaseEmbedding interface.\n *\n * @example\n * ```typescript\n * import { Settings, VectorStoreIndex, Document } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * // Create index with documents\n * const index = await VectorStoreIndex.fromDocuments([\n * new Document({ text: \"Hello world\" }),\n * ]);\n *\n * // With GPU routing for multi-GPU clusters\n * const embedModel = new SIEEmbedding({\n * baseUrl: \"https://cluster.example.com\",\n * modelName: \"BAAI/bge-m3\",\n * gpu: \"a100-80gb\",\n * });\n * ```\n */\nexport class SIEEmbedding extends BaseEmbedding {\n readonly modelName: string;\n private readonly instruction?: string;\n private readonly outputDtype?: DType;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n /**\n * Get embeddings for multiple text strings (documents).\n * This is a property (arrow function) to match BaseEmbedding interface.\n */\n override getTextEmbeddings = async (texts: string[]): Promise<number[][]> => {\n if (texts.length === 0) {\n return [];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n return (results as EncodeResult[]).map((result) => denseEmbedding(result));\n };\n\n constructor(options: SIEEmbeddingOptions = {}) {\n super();\n\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n client,\n instruction,\n outputDtype,\n gpu,\n timeout = 180_000,\n embedBatchSize = 10,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.instruction = instruction;\n this.outputDtype = outputDtype;\n this._client = client;\n this.embedBatchSize = embedBatchSize;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Get embedding for a single text string (document).\n *\n * @param text - Text to embed.\n * @returns Embedding vector as array of numbers.\n */\n async getTextEmbedding(text: string): Promise<number[]> {\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const result = await this.client.encode(this.modelName, { text }, options);\n return denseEmbedding(result as EncodeResult);\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\n/**\n * Configuration options for SIESparseEmbeddingFunction.\n */\nexport interface SIESparseEmbeddingFunctionOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding. Must support sparse output.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Sparse embedding function for LlamaIndex hybrid search.\n *\n * Compatible with LlamaIndex vector stores that support hybrid search,\n * such as QdrantVectorStore with enableHybrid: true.\n *\n * @example\n * ```typescript\n * import { QdrantVectorStore } from \"llamaindex\";\n * import { SIESparseEmbeddingFunction } from \"@superlinked/sie-llamaindex\";\n *\n * const sparseEmbedFn = new SIESparseEmbeddingFunction({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * const vectorStore = new QdrantVectorStore({\n * client: qdrantClient,\n * collectionName: \"hybrid_docs\",\n * enableHybrid: true,\n * sparseEmbeddingFunction: sparseEmbedFn,\n * });\n * ```\n */\nexport class SIESparseEmbeddingFunction {\n private readonly modelName: string;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIESparseEmbeddingFunctionOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Encode query texts to sparse vectors.\n *\n * @param texts - List of query texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeQueries(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: true,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Encode document texts to sparse vectors.\n *\n * @param texts - List of document texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeDocuments(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\nexport { SIENodePostprocessor, type SIENodePostprocessorOptions } from \"./rerankers.js\";\nexport { createSIEExtractorTool, type SIEExtractorToolOptions } from \"./extractors.js\";\n","/**\n * SIE reranker integration for LlamaIndex.TS\n *\n * Provides node reranking using SIE's score endpoint:\n * - SIENodePostprocessor: Cross-encoder reranking implementing BaseNodePostprocessor\n *\n * @example\n * ```typescript\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const reranked = await reranker.postprocessNodes(nodes, \"search query\");\n * ```\n */\n\nimport { SIEClient, type SIEClientOptions } from \"@superlinked/sie-sdk\";\nimport { MetadataMode } from \"llamaindex\";\nimport type { BaseNodePostprocessor, MessageContent, NodeWithScore } from \"llamaindex\";\n\n/**\n * Configuration options for SIENodePostprocessor.\n */\nexport interface SIENodePostprocessorOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Reranker model name/ID.\n * @default \"jinaai/jina-reranker-v2-base-multilingual\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n * If provided, baseUrl and other connection options are ignored.\n */\n client?: SIEClient;\n\n /**\n * Number of top nodes to return. If undefined, returns all nodes.\n */\n topN?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Extract a plain query string from LlamaIndex's MessageContent type.\n *\n * MessageContent is `string | MessageContentDetail[]`. For reranking\n * we need a plain string.\n */\nfunction extractQueryString(query: MessageContent): string {\n if (typeof query === \"string\") {\n return query;\n }\n // MessageContentDetail[] — concatenate text parts\n return query\n .filter(\n (part): part is { type: \"text\"; text: string } => \"type\" in part && part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\" \");\n}\n\n/**\n * LlamaIndex node postprocessor using SIE's reranking.\n *\n * Wraps SIEClient.score() to implement the BaseNodePostprocessor interface.\n *\n * @example\n * ```typescript\n * import { VectorStoreIndex } from \"llamaindex\";\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const queryEngine = index.asQueryEngine({\n * nodePostprocessors: [reranker],\n * });\n *\n * const response = await queryEngine.query({ query: \"What is the topic?\" });\n * ```\n */\nexport class SIENodePostprocessor implements BaseNodePostprocessor {\n readonly modelName: string;\n private readonly topN?: number;\n private _client: SIEClient | undefined;\n private readonly _ownsClient: boolean;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIENodePostprocessorOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"jinaai/jina-reranker-v2-base-multilingual\",\n client,\n topN,\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.topN = topN;\n this._client = client;\n this._ownsClient = !client;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Rerank nodes by relevance to query.\n *\n * @param nodes - Nodes with scores to rerank.\n * @param query - Optional query string or MessageContent.\n * @returns Reranked nodes with updated scores, sorted by relevance descending.\n */\n async postprocessNodes(nodes: NodeWithScore[], query?: MessageContent): Promise<NodeWithScore[]> {\n if (nodes.length === 0 || query === undefined) {\n return nodes;\n }\n\n const queryText = extractQueryString(query);\n if (!queryText) {\n return nodes;\n }\n\n const queryItem = { text: queryText };\n const docItems = nodes.map((n) => ({ text: n.node.getContent(MetadataMode.NONE) }));\n\n const result = await this.client.score(this.modelName, queryItem, docItems);\n\n // Map score entries back to NodeWithScore with updated scores.\n // ScoreResult.scores are already sorted by score descending.\n const reranked: NodeWithScore[] = [];\n for (const entry of result.scores) {\n const idx = Number.parseInt(entry.itemId, 10);\n const original = nodes[idx];\n if (original) {\n reranked.push({\n node: original.node,\n score: entry.score,\n });\n }\n }\n\n if (this.topN !== undefined) {\n return reranked.slice(0, this.topN);\n }\n return reranked;\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client && this._ownsClient) {\n await this._client.close();\n }\n }\n}\n","/**\n * SIE extraction tool for LlamaIndex.TS\n *\n * Provides extraction using SIE's extract endpoint:\n * - createSIEExtractorTool: Factory that creates a FunctionTool for extraction\n *\n * Returns entities, relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const result = await extractor.call({ text: \"John Smith works at Acme Corp\" });\n * const parsed = JSON.parse(result);\n * console.log(parsed.entities);\n * ```\n */\n\nimport {\n type ExtractOptions,\n type ExtractResult,\n SIEClient,\n type SIEClientOptions,\n} from \"@superlinked/sie-sdk\";\nimport { FunctionTool } from \"llamaindex\";\n\n/**\n * Configuration options for createSIEExtractorTool.\n */\nexport interface SIEExtractorToolOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Extraction model name/ID.\n * @default \"urchade/gliner_multi-v2.1\"\n */\n modelName?: string;\n\n /**\n * Labels to extract.\n * @default [\"person\", \"organization\", \"location\"]\n */\n labels?: string[];\n\n /**\n * Minimum confidence threshold (0-1).\n */\n threshold?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Tool name for the agent.\n * @default \"sie_extract\"\n */\n name?: string;\n\n /**\n * Tool description for the agent.\n */\n description?: string;\n}\n\n/**\n * Internal class to hold SIE extractor state.\n */\nclass _SIEExtractor {\n private readonly baseUrl: string;\n private readonly modelName: string;\n private readonly labels: string[];\n private readonly threshold?: number;\n private readonly clientOptions: SIEClientOptions;\n private _client: SIEClient | undefined;\n\n constructor(options: SIEExtractorToolOptions) {\n this.baseUrl = options.baseUrl ?? \"http://localhost:8080\";\n this.modelName = options.modelName ?? \"urchade/gliner_multi-v2.1\";\n this.labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n this.threshold = options.threshold;\n this.clientOptions = {\n timeout: options.timeout ?? 180_000,\n gpu: options.gpu,\n };\n }\n\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n async extract(text: string): Promise<string> {\n const extractOptions: ExtractOptions = {\n labels: this.labels,\n };\n if (this.threshold !== undefined) {\n extractOptions.threshold = this.threshold;\n }\n\n const result: ExtractResult = await this.client.extract(\n this.modelName,\n { text },\n extractOptions,\n );\n\n return JSON.stringify({\n entities: result.entities.map((e) => ({\n text: e.text,\n label: e.label,\n score: e.score,\n ...(e.start !== undefined && { start: e.start }),\n ...(e.end !== undefined && { end: e.end }),\n })),\n relations: result.relations.map((r) => ({\n head: r.head,\n tail: r.tail,\n relation: r.relation,\n score: r.score,\n })),\n classifications: result.classifications.map((c) => ({\n label: c.label,\n score: c.score,\n })),\n objects: result.objects.map((o) => ({\n label: o.label,\n score: o.score,\n bbox: o.bbox,\n })),\n });\n }\n}\n\n/**\n * Create a LlamaIndex FunctionTool for extraction.\n *\n * Creates a tool that wraps SIE's extract endpoint for use with\n * LlamaIndex agents and workflows. Returns JSON with entities,\n * relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { OpenAI, ReActAgent } from \"llamaindex\";\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const agent = new ReActAgent({\n * tools: [extractor],\n * llm: new OpenAI(),\n * });\n *\n * const response = await agent.chat({\n * message: \"Extract entities from: John works at Google in NYC\",\n * });\n * ```\n *\n * @param options - Configuration for the extractor tool.\n * @returns FunctionTool wrapping SIE extraction.\n */\nexport function createSIEExtractorTool(options: SIEExtractorToolOptions = {}) {\n const labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n const name = options.name ?? \"sie_extract\";\n const description =\n options.description ??\n `Extract structured information from text. Finds entities of types: ${labels.join(\", \")}. Returns entities, relations, classifications, and detected objects.`;\n\n const extractor = new _SIEExtractor(options);\n\n async function extract(input: { text: string }): Promise<string> {\n return extractor.extract(input.text);\n }\n\n return FunctionTool.from(extract, {\n name,\n description,\n });\n}\n"],"mappings":"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","names":["import_sie_sdk","import_llamaindex","import_sie_sdk","import_llamaindex"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/rerankers.ts","../src/extractors.ts"],"sourcesContent":["/**\n * SIE embeddings integration for LlamaIndex.TS\n *\n * Provides embedding generation using SIE's encode endpoint:\n * - SIEEmbedding: Dense embeddings implementing BaseEmbedding\n * - SIESparseEmbeddingFunction: Sparse embeddings for hybrid search\n * - SIENodePostprocessor: Cross-encoder reranking for query pipelines\n * - createSIEExtractorTool: Entity extraction tool for agents\n *\n * @example\n * ```typescript\n * import { Settings } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n * ```\n */\n\nimport {\n type DType,\n type EncodeOptions,\n type EncodeResult,\n SIEClient,\n type SIEClientOptions,\n denseEmbedding,\n sparseEmbedding,\n} from \"@superlinked/sie-sdk\";\nimport { BaseEmbedding } from \"llamaindex\";\n\n/**\n * Configuration options for SIEEmbedding.\n */\nexport interface SIEEmbeddingOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n */\n client?: SIEClient;\n\n /**\n * Optional instruction prefix for embedding (model-dependent).\n */\n instruction?: string;\n\n /**\n * Output dtype: \"float32\" (default), \"float16\", \"int8\", \"binary\".\n */\n outputDtype?: DType;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Batch size for embedding multiple texts.\n * @default 10\n */\n embedBatchSize?: number;\n}\n\n/**\n * LlamaIndex BaseEmbedding implementation using SIE.\n *\n * Wraps SIEClient.encode() to implement the LlamaIndex BaseEmbedding interface.\n *\n * @example\n * ```typescript\n * import { Settings, VectorStoreIndex, Document } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * // Create index with documents\n * const index = await VectorStoreIndex.fromDocuments([\n * new Document({ text: \"Hello world\" }),\n * ]);\n *\n * // With GPU routing for multi-GPU clusters\n * const embedModel = new SIEEmbedding({\n * baseUrl: \"https://cluster.example.com\",\n * modelName: \"BAAI/bge-m3\",\n * gpu: \"a100-80gb\",\n * });\n * ```\n */\nexport class SIEEmbedding extends BaseEmbedding {\n readonly modelName: string;\n private readonly instruction?: string;\n private readonly outputDtype?: DType;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n /**\n * Get embeddings for multiple text strings (documents).\n * This is a property (arrow function) to match BaseEmbedding interface.\n */\n override getTextEmbeddings = async (texts: string[]): Promise<number[][]> => {\n if (texts.length === 0) {\n return [];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n return (results as EncodeResult[]).map((result) => denseEmbedding(result));\n };\n\n constructor(options: SIEEmbeddingOptions = {}) {\n super();\n\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n client,\n instruction,\n outputDtype,\n gpu,\n timeout = 180_000,\n embedBatchSize = 10,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.instruction = instruction;\n this.outputDtype = outputDtype;\n this._client = client;\n this.embedBatchSize = embedBatchSize;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Get embedding for a single text string (document).\n *\n * @param text - Text to embed.\n * @returns Embedding vector as array of numbers.\n */\n async getTextEmbedding(text: string): Promise<number[]> {\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const result = await this.client.encode(this.modelName, { text }, options);\n return denseEmbedding(result as EncodeResult);\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\n/**\n * Configuration options for SIESparseEmbeddingFunction.\n */\nexport interface SIESparseEmbeddingFunctionOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding. Must support sparse output.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Sparse embedding function for LlamaIndex hybrid search.\n *\n * Compatible with LlamaIndex vector stores that support hybrid search,\n * such as QdrantVectorStore with enableHybrid: true.\n *\n * @example\n * ```typescript\n * import { QdrantVectorStore } from \"llamaindex\";\n * import { SIESparseEmbeddingFunction } from \"@superlinked/sie-llamaindex\";\n *\n * const sparseEmbedFn = new SIESparseEmbeddingFunction({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * const vectorStore = new QdrantVectorStore({\n * client: qdrantClient,\n * collectionName: \"hybrid_docs\",\n * enableHybrid: true,\n * sparseEmbeddingFunction: sparseEmbedFn,\n * });\n * ```\n */\nexport class SIESparseEmbeddingFunction {\n private readonly modelName: string;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIESparseEmbeddingFunctionOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Encode query texts to sparse vectors.\n *\n * @param texts - List of query texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeQueries(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: true,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Encode document texts to sparse vectors.\n *\n * @param texts - List of document texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeDocuments(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\nexport { SIENodePostprocessor, type SIENodePostprocessorOptions } from \"./rerankers.js\";\nexport { createSIEExtractorTool, type SIEExtractorToolOptions } from \"./extractors.js\";\n","/**\n * SIE reranker integration for LlamaIndex.TS\n *\n * Provides node reranking using SIE's score endpoint:\n * - SIENodePostprocessor: Cross-encoder reranking implementing BaseNodePostprocessor\n *\n * @example\n * ```typescript\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const reranked = await reranker.postprocessNodes(nodes, \"search query\");\n * ```\n */\n\nimport { SIEClient, type SIEClientOptions } from \"@superlinked/sie-sdk\";\nimport { MetadataMode } from \"llamaindex\";\nimport type { BaseNodePostprocessor, MessageContent, NodeWithScore } from \"llamaindex\";\n\n/**\n * Configuration options for SIENodePostprocessor.\n */\nexport interface SIENodePostprocessorOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Reranker model name/ID.\n * @default \"jinaai/jina-reranker-v2-base-multilingual\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n * If provided, baseUrl and other connection options are ignored.\n */\n client?: SIEClient;\n\n /**\n * Number of top nodes to return. If undefined, returns all nodes.\n */\n topN?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Extract a plain query string from LlamaIndex's MessageContent type.\n *\n * MessageContent is `string | MessageContentDetail[]`. For reranking\n * we need a plain string.\n */\nfunction extractQueryString(query: MessageContent): string {\n if (typeof query === \"string\") {\n return query;\n }\n // MessageContentDetail[] — concatenate text parts\n return query\n .filter(\n (part): part is { type: \"text\"; text: string } => \"type\" in part && part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\" \");\n}\n\n/**\n * LlamaIndex node postprocessor using SIE's reranking.\n *\n * Wraps SIEClient.score() to implement the BaseNodePostprocessor interface.\n *\n * @example\n * ```typescript\n * import { VectorStoreIndex } from \"llamaindex\";\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const queryEngine = index.asQueryEngine({\n * nodePostprocessors: [reranker],\n * });\n *\n * const response = await queryEngine.query({ query: \"What is the topic?\" });\n * ```\n */\nexport class SIENodePostprocessor implements BaseNodePostprocessor {\n readonly modelName: string;\n private readonly topN?: number;\n private _client: SIEClient | undefined;\n private readonly _ownsClient: boolean;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIENodePostprocessorOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"jinaai/jina-reranker-v2-base-multilingual\",\n client,\n topN,\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.topN = topN;\n this._client = client;\n this._ownsClient = !client;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Rerank nodes by relevance to query.\n *\n * @param nodes - Nodes with scores to rerank.\n * @param query - Optional query string or MessageContent.\n * @returns Reranked nodes with updated scores, sorted by relevance descending.\n */\n async postprocessNodes(nodes: NodeWithScore[], query?: MessageContent): Promise<NodeWithScore[]> {\n if (nodes.length === 0 || query === undefined) {\n return nodes;\n }\n\n const queryText = extractQueryString(query);\n if (!queryText) {\n return nodes;\n }\n\n const queryItem = { text: queryText };\n const docItems = nodes.map((n, idx) => ({\n id: String(idx),\n text: n.node.getContent(MetadataMode.NONE),\n }));\n\n const result = await this.client.score(this.modelName, queryItem, docItems);\n\n // Map score entries back to NodeWithScore with updated scores.\n // ScoreResult.scores are already sorted by score descending, and each\n // entry's itemId echoes the id sent for its node.\n const positions = new Map(docItems.map((item, idx) => [item.id, idx]));\n const reranked: NodeWithScore[] = [];\n for (const entry of result.scores) {\n const idx = positions.get(entry.itemId);\n positions.delete(entry.itemId);\n const original = idx === undefined ? undefined : nodes[idx];\n if (original) {\n reranked.push({\n node: original.node,\n score: entry.score,\n });\n }\n }\n\n if (this.topN !== undefined) {\n return reranked.slice(0, this.topN);\n }\n return reranked;\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client && this._ownsClient) {\n await this._client.close();\n }\n }\n}\n","/**\n * SIE extraction tool for LlamaIndex.TS\n *\n * Provides extraction using SIE's extract endpoint:\n * - createSIEExtractorTool: Factory that creates a FunctionTool for extraction\n *\n * Returns entities, relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const result = await extractor.call({ text: \"John Smith works at Acme Corp\" });\n * const parsed = JSON.parse(result);\n * console.log(parsed.entities);\n * ```\n */\n\nimport {\n type ExtractOptions,\n type ExtractResult,\n RequestError,\n SIEClient,\n type SIEClientOptions,\n} from \"@superlinked/sie-sdk\";\nimport { FunctionTool } from \"llamaindex\";\n\n/**\n * Configuration options for createSIEExtractorTool.\n */\nexport interface SIEExtractorToolOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Extraction model name/ID.\n * @default \"urchade/gliner_multi-v2.1\"\n */\n modelName?: string;\n\n /**\n * Labels to extract.\n * @default [\"person\", \"organization\", \"location\"]\n */\n labels?: string[];\n\n /**\n * Minimum confidence threshold (0-1).\n */\n threshold?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Tool name for the agent.\n * @default \"sie_extract\"\n */\n name?: string;\n\n /**\n * Tool description for the agent.\n */\n description?: string;\n}\n\n/**\n * Internal class to hold SIE extractor state.\n */\nclass _SIEExtractor {\n private readonly baseUrl: string;\n private readonly modelName: string;\n private readonly labels: string[];\n private readonly threshold?: number;\n private readonly clientOptions: SIEClientOptions;\n private _client: SIEClient | undefined;\n\n constructor(options: SIEExtractorToolOptions) {\n this.baseUrl = options.baseUrl ?? \"http://localhost:8080\";\n this.modelName = options.modelName ?? \"urchade/gliner_multi-v2.1\";\n this.labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n this.threshold = options.threshold;\n this.clientOptions = {\n timeout: options.timeout ?? 180_000,\n gpu: options.gpu,\n };\n }\n\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n async extract(text: string): Promise<string> {\n const extractOptions: ExtractOptions = {\n labels: this.labels,\n };\n if (this.threshold !== undefined) {\n extractOptions.threshold = this.threshold;\n }\n\n const result: ExtractResult = await this.client.extract(\n this.modelName,\n { text },\n extractOptions,\n );\n if (result.error) {\n throw new RequestError(\n `Extraction failed: ${result.error.message}`,\n result.error.code,\n undefined,\n result.request?.id,\n );\n }\n\n return JSON.stringify({\n entities: result.entities.map((e) => ({\n text: e.text,\n label: e.label,\n score: e.score,\n ...(e.start !== undefined && { start: e.start }),\n ...(e.end !== undefined && { end: e.end }),\n })),\n relations: result.relations.map((r) => ({\n head: r.head,\n tail: r.tail,\n relation: r.relation,\n score: r.score,\n })),\n classifications: result.classifications.map((c) => ({\n label: c.label,\n score: c.score,\n })),\n objects: result.objects.map((o) => ({\n label: o.label,\n score: o.score,\n bbox: o.bbox,\n })),\n });\n }\n}\n\n/**\n * Create a LlamaIndex FunctionTool for extraction.\n *\n * Creates a tool that wraps SIE's extract endpoint for use with\n * LlamaIndex agents and workflows. Returns JSON with entities,\n * relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { OpenAI, ReActAgent } from \"llamaindex\";\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const agent = new ReActAgent({\n * tools: [extractor],\n * llm: new OpenAI(),\n * });\n *\n * const response = await agent.chat({\n * message: \"Extract entities from: John works at Google in NYC\",\n * });\n * ```\n *\n * @param options - Configuration for the extractor tool.\n * @returns FunctionTool wrapping SIE extraction.\n */\nexport function createSIEExtractorTool(options: SIEExtractorToolOptions = {}) {\n const labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n const name = options.name ?? \"sie_extract\";\n const description =\n options.description ??\n `Extract structured information from text. Finds entities of types: ${labels.join(\", \")}. Returns entities, relations, classifications, and detected objects.`;\n\n const extractor = new _SIEExtractor(options);\n\n async function extract(input: { text: string }): Promise<string> {\n return extractor.extract(input.text);\n }\n\n return FunctionTool.from(extract, {\n name,\n description,\n });\n}\n"],"mappings":"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","names":["import_sie_sdk","import_llamaindex","import_sie_sdk","import_llamaindex"]}
package/dist/index.js CHANGED
@@ -68,12 +68,17 @@ var SIENodePostprocessor = class {
68
68
  return nodes;
69
69
  }
70
70
  const queryItem = { text: queryText };
71
- const docItems = nodes.map((n) => ({ text: n.node.getContent(MetadataMode.NONE) }));
71
+ const docItems = nodes.map((n, idx) => ({
72
+ id: String(idx),
73
+ text: n.node.getContent(MetadataMode.NONE)
74
+ }));
72
75
  const result = await this.client.score(this.modelName, queryItem, docItems);
76
+ const positions = new Map(docItems.map((item, idx) => [item.id, idx]));
73
77
  const reranked = [];
74
78
  for (const entry of result.scores) {
75
- const idx = Number.parseInt(entry.itemId, 10);
76
- const original = nodes[idx];
79
+ const idx = positions.get(entry.itemId);
80
+ positions.delete(entry.itemId);
81
+ const original = idx === void 0 ? void 0 : nodes[idx];
77
82
  if (original) {
78
83
  reranked.push({
79
84
  node: original.node,
@@ -98,6 +103,7 @@ var SIENodePostprocessor = class {
98
103
 
99
104
  // src/extractors.ts
100
105
  import {
106
+ RequestError,
101
107
  SIEClient as SIEClient2
102
108
  } from "@superlinked/sie-sdk";
103
109
  import { FunctionTool } from "llamaindex";
@@ -136,6 +142,14 @@ var _SIEExtractor = class {
136
142
  { text },
137
143
  extractOptions
138
144
  );
145
+ if (result.error) {
146
+ throw new RequestError(
147
+ `Extraction failed: ${result.error.message}`,
148
+ result.error.code,
149
+ void 0,
150
+ result.request?.id
151
+ );
152
+ }
139
153
  return JSON.stringify({
140
154
  entities: result.entities.map((e) => ({
141
155
  text: e.text,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/rerankers.ts","../src/extractors.ts"],"sourcesContent":["/**\n * SIE embeddings integration for LlamaIndex.TS\n *\n * Provides embedding generation using SIE's encode endpoint:\n * - SIEEmbedding: Dense embeddings implementing BaseEmbedding\n * - SIESparseEmbeddingFunction: Sparse embeddings for hybrid search\n * - SIENodePostprocessor: Cross-encoder reranking for query pipelines\n * - createSIEExtractorTool: Entity extraction tool for agents\n *\n * @example\n * ```typescript\n * import { Settings } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n * ```\n */\n\nimport {\n type DType,\n type EncodeOptions,\n type EncodeResult,\n SIEClient,\n type SIEClientOptions,\n denseEmbedding,\n sparseEmbedding,\n} from \"@superlinked/sie-sdk\";\nimport { BaseEmbedding } from \"llamaindex\";\n\n/**\n * Configuration options for SIEEmbedding.\n */\nexport interface SIEEmbeddingOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n */\n client?: SIEClient;\n\n /**\n * Optional instruction prefix for embedding (model-dependent).\n */\n instruction?: string;\n\n /**\n * Output dtype: \"float32\" (default), \"float16\", \"int8\", \"binary\".\n */\n outputDtype?: DType;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Batch size for embedding multiple texts.\n * @default 10\n */\n embedBatchSize?: number;\n}\n\n/**\n * LlamaIndex BaseEmbedding implementation using SIE.\n *\n * Wraps SIEClient.encode() to implement the LlamaIndex BaseEmbedding interface.\n *\n * @example\n * ```typescript\n * import { Settings, VectorStoreIndex, Document } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * // Create index with documents\n * const index = await VectorStoreIndex.fromDocuments([\n * new Document({ text: \"Hello world\" }),\n * ]);\n *\n * // With GPU routing for multi-GPU clusters\n * const embedModel = new SIEEmbedding({\n * baseUrl: \"https://cluster.example.com\",\n * modelName: \"BAAI/bge-m3\",\n * gpu: \"a100-80gb\",\n * });\n * ```\n */\nexport class SIEEmbedding extends BaseEmbedding {\n readonly modelName: string;\n private readonly instruction?: string;\n private readonly outputDtype?: DType;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n /**\n * Get embeddings for multiple text strings (documents).\n * This is a property (arrow function) to match BaseEmbedding interface.\n */\n override getTextEmbeddings = async (texts: string[]): Promise<number[][]> => {\n if (texts.length === 0) {\n return [];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n return (results as EncodeResult[]).map((result) => denseEmbedding(result));\n };\n\n constructor(options: SIEEmbeddingOptions = {}) {\n super();\n\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n client,\n instruction,\n outputDtype,\n gpu,\n timeout = 180_000,\n embedBatchSize = 10,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.instruction = instruction;\n this.outputDtype = outputDtype;\n this._client = client;\n this.embedBatchSize = embedBatchSize;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Get embedding for a single text string (document).\n *\n * @param text - Text to embed.\n * @returns Embedding vector as array of numbers.\n */\n async getTextEmbedding(text: string): Promise<number[]> {\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const result = await this.client.encode(this.modelName, { text }, options);\n return denseEmbedding(result as EncodeResult);\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\n/**\n * Configuration options for SIESparseEmbeddingFunction.\n */\nexport interface SIESparseEmbeddingFunctionOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding. Must support sparse output.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Sparse embedding function for LlamaIndex hybrid search.\n *\n * Compatible with LlamaIndex vector stores that support hybrid search,\n * such as QdrantVectorStore with enableHybrid: true.\n *\n * @example\n * ```typescript\n * import { QdrantVectorStore } from \"llamaindex\";\n * import { SIESparseEmbeddingFunction } from \"@superlinked/sie-llamaindex\";\n *\n * const sparseEmbedFn = new SIESparseEmbeddingFunction({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * const vectorStore = new QdrantVectorStore({\n * client: qdrantClient,\n * collectionName: \"hybrid_docs\",\n * enableHybrid: true,\n * sparseEmbeddingFunction: sparseEmbedFn,\n * });\n * ```\n */\nexport class SIESparseEmbeddingFunction {\n private readonly modelName: string;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIESparseEmbeddingFunctionOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Encode query texts to sparse vectors.\n *\n * @param texts - List of query texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeQueries(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: true,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Encode document texts to sparse vectors.\n *\n * @param texts - List of document texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeDocuments(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\nexport { SIENodePostprocessor, type SIENodePostprocessorOptions } from \"./rerankers.js\";\nexport { createSIEExtractorTool, type SIEExtractorToolOptions } from \"./extractors.js\";\n","/**\n * SIE reranker integration for LlamaIndex.TS\n *\n * Provides node reranking using SIE's score endpoint:\n * - SIENodePostprocessor: Cross-encoder reranking implementing BaseNodePostprocessor\n *\n * @example\n * ```typescript\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const reranked = await reranker.postprocessNodes(nodes, \"search query\");\n * ```\n */\n\nimport { SIEClient, type SIEClientOptions } from \"@superlinked/sie-sdk\";\nimport { MetadataMode } from \"llamaindex\";\nimport type { BaseNodePostprocessor, MessageContent, NodeWithScore } from \"llamaindex\";\n\n/**\n * Configuration options for SIENodePostprocessor.\n */\nexport interface SIENodePostprocessorOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Reranker model name/ID.\n * @default \"jinaai/jina-reranker-v2-base-multilingual\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n * If provided, baseUrl and other connection options are ignored.\n */\n client?: SIEClient;\n\n /**\n * Number of top nodes to return. If undefined, returns all nodes.\n */\n topN?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Extract a plain query string from LlamaIndex's MessageContent type.\n *\n * MessageContent is `string | MessageContentDetail[]`. For reranking\n * we need a plain string.\n */\nfunction extractQueryString(query: MessageContent): string {\n if (typeof query === \"string\") {\n return query;\n }\n // MessageContentDetail[] — concatenate text parts\n return query\n .filter(\n (part): part is { type: \"text\"; text: string } => \"type\" in part && part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\" \");\n}\n\n/**\n * LlamaIndex node postprocessor using SIE's reranking.\n *\n * Wraps SIEClient.score() to implement the BaseNodePostprocessor interface.\n *\n * @example\n * ```typescript\n * import { VectorStoreIndex } from \"llamaindex\";\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const queryEngine = index.asQueryEngine({\n * nodePostprocessors: [reranker],\n * });\n *\n * const response = await queryEngine.query({ query: \"What is the topic?\" });\n * ```\n */\nexport class SIENodePostprocessor implements BaseNodePostprocessor {\n readonly modelName: string;\n private readonly topN?: number;\n private _client: SIEClient | undefined;\n private readonly _ownsClient: boolean;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIENodePostprocessorOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"jinaai/jina-reranker-v2-base-multilingual\",\n client,\n topN,\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.topN = topN;\n this._client = client;\n this._ownsClient = !client;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Rerank nodes by relevance to query.\n *\n * @param nodes - Nodes with scores to rerank.\n * @param query - Optional query string or MessageContent.\n * @returns Reranked nodes with updated scores, sorted by relevance descending.\n */\n async postprocessNodes(nodes: NodeWithScore[], query?: MessageContent): Promise<NodeWithScore[]> {\n if (nodes.length === 0 || query === undefined) {\n return nodes;\n }\n\n const queryText = extractQueryString(query);\n if (!queryText) {\n return nodes;\n }\n\n const queryItem = { text: queryText };\n const docItems = nodes.map((n) => ({ text: n.node.getContent(MetadataMode.NONE) }));\n\n const result = await this.client.score(this.modelName, queryItem, docItems);\n\n // Map score entries back to NodeWithScore with updated scores.\n // ScoreResult.scores are already sorted by score descending.\n const reranked: NodeWithScore[] = [];\n for (const entry of result.scores) {\n const idx = Number.parseInt(entry.itemId, 10);\n const original = nodes[idx];\n if (original) {\n reranked.push({\n node: original.node,\n score: entry.score,\n });\n }\n }\n\n if (this.topN !== undefined) {\n return reranked.slice(0, this.topN);\n }\n return reranked;\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client && this._ownsClient) {\n await this._client.close();\n }\n }\n}\n","/**\n * SIE extraction tool for LlamaIndex.TS\n *\n * Provides extraction using SIE's extract endpoint:\n * - createSIEExtractorTool: Factory that creates a FunctionTool for extraction\n *\n * Returns entities, relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const result = await extractor.call({ text: \"John Smith works at Acme Corp\" });\n * const parsed = JSON.parse(result);\n * console.log(parsed.entities);\n * ```\n */\n\nimport {\n type ExtractOptions,\n type ExtractResult,\n SIEClient,\n type SIEClientOptions,\n} from \"@superlinked/sie-sdk\";\nimport { FunctionTool } from \"llamaindex\";\n\n/**\n * Configuration options for createSIEExtractorTool.\n */\nexport interface SIEExtractorToolOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Extraction model name/ID.\n * @default \"urchade/gliner_multi-v2.1\"\n */\n modelName?: string;\n\n /**\n * Labels to extract.\n * @default [\"person\", \"organization\", \"location\"]\n */\n labels?: string[];\n\n /**\n * Minimum confidence threshold (0-1).\n */\n threshold?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Tool name for the agent.\n * @default \"sie_extract\"\n */\n name?: string;\n\n /**\n * Tool description for the agent.\n */\n description?: string;\n}\n\n/**\n * Internal class to hold SIE extractor state.\n */\nclass _SIEExtractor {\n private readonly baseUrl: string;\n private readonly modelName: string;\n private readonly labels: string[];\n private readonly threshold?: number;\n private readonly clientOptions: SIEClientOptions;\n private _client: SIEClient | undefined;\n\n constructor(options: SIEExtractorToolOptions) {\n this.baseUrl = options.baseUrl ?? \"http://localhost:8080\";\n this.modelName = options.modelName ?? \"urchade/gliner_multi-v2.1\";\n this.labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n this.threshold = options.threshold;\n this.clientOptions = {\n timeout: options.timeout ?? 180_000,\n gpu: options.gpu,\n };\n }\n\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n async extract(text: string): Promise<string> {\n const extractOptions: ExtractOptions = {\n labels: this.labels,\n };\n if (this.threshold !== undefined) {\n extractOptions.threshold = this.threshold;\n }\n\n const result: ExtractResult = await this.client.extract(\n this.modelName,\n { text },\n extractOptions,\n );\n\n return JSON.stringify({\n entities: result.entities.map((e) => ({\n text: e.text,\n label: e.label,\n score: e.score,\n ...(e.start !== undefined && { start: e.start }),\n ...(e.end !== undefined && { end: e.end }),\n })),\n relations: result.relations.map((r) => ({\n head: r.head,\n tail: r.tail,\n relation: r.relation,\n score: r.score,\n })),\n classifications: result.classifications.map((c) => ({\n label: c.label,\n score: c.score,\n })),\n objects: result.objects.map((o) => ({\n label: o.label,\n score: o.score,\n bbox: o.bbox,\n })),\n });\n }\n}\n\n/**\n * Create a LlamaIndex FunctionTool for extraction.\n *\n * Creates a tool that wraps SIE's extract endpoint for use with\n * LlamaIndex agents and workflows. Returns JSON with entities,\n * relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { OpenAI, ReActAgent } from \"llamaindex\";\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const agent = new ReActAgent({\n * tools: [extractor],\n * llm: new OpenAI(),\n * });\n *\n * const response = await agent.chat({\n * message: \"Extract entities from: John works at Google in NYC\",\n * });\n * ```\n *\n * @param options - Configuration for the extractor tool.\n * @returns FunctionTool wrapping SIE extraction.\n */\nexport function createSIEExtractorTool(options: SIEExtractorToolOptions = {}) {\n const labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n const name = options.name ?? \"sie_extract\";\n const description =\n options.description ??\n `Extract structured information from text. Finds entities of types: ${labels.join(\", \")}. Returns entities, relations, classifications, and detected objects.`;\n\n const extractor = new _SIEExtractor(options);\n\n async function extract(input: { text: string }): Promise<string> {\n return extractor.extract(input.text);\n }\n\n return FunctionTool.from(extract, {\n name,\n description,\n });\n}\n"],"mappings":"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","names":["SIEClient","SIEClient","SIEClient"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/rerankers.ts","../src/extractors.ts"],"sourcesContent":["/**\n * SIE embeddings integration for LlamaIndex.TS\n *\n * Provides embedding generation using SIE's encode endpoint:\n * - SIEEmbedding: Dense embeddings implementing BaseEmbedding\n * - SIESparseEmbeddingFunction: Sparse embeddings for hybrid search\n * - SIENodePostprocessor: Cross-encoder reranking for query pipelines\n * - createSIEExtractorTool: Entity extraction tool for agents\n *\n * @example\n * ```typescript\n * import { Settings } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n * ```\n */\n\nimport {\n type DType,\n type EncodeOptions,\n type EncodeResult,\n SIEClient,\n type SIEClientOptions,\n denseEmbedding,\n sparseEmbedding,\n} from \"@superlinked/sie-sdk\";\nimport { BaseEmbedding } from \"llamaindex\";\n\n/**\n * Configuration options for SIEEmbedding.\n */\nexport interface SIEEmbeddingOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n */\n client?: SIEClient;\n\n /**\n * Optional instruction prefix for embedding (model-dependent).\n */\n instruction?: string;\n\n /**\n * Output dtype: \"float32\" (default), \"float16\", \"int8\", \"binary\".\n */\n outputDtype?: DType;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Batch size for embedding multiple texts.\n * @default 10\n */\n embedBatchSize?: number;\n}\n\n/**\n * LlamaIndex BaseEmbedding implementation using SIE.\n *\n * Wraps SIEClient.encode() to implement the LlamaIndex BaseEmbedding interface.\n *\n * @example\n * ```typescript\n * import { Settings, VectorStoreIndex, Document } from \"llamaindex\";\n * import { SIEEmbedding } from \"@superlinked/sie-llamaindex\";\n *\n * // Set as default embedding model\n * Settings.embedModel = new SIEEmbedding({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * // Create index with documents\n * const index = await VectorStoreIndex.fromDocuments([\n * new Document({ text: \"Hello world\" }),\n * ]);\n *\n * // With GPU routing for multi-GPU clusters\n * const embedModel = new SIEEmbedding({\n * baseUrl: \"https://cluster.example.com\",\n * modelName: \"BAAI/bge-m3\",\n * gpu: \"a100-80gb\",\n * });\n * ```\n */\nexport class SIEEmbedding extends BaseEmbedding {\n readonly modelName: string;\n private readonly instruction?: string;\n private readonly outputDtype?: DType;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n /**\n * Get embeddings for multiple text strings (documents).\n * This is a property (arrow function) to match BaseEmbedding interface.\n */\n override getTextEmbeddings = async (texts: string[]): Promise<number[][]> => {\n if (texts.length === 0) {\n return [];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n return (results as EncodeResult[]).map((result) => denseEmbedding(result));\n };\n\n constructor(options: SIEEmbeddingOptions = {}) {\n super();\n\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n client,\n instruction,\n outputDtype,\n gpu,\n timeout = 180_000,\n embedBatchSize = 10,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.instruction = instruction;\n this.outputDtype = outputDtype;\n this._client = client;\n this.embedBatchSize = embedBatchSize;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Get embedding for a single text string (document).\n *\n * @param text - Text to embed.\n * @returns Embedding vector as array of numbers.\n */\n async getTextEmbedding(text: string): Promise<number[]> {\n const options: EncodeOptions = {\n outputTypes: [\"dense\"],\n instruction: this.instruction,\n outputDtype: this.outputDtype,\n isQuery: false,\n };\n\n const result = await this.client.encode(this.modelName, { text }, options);\n return denseEmbedding(result as EncodeResult);\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\n/**\n * Configuration options for SIESparseEmbeddingFunction.\n */\nexport interface SIESparseEmbeddingFunctionOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Model name/ID to use for encoding. Must support sparse output.\n * @default \"BAAI/bge-m3\"\n */\n modelName?: string;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Sparse embedding function for LlamaIndex hybrid search.\n *\n * Compatible with LlamaIndex vector stores that support hybrid search,\n * such as QdrantVectorStore with enableHybrid: true.\n *\n * @example\n * ```typescript\n * import { QdrantVectorStore } from \"llamaindex\";\n * import { SIESparseEmbeddingFunction } from \"@superlinked/sie-llamaindex\";\n *\n * const sparseEmbedFn = new SIESparseEmbeddingFunction({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"BAAI/bge-m3\",\n * });\n *\n * const vectorStore = new QdrantVectorStore({\n * client: qdrantClient,\n * collectionName: \"hybrid_docs\",\n * enableHybrid: true,\n * sparseEmbeddingFunction: sparseEmbedFn,\n * });\n * ```\n */\nexport class SIESparseEmbeddingFunction {\n private readonly modelName: string;\n private _client: SIEClient | undefined;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIESparseEmbeddingFunctionOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"BAAI/bge-m3\",\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Encode query texts to sparse vectors.\n *\n * @param texts - List of query texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeQueries(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: true,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Encode document texts to sparse vectors.\n *\n * @param texts - List of document texts to encode.\n * @returns Tuple of [indices_list, values_list].\n */\n async encodeDocuments(texts: string[]): Promise<[number[][], number[][]]> {\n if (texts.length === 0) {\n return [[], []];\n }\n\n const items = texts.map((text) => ({ text }));\n const options: EncodeOptions = {\n outputTypes: [\"sparse\"],\n isQuery: false,\n };\n\n const results = await this.client.encode(this.modelName, items, options);\n\n const indicesList: number[][] = [];\n const valuesList: number[][] = [];\n\n for (const result of results as EncodeResult[]) {\n const sparse = sparseEmbedding(result);\n indicesList.push(sparse.indices);\n valuesList.push(sparse.values);\n }\n\n return [indicesList, valuesList];\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client) {\n await this._client.close();\n }\n }\n}\n\nexport { SIENodePostprocessor, type SIENodePostprocessorOptions } from \"./rerankers.js\";\nexport { createSIEExtractorTool, type SIEExtractorToolOptions } from \"./extractors.js\";\n","/**\n * SIE reranker integration for LlamaIndex.TS\n *\n * Provides node reranking using SIE's score endpoint:\n * - SIENodePostprocessor: Cross-encoder reranking implementing BaseNodePostprocessor\n *\n * @example\n * ```typescript\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * baseUrl: \"http://localhost:8080\",\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const reranked = await reranker.postprocessNodes(nodes, \"search query\");\n * ```\n */\n\nimport { SIEClient, type SIEClientOptions } from \"@superlinked/sie-sdk\";\nimport { MetadataMode } from \"llamaindex\";\nimport type { BaseNodePostprocessor, MessageContent, NodeWithScore } from \"llamaindex\";\n\n/**\n * Configuration options for SIENodePostprocessor.\n */\nexport interface SIENodePostprocessorOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Reranker model name/ID.\n * @default \"jinaai/jina-reranker-v2-base-multilingual\"\n */\n modelName?: string;\n\n /**\n * Optional pre-configured SIEClient instance.\n * If provided, baseUrl and other connection options are ignored.\n */\n client?: SIEClient;\n\n /**\n * Number of top nodes to return. If undefined, returns all nodes.\n */\n topN?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n}\n\n/**\n * Extract a plain query string from LlamaIndex's MessageContent type.\n *\n * MessageContent is `string | MessageContentDetail[]`. For reranking\n * we need a plain string.\n */\nfunction extractQueryString(query: MessageContent): string {\n if (typeof query === \"string\") {\n return query;\n }\n // MessageContentDetail[] — concatenate text parts\n return query\n .filter(\n (part): part is { type: \"text\"; text: string } => \"type\" in part && part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\" \");\n}\n\n/**\n * LlamaIndex node postprocessor using SIE's reranking.\n *\n * Wraps SIEClient.score() to implement the BaseNodePostprocessor interface.\n *\n * @example\n * ```typescript\n * import { VectorStoreIndex } from \"llamaindex\";\n * import { SIENodePostprocessor } from \"@superlinked/sie-llamaindex\";\n *\n * const reranker = new SIENodePostprocessor({\n * modelName: \"jinaai/jina-reranker-v2-base-multilingual\",\n * topN: 3,\n * });\n *\n * const queryEngine = index.asQueryEngine({\n * nodePostprocessors: [reranker],\n * });\n *\n * const response = await queryEngine.query({ query: \"What is the topic?\" });\n * ```\n */\nexport class SIENodePostprocessor implements BaseNodePostprocessor {\n readonly modelName: string;\n private readonly topN?: number;\n private _client: SIEClient | undefined;\n private readonly _ownsClient: boolean;\n private readonly baseUrl: string;\n private readonly clientOptions: SIEClientOptions;\n\n constructor(options: SIENodePostprocessorOptions = {}) {\n const {\n baseUrl = \"http://localhost:8080\",\n modelName = \"jinaai/jina-reranker-v2-base-multilingual\",\n client,\n topN,\n gpu,\n timeout = 180_000,\n } = options;\n\n this.baseUrl = baseUrl;\n this.modelName = modelName;\n this.topN = topN;\n this._client = client;\n this._ownsClient = !client;\n\n this.clientOptions = {\n timeout,\n gpu,\n };\n }\n\n /**\n * Get or create the SIEClient.\n */\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n /**\n * Rerank nodes by relevance to query.\n *\n * @param nodes - Nodes with scores to rerank.\n * @param query - Optional query string or MessageContent.\n * @returns Reranked nodes with updated scores, sorted by relevance descending.\n */\n async postprocessNodes(nodes: NodeWithScore[], query?: MessageContent): Promise<NodeWithScore[]> {\n if (nodes.length === 0 || query === undefined) {\n return nodes;\n }\n\n const queryText = extractQueryString(query);\n if (!queryText) {\n return nodes;\n }\n\n const queryItem = { text: queryText };\n const docItems = nodes.map((n, idx) => ({\n id: String(idx),\n text: n.node.getContent(MetadataMode.NONE),\n }));\n\n const result = await this.client.score(this.modelName, queryItem, docItems);\n\n // Map score entries back to NodeWithScore with updated scores.\n // ScoreResult.scores are already sorted by score descending, and each\n // entry's itemId echoes the id sent for its node.\n const positions = new Map(docItems.map((item, idx) => [item.id, idx]));\n const reranked: NodeWithScore[] = [];\n for (const entry of result.scores) {\n const idx = positions.get(entry.itemId);\n positions.delete(entry.itemId);\n const original = idx === undefined ? undefined : nodes[idx];\n if (original) {\n reranked.push({\n node: original.node,\n score: entry.score,\n });\n }\n }\n\n if (this.topN !== undefined) {\n return reranked.slice(0, this.topN);\n }\n return reranked;\n }\n\n /**\n * Close the underlying client connection.\n */\n async close(): Promise<void> {\n if (this._client && this._ownsClient) {\n await this._client.close();\n }\n }\n}\n","/**\n * SIE extraction tool for LlamaIndex.TS\n *\n * Provides extraction using SIE's extract endpoint:\n * - createSIEExtractorTool: Factory that creates a FunctionTool for extraction\n *\n * Returns entities, relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const result = await extractor.call({ text: \"John Smith works at Acme Corp\" });\n * const parsed = JSON.parse(result);\n * console.log(parsed.entities);\n * ```\n */\n\nimport {\n type ExtractOptions,\n type ExtractResult,\n RequestError,\n SIEClient,\n type SIEClientOptions,\n} from \"@superlinked/sie-sdk\";\nimport { FunctionTool } from \"llamaindex\";\n\n/**\n * Configuration options for createSIEExtractorTool.\n */\nexport interface SIEExtractorToolOptions {\n /**\n * URL of the SIE server.\n * @default \"http://localhost:8080\"\n */\n baseUrl?: string;\n\n /**\n * Extraction model name/ID.\n * @default \"urchade/gliner_multi-v2.1\"\n */\n modelName?: string;\n\n /**\n * Labels to extract.\n * @default [\"person\", \"organization\", \"location\"]\n */\n labels?: string[];\n\n /**\n * Minimum confidence threshold (0-1).\n */\n threshold?: number;\n\n /**\n * Target GPU type for routing (e.g., \"l4\", \"a100-80gb\").\n */\n gpu?: string;\n\n /**\n * Request timeout in milliseconds.\n * @default 180000 (3 minutes)\n */\n timeout?: number;\n\n /**\n * Tool name for the agent.\n * @default \"sie_extract\"\n */\n name?: string;\n\n /**\n * Tool description for the agent.\n */\n description?: string;\n}\n\n/**\n * Internal class to hold SIE extractor state.\n */\nclass _SIEExtractor {\n private readonly baseUrl: string;\n private readonly modelName: string;\n private readonly labels: string[];\n private readonly threshold?: number;\n private readonly clientOptions: SIEClientOptions;\n private _client: SIEClient | undefined;\n\n constructor(options: SIEExtractorToolOptions) {\n this.baseUrl = options.baseUrl ?? \"http://localhost:8080\";\n this.modelName = options.modelName ?? \"urchade/gliner_multi-v2.1\";\n this.labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n this.threshold = options.threshold;\n this.clientOptions = {\n timeout: options.timeout ?? 180_000,\n gpu: options.gpu,\n };\n }\n\n private get client(): SIEClient {\n if (!this._client) {\n this._client = new SIEClient(this.baseUrl, this.clientOptions);\n }\n return this._client;\n }\n\n async extract(text: string): Promise<string> {\n const extractOptions: ExtractOptions = {\n labels: this.labels,\n };\n if (this.threshold !== undefined) {\n extractOptions.threshold = this.threshold;\n }\n\n const result: ExtractResult = await this.client.extract(\n this.modelName,\n { text },\n extractOptions,\n );\n if (result.error) {\n throw new RequestError(\n `Extraction failed: ${result.error.message}`,\n result.error.code,\n undefined,\n result.request?.id,\n );\n }\n\n return JSON.stringify({\n entities: result.entities.map((e) => ({\n text: e.text,\n label: e.label,\n score: e.score,\n ...(e.start !== undefined && { start: e.start }),\n ...(e.end !== undefined && { end: e.end }),\n })),\n relations: result.relations.map((r) => ({\n head: r.head,\n tail: r.tail,\n relation: r.relation,\n score: r.score,\n })),\n classifications: result.classifications.map((c) => ({\n label: c.label,\n score: c.score,\n })),\n objects: result.objects.map((o) => ({\n label: o.label,\n score: o.score,\n bbox: o.bbox,\n })),\n });\n }\n}\n\n/**\n * Create a LlamaIndex FunctionTool for extraction.\n *\n * Creates a tool that wraps SIE's extract endpoint for use with\n * LlamaIndex agents and workflows. Returns JSON with entities,\n * relations, classifications, and detected objects.\n *\n * @example\n * ```typescript\n * import { OpenAI, ReActAgent } from \"llamaindex\";\n * import { createSIEExtractorTool } from \"@superlinked/sie-llamaindex\";\n *\n * const extractor = createSIEExtractorTool({\n * modelName: \"urchade/gliner_multi-v2.1\",\n * labels: [\"person\", \"organization\", \"location\"],\n * });\n *\n * const agent = new ReActAgent({\n * tools: [extractor],\n * llm: new OpenAI(),\n * });\n *\n * const response = await agent.chat({\n * message: \"Extract entities from: John works at Google in NYC\",\n * });\n * ```\n *\n * @param options - Configuration for the extractor tool.\n * @returns FunctionTool wrapping SIE extraction.\n */\nexport function createSIEExtractorTool(options: SIEExtractorToolOptions = {}) {\n const labels = options.labels ?? [\"person\", \"organization\", \"location\"];\n const name = options.name ?? \"sie_extract\";\n const description =\n options.description ??\n `Extract structured information from text. Finds entities of types: ${labels.join(\", \")}. Returns entities, relations, classifications, and detected objects.`;\n\n const extractor = new _SIEExtractor(options);\n\n async function extract(input: { text: string }): Promise<string> {\n return extractor.extract(input.text);\n }\n\n return FunctionTool.from(extract, {\n name,\n description,\n });\n}\n"],"mappings":"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","names":["SIEClient","SIEClient","SIEClient"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superlinked/sie-llamaindex",
3
- "version": "0.8.3",
3
+ "version": "0.9.0",
4
4
  "description": "SIE embeddings integration for LlamaIndex.TS",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -17,7 +17,7 @@
17
17
  "dist"
18
18
  ],
19
19
  "dependencies": {
20
- "@superlinked/sie-sdk": "0.8.3"
20
+ "@superlinked/sie-sdk": "0.9.0"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "llamaindex": ">=0.6.0"