@mcp-abap-adt/openai-embedder 11.0.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/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # @mcp-abap-adt/openai-embedder
2
+
3
+ OpenAI embedding provider for @mcp-abap-adt/llm-agent. Implements `IEmbedderBatch`; uses native `fetch`.
4
+
5
+ ## Exports
6
+
7
+ - `OpenAiEmbedder` — implements IEmbedderBatch, calls OpenAI /v1/embeddings.
8
+ - `OpenAiEmbedderConfig` — configuration type.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install @mcp-abap-adt/openai-embedder
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```ts
19
+ import { OpenAiEmbedder } from '@mcp-abap-adt/openai-embedder';
20
+
21
+ const embedder = new OpenAiEmbedder({
22
+ apiKey: 'sk-...',
23
+ model: 'text-embedding-3-small',
24
+ });
25
+
26
+ const result = await embedder.embed('Hello world');
27
+ console.log(result.vector);
28
+ ```
29
+
30
+ Optional peer dependency of @mcp-abap-adt/llm-agent-server.
@@ -0,0 +1,3 @@
1
+ export type { OpenAiEmbedderConfig } from './openai-embedder.js';
2
+ export { OpenAiEmbedder } from './openai-embedder.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { OpenAiEmbedder } from './openai-embedder.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { IEmbedderBatch, IEmbedResult } from '@mcp-abap-adt/llm-agent';
2
+ import { type CallOptions } from '@mcp-abap-adt/llm-agent';
3
+ export interface OpenAiEmbedderConfig {
4
+ /** API key for OpenAI-compatible service */
5
+ apiKey: string;
6
+ /** API base URL. Default: 'https://api.openai.com/v1' */
7
+ baseURL?: string;
8
+ /** Embedding model. Default: 'text-embedding-3-small' */
9
+ model?: string;
10
+ /** Per-request timeout in milliseconds. Default: 30 000 */
11
+ timeoutMs?: number;
12
+ }
13
+ export declare class OpenAiEmbedder implements IEmbedderBatch {
14
+ private readonly baseURL;
15
+ private readonly apiKey;
16
+ private readonly model;
17
+ private readonly timeoutMs;
18
+ constructor(config: OpenAiEmbedderConfig);
19
+ embed(text: string, options?: CallOptions): Promise<IEmbedResult>;
20
+ embedBatch(texts: string[], options?: CallOptions): Promise<IEmbedResult[]>;
21
+ }
22
+ //# sourceMappingURL=openai-embedder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-embedder.d.ts","sourceRoot":"","sources":["../src/openai-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,yBAAyB,CAAC;AAErE,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,cAAe,YAAW,cAAc;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,EAAE,oBAAoB;IAclC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAwDjE,UAAU,CACd,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,YAAY,EAAE,CAAC;CAwE3B"}
@@ -0,0 +1,122 @@
1
+ import { RagError } from '@mcp-abap-adt/llm-agent';
2
+ export class OpenAiEmbedder {
3
+ baseURL;
4
+ apiKey;
5
+ model;
6
+ timeoutMs;
7
+ constructor(config) {
8
+ this.apiKey = config.apiKey;
9
+ this.baseURL = (config.baseURL ?? 'https://api.openai.com/v1').replace(/\/$/, '');
10
+ this.model = config.model ?? 'text-embedding-3-small';
11
+ this.timeoutMs = config.timeoutMs ?? 30_000;
12
+ if (!this.apiKey) {
13
+ throw new Error('OpenAI API key is required for embedding');
14
+ }
15
+ }
16
+ async embed(text, options) {
17
+ const url = `${this.baseURL}/embeddings`;
18
+ let lastError;
19
+ const maxRetries = 3;
20
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
21
+ try {
22
+ const timeoutSignal = AbortSignal.timeout(this.timeoutMs);
23
+ const signal = options?.signal
24
+ ? AbortSignal.any([options.signal, timeoutSignal])
25
+ : timeoutSignal;
26
+ const res = await fetch(url, {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Content-Type': 'application/json',
30
+ Authorization: `Bearer ${this.apiKey}`,
31
+ },
32
+ body: JSON.stringify({ model: this.model, input: text }),
33
+ signal,
34
+ });
35
+ if (!res.ok) {
36
+ const errorText = await res.text();
37
+ throw new RagError(`OpenAI embed error: HTTP ${res.status} - ${errorText}`, 'EMBED_ERROR');
38
+ }
39
+ const json = (await res.json());
40
+ const vector = json.data[0].embedding;
41
+ const usage = json.usage
42
+ ? {
43
+ promptTokens: json.usage.prompt_tokens,
44
+ totalTokens: json.usage.total_tokens,
45
+ }
46
+ : undefined;
47
+ return { vector, usage };
48
+ }
49
+ catch (err) {
50
+ lastError = err instanceof Error ? err : new Error(String(err));
51
+ if (err instanceof Error && err.name === 'AbortError')
52
+ throw err;
53
+ const delay = 500 * 2 ** attempt;
54
+ await new Promise((resolve) => setTimeout(resolve, delay));
55
+ }
56
+ }
57
+ throw (lastError ||
58
+ new RagError('OpenAI embed failed after retries', 'EMBED_ERROR'));
59
+ }
60
+ async embedBatch(texts, options) {
61
+ if (texts.length === 0)
62
+ return [];
63
+ const chunkSize = 100;
64
+ const results = new Array(texts.length);
65
+ for (let start = 0; start < texts.length; start += chunkSize) {
66
+ const chunk = texts.slice(start, start + chunkSize);
67
+ const url = `${this.baseURL}/embeddings`;
68
+ let lastError;
69
+ const maxRetries = 3;
70
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
71
+ try {
72
+ const timeoutSignal = AbortSignal.timeout(this.timeoutMs);
73
+ const signal = options?.signal
74
+ ? AbortSignal.any([options.signal, timeoutSignal])
75
+ : timeoutSignal;
76
+ const res = await fetch(url, {
77
+ method: 'POST',
78
+ headers: {
79
+ 'Content-Type': 'application/json',
80
+ Authorization: `Bearer ${this.apiKey}`,
81
+ },
82
+ body: JSON.stringify({ model: this.model, input: chunk }),
83
+ signal,
84
+ });
85
+ if (!res.ok) {
86
+ const errorText = await res.text();
87
+ throw new RagError(`OpenAI batch embed error: HTTP ${res.status} - ${errorText}`, 'EMBED_ERROR');
88
+ }
89
+ const json = (await res.json());
90
+ const sorted = json.data.sort((a, b) => a.index - b.index);
91
+ const chunkLen = sorted.length;
92
+ const usagePerItem = json.usage
93
+ ? {
94
+ promptTokens: Math.round(json.usage.prompt_tokens / chunkLen),
95
+ totalTokens: Math.round(json.usage.total_tokens / chunkLen),
96
+ }
97
+ : undefined;
98
+ for (let i = 0; i < sorted.length; i++) {
99
+ results[start + i] = {
100
+ vector: sorted[i].embedding,
101
+ usage: usagePerItem,
102
+ };
103
+ }
104
+ lastError = undefined;
105
+ break;
106
+ }
107
+ catch (err) {
108
+ lastError = err instanceof Error ? err : new Error(String(err));
109
+ if (err instanceof Error && err.name === 'AbortError')
110
+ throw err;
111
+ const delay = 500 * 2 ** attempt;
112
+ await new Promise((resolve) => setTimeout(resolve, delay));
113
+ }
114
+ }
115
+ if (lastError) {
116
+ throw lastError;
117
+ }
118
+ }
119
+ return results;
120
+ }
121
+ }
122
+ //# sourceMappingURL=openai-embedder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-embedder.js","sourceRoot":"","sources":["../src/openai-embedder.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@mcp-abap-adt/openai-embedder",
3
+ "version": "11.0.0",
4
+ "description": "OpenAI embedding provider (IEmbedderBatch) for @mcp-abap-adt/llm-agent.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.json",
22
+ "clean": "tsc -p tsconfig.json --clean",
23
+ "test": "node --import tsx/esm --test --test-reporter=spec 'src/**/*.test.ts'"
24
+ },
25
+ "dependencies": {
26
+ "@mcp-abap-adt/llm-agent": "*"
27
+ },
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/fr0ster/llm-agent.git"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ }
36
+ }