@mcp-abap-adt/sap-aicore-embedder 26.0.0 → 28.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 +34 -8
- package/dist/foundation-embedder.d.ts +14 -10
- package/dist/foundation-embedder.d.ts.map +1 -1
- package/dist/foundation-embedder.js +7 -18
- package/dist/foundation-embedder.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestration-embedder.d.ts +31 -0
- package/dist/orchestration-embedder.d.ts.map +1 -1
- package/dist/orchestration-embedder.js +40 -4
- package/dist/orchestration-embedder.js.map +1 -1
- package/dist/sap-ai-core-embedder.d.ts +10 -6
- package/dist/sap-ai-core-embedder.d.ts.map +1 -1
- package/dist/sap-ai-core-embedder.js +5 -2
- package/dist/sap-ai-core-embedder.js.map +1 -1
- package/package.json +7 -3
- package/dist/auth.d.ts +0 -23
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -56
- package/dist/auth.js.map +0 -1
- package/dist/service-key.d.ts +0 -10
- package/dist/service-key.d.ts.map +0 -1
- package/dist/service-key.js +0 -27
- package/dist/service-key.js.map +0 -1
package/README.md
CHANGED
|
@@ -17,10 +17,15 @@ npm install @mcp-abap-adt/sap-aicore-embedder
|
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
19
|
import { SapAiCoreEmbedder } from '@mcp-abap-adt/sap-aicore-embedder';
|
|
20
|
+
import { serviceKeyCredential } from '@mcp-abap-adt/sap-aicore-auth';
|
|
21
|
+
|
|
22
|
+
const { credential, apiBaseUrl } = serviceKeyCredential(process.env.AICORE_SERVICE_KEY!);
|
|
20
23
|
|
|
21
24
|
const embedder = new SapAiCoreEmbedder({
|
|
22
25
|
model: 'text-embedding-3-small',
|
|
23
26
|
resourceGroup: 'default', // optional
|
|
27
|
+
credential,
|
|
28
|
+
apiBaseUrl,
|
|
24
29
|
});
|
|
25
30
|
|
|
26
31
|
// Embed a single text
|
|
@@ -39,22 +44,31 @@ interface SapAiCoreEmbedderConfig {
|
|
|
39
44
|
model: string;
|
|
40
45
|
resourceGroup?: string; // default: 'default'
|
|
41
46
|
scenario?: 'foundation-models' | 'orchestration'; // default: 'orchestration'
|
|
42
|
-
|
|
47
|
+
credential: IBearerCredential; // required, both scenarios — resolved fresh per call
|
|
48
|
+
apiBaseUrl: string; // required, both scenarios
|
|
43
49
|
}
|
|
44
50
|
```
|
|
45
51
|
|
|
52
|
+
`credential` and `apiBaseUrl` are required for both scenarios and are never
|
|
53
|
+
read from the environment inside this package. Build them from a raw SAP AI
|
|
54
|
+
Core service key with `serviceKeyCredential` from `@mcp-abap-adt/sap-aicore-auth`
|
|
55
|
+
— see [Authentication](#authentication) below. `IBearerCredential` comes from
|
|
56
|
+
`@mcp-abap-adt/interfaces-auth`.
|
|
57
|
+
|
|
46
58
|
### Orchestration (default)
|
|
47
59
|
|
|
48
|
-
The default scenario — matches v11.0.0 behavior. Use this when the embedding model is deployed under the `orchestration` scenario.
|
|
60
|
+
The default scenario — matches v11.0.0 behavior. Use this when the embedding model is deployed under the `orchestration` scenario.
|
|
49
61
|
|
|
50
62
|
```ts
|
|
51
63
|
import { SapAiCoreEmbedder } from '@mcp-abap-adt/sap-aicore-embedder';
|
|
64
|
+
import { serviceKeyCredential } from '@mcp-abap-adt/sap-aicore-auth';
|
|
52
65
|
|
|
53
|
-
const embedder = new SapAiCoreEmbedder({
|
|
66
|
+
const embedder = new SapAiCoreEmbedder({
|
|
67
|
+
model: 'text-embedding-3-small',
|
|
68
|
+
...serviceKeyCredential(process.env.AICORE_SERVICE_KEY!),
|
|
69
|
+
});
|
|
54
70
|
```
|
|
55
71
|
|
|
56
|
-
Existing v11.0.0 consumers require no config changes.
|
|
57
|
-
|
|
58
72
|
### Foundation-models
|
|
59
73
|
|
|
60
74
|
Opt-in path for tenants where embedding models (such as `gemini-embedding` or `text-embedding-3-small`) are deployed under the `foundation-models` scenario rather than the orchestration scenario. The embedder calls the AI Core REST inference API directly.
|
|
@@ -63,8 +77,8 @@ Opt-in path for tenants where embedding models (such as `gemini-embedding` or `t
|
|
|
63
77
|
const embedder = new SapAiCoreEmbedder({
|
|
64
78
|
model: 'gemini-embedding',
|
|
65
79
|
scenario: 'foundation-models',
|
|
80
|
+
...serviceKeyCredential(process.env.AICORE_SERVICE_KEY!),
|
|
66
81
|
});
|
|
67
|
-
// Auth: process.env.AICORE_SERVICE_KEY (client_credentials flow)
|
|
68
82
|
```
|
|
69
83
|
|
|
70
84
|
#### Batch size cap
|
|
@@ -81,9 +95,21 @@ quota is stricter than the model's documented limit.
|
|
|
81
95
|
|
|
82
96
|
## Authentication
|
|
83
97
|
|
|
84
|
-
|
|
98
|
+
Neither scenario reads an environment variable inside this package — the
|
|
99
|
+
caller resolves the credential and passes it in. `serviceKeyCredential(raw)`
|
|
100
|
+
(`@mcp-abap-adt/sap-aicore-auth`) turns a raw SAP AI Core service-key JSON
|
|
101
|
+
string into the `{ credential, apiBaseUrl }` pair both scenarios need:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { serviceKeyCredential } from '@mcp-abap-adt/sap-aicore-auth';
|
|
105
|
+
|
|
106
|
+
const { credential, apiBaseUrl } = serviceKeyCredential(process.env.AICORE_SERVICE_KEY!);
|
|
107
|
+
```
|
|
85
108
|
|
|
86
|
-
|
|
109
|
+
`credential.token()` is asked fresh on every `embed()`/`embedBatch()` call —
|
|
110
|
+
never cached on the embedder instance — so a rotating token keeps rotating.
|
|
111
|
+
Reading `AICORE_SERVICE_KEY` (or any other environment variable) is the
|
|
112
|
+
composition root's job, not this package's.
|
|
87
113
|
|
|
88
114
|
## License
|
|
89
115
|
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
+
import type { IBearerCredential } from '@mcp-abap-adt/interfaces-auth';
|
|
1
2
|
import type { IEmbedderBatch, IEmbedResult } from '@mcp-abap-adt/llm-agent';
|
|
2
3
|
import { type CallOptions } from '@mcp-abap-adt/llm-agent';
|
|
3
|
-
export interface FoundationModelsCredentials {
|
|
4
|
-
clientId: string;
|
|
5
|
-
clientSecret: string;
|
|
6
|
-
tokenUrl: string;
|
|
7
|
-
apiBaseUrl: string;
|
|
8
|
-
}
|
|
9
4
|
export interface FoundationModelsEmbedderConfig {
|
|
10
5
|
model: string;
|
|
11
6
|
resourceGroup?: string;
|
|
12
|
-
/**
|
|
13
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The bearer credential presented to SAP AI Core. Asked for fresh on every
|
|
9
|
+
* `embed()`/`embedBatch()` call — never cached here, so a rotating token
|
|
10
|
+
* keeps rotating. Build one from a service key with `serviceKeyCredential`
|
|
11
|
+
* (`@mcp-abap-adt/sap-aicore-auth`).
|
|
12
|
+
*/
|
|
13
|
+
credential: IBearerCredential;
|
|
14
|
+
/**
|
|
15
|
+
* SAP AI Core REST inference base URL. Not part of the credential
|
|
16
|
+
* (§4.6.3) — its own field, the name `parseServiceKey` returns.
|
|
17
|
+
*/
|
|
18
|
+
apiBaseUrl: string;
|
|
14
19
|
/**
|
|
15
20
|
* Azure OpenAI api-version query parameter for OpenAI-family deployments.
|
|
16
21
|
* Default: '2023-05-15'. Ignored for Gemini-family models.
|
|
@@ -23,7 +28,7 @@ export declare class FoundationModelsEmbedder implements IEmbedderBatch {
|
|
|
23
28
|
private readonly azureApiVersion;
|
|
24
29
|
private readonly resourceGroup;
|
|
25
30
|
private readonly apiBaseUrl;
|
|
26
|
-
private readonly
|
|
31
|
+
private readonly credential;
|
|
27
32
|
private deploymentIdPromise;
|
|
28
33
|
/**
|
|
29
34
|
* Provider batch cap, set only for families with a confirmed limit — see
|
|
@@ -39,6 +44,5 @@ export declare class FoundationModelsEmbedder implements IEmbedderBatch {
|
|
|
39
44
|
embedBatch(texts: string[], _options?: CallOptions): Promise<IEmbedResult[]>;
|
|
40
45
|
private requestEmbeddings;
|
|
41
46
|
private getDeploymentId;
|
|
42
|
-
private loadCredentialsFromEnv;
|
|
43
47
|
}
|
|
44
48
|
//# sourceMappingURL=foundation-embedder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundation-embedder.d.ts","sourceRoot":"","sources":["../src/foundation-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"foundation-embedder.d.ts","sourceRoot":"","sources":["../src/foundation-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,yBAAyB,CAAC;AAIrE,MAAM,WAAW,8BAA8B;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAiBD,qBAAa,wBAAyB,YAAW,cAAc;IAC7D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,mBAAmB,CAAgC;IAE3D;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAEnB,MAAM,EAAE,8BAA8B;IAU5C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAQlE,UAAU,CACd,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC;YAUZ,iBAAiB;IAuD/B,OAAO,CAAC,eAAe;CAcxB"}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { RagError } from '@mcp-abap-adt/llm-agent';
|
|
2
|
-
import { TokenProvider } from './auth.js';
|
|
3
2
|
import { decodeEmbedding } from './decode-embedding.js';
|
|
4
3
|
import { resolveDeploymentId } from './deployments.js';
|
|
5
|
-
import { parseServiceKey } from './service-key.js';
|
|
6
4
|
export class FoundationModelsEmbedder {
|
|
7
5
|
model;
|
|
8
6
|
family;
|
|
9
7
|
azureApiVersion;
|
|
10
8
|
resourceGroup;
|
|
11
9
|
apiBaseUrl;
|
|
12
|
-
|
|
10
|
+
credential;
|
|
13
11
|
deploymentIdPromise = null;
|
|
14
12
|
/**
|
|
15
13
|
* Provider batch cap, set only for families with a confirmed limit — see
|
|
@@ -21,17 +19,12 @@ export class FoundationModelsEmbedder {
|
|
|
21
19
|
*/
|
|
22
20
|
maxBatchSize;
|
|
23
21
|
constructor(config) {
|
|
24
|
-
const creds = config.credentials ?? this.loadCredentialsFromEnv();
|
|
25
22
|
this.model = config.model;
|
|
26
23
|
this.family = detectFamily(config.model);
|
|
27
24
|
this.azureApiVersion = config.azureApiVersion ?? '2023-05-15';
|
|
28
25
|
this.resourceGroup = config.resourceGroup ?? 'default';
|
|
29
|
-
this.apiBaseUrl =
|
|
30
|
-
this.
|
|
31
|
-
clientId: creds.clientId,
|
|
32
|
-
clientSecret: creds.clientSecret,
|
|
33
|
-
tokenUrl: creds.tokenUrl,
|
|
34
|
-
});
|
|
26
|
+
this.apiBaseUrl = config.apiBaseUrl;
|
|
27
|
+
this.credential = config.credential;
|
|
35
28
|
if (this.family === 'gemini')
|
|
36
29
|
this.maxBatchSize = 250;
|
|
37
30
|
}
|
|
@@ -53,7 +46,10 @@ export class FoundationModelsEmbedder {
|
|
|
53
46
|
return sorted.map((item) => ({ vector: decodeEmbedding(item.embedding) }));
|
|
54
47
|
}
|
|
55
48
|
async requestEmbeddings(input) {
|
|
56
|
-
|
|
49
|
+
// Asked fresh on every request — never cached on the instance — so a
|
|
50
|
+
// rotating credential (client-credentials exchange, Entra ID, ...) keeps
|
|
51
|
+
// rotating rather than being frozen at construction time.
|
|
52
|
+
const token = await this.credential.token();
|
|
57
53
|
const deploymentId = await this.getDeploymentId(token);
|
|
58
54
|
const base = `${this.apiBaseUrl}/v2/inference/deployments/${deploymentId}`;
|
|
59
55
|
const headers = {
|
|
@@ -111,13 +107,6 @@ export class FoundationModelsEmbedder {
|
|
|
111
107
|
}
|
|
112
108
|
return this.deploymentIdPromise;
|
|
113
109
|
}
|
|
114
|
-
loadCredentialsFromEnv() {
|
|
115
|
-
const raw = process.env.AICORE_SERVICE_KEY;
|
|
116
|
-
if (!raw) {
|
|
117
|
-
throw new Error('SapAiCoreEmbedder (foundation-models): no credentials provided and AICORE_SERVICE_KEY env var is not set');
|
|
118
|
-
}
|
|
119
|
-
return parseServiceKey(raw);
|
|
120
|
-
}
|
|
121
110
|
}
|
|
122
111
|
function detectFamily(model) {
|
|
123
112
|
return /^gemini/i.test(model) ? 'gemini' : 'azure-openai';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundation-embedder.js","sourceRoot":"","sources":["../src/foundation-embedder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"foundation-embedder.js","sourceRoot":"","sources":["../src/foundation-embedder.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { SapAiCoreEmbedderConfig, SapAiCoreEmbedderScenario, } from './sap-ai-core-embedder.js';
|
|
2
2
|
export { SapAiCoreEmbedder } from './sap-ai-core-embedder.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -1,15 +1,46 @@
|
|
|
1
|
+
import type { IBearerCredential } from '@mcp-abap-adt/interfaces-auth';
|
|
1
2
|
import type { IEmbedderBatch, IEmbedResult } from '@mcp-abap-adt/llm-agent';
|
|
2
3
|
import { type CallOptions } from '@mcp-abap-adt/llm-agent';
|
|
3
4
|
export interface OrchestrationScenarioEmbedderConfig {
|
|
4
5
|
model: string;
|
|
5
6
|
resourceGroup?: string;
|
|
7
|
+
/**
|
|
8
|
+
* The bearer credential presented to SAP AI Core. Asked for fresh on every
|
|
9
|
+
* `embed()`/`embedBatch()` call via `buildDestination` — never cached here.
|
|
10
|
+
* Build one from a service key with `serviceKeyCredential`
|
|
11
|
+
* (`@mcp-abap-adt/sap-aicore-auth`).
|
|
12
|
+
*/
|
|
13
|
+
credential: IBearerCredential;
|
|
14
|
+
/**
|
|
15
|
+
* SAP AI Core orchestration base URL. Not part of the credential
|
|
16
|
+
* (§4.6.3) — its own field, the name `parseServiceKey` returns.
|
|
17
|
+
*/
|
|
18
|
+
apiBaseUrl: string;
|
|
19
|
+
}
|
|
20
|
+
/** The constructed-destination shape the SAP AI SDK documents. */
|
|
21
|
+
export interface OrchestrationEmbedderDestination {
|
|
22
|
+
url: string;
|
|
23
|
+
authentication: 'NoAuthentication';
|
|
24
|
+
headers: Record<string, string>;
|
|
6
25
|
}
|
|
7
26
|
export declare class OrchestrationScenarioEmbedder implements IEmbedderBatch {
|
|
8
27
|
private readonly model;
|
|
9
28
|
private readonly resourceGroup?;
|
|
29
|
+
private readonly apiBaseUrl;
|
|
30
|
+
private readonly credential;
|
|
10
31
|
constructor(config: OrchestrationScenarioEmbedderConfig);
|
|
11
32
|
embed(text: string, _options?: CallOptions): Promise<IEmbedResult>;
|
|
12
33
|
embedBatch(texts: string[], _options?: CallOptions): Promise<IEmbedResult[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Create an OrchestrationEmbeddingClient for the given destination.
|
|
36
|
+
*
|
|
37
|
+
* `destination` is built by the caller via `buildDestination()`, per call —
|
|
38
|
+
* same split as `SapCoreAIProvider.createClient()` in `sap-aicore-llm`,
|
|
39
|
+
* deliberately: it lets a test spy on this method and observe the
|
|
40
|
+
* destination (and the credential's token behind it) that `embed()`/
|
|
41
|
+
* `embedBatch()` actually computed, the way `sap-core-ai-provider.test.ts`
|
|
42
|
+
* already does for the LLM provider.
|
|
43
|
+
*/
|
|
13
44
|
private createClient;
|
|
14
45
|
}
|
|
15
46
|
//# sourceMappingURL=orchestration-embedder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestration-embedder.d.ts","sourceRoot":"","sources":["../src/orchestration-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,yBAAyB,CAAC;AAGrE,MAAM,WAAW,mCAAmC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"orchestration-embedder.d.ts","sourceRoot":"","sources":["../src/orchestration-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,yBAAyB,CAAC;AAGrE,MAAM,WAAW,mCAAmC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,kEAAkE;AAClE,MAAM,WAAW,gCAAgC;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,kBAAkB,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAoBD,qBAAa,6BAA8B,YAAW,cAAc;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;gBAEnC,MAAM,EAAE,mCAAmC;IAOjD,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAclE,UAAU,CACd,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC;IAgB1B;;;;;;;;;OASG;YACW,YAAY;CAY3B"}
|
|
@@ -1,14 +1,36 @@
|
|
|
1
1
|
import { RagError } from '@mcp-abap-adt/llm-agent';
|
|
2
2
|
import { decodeEmbedding } from './decode-embedding.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build the constructed-destination the SDK documents. Called from
|
|
5
|
+
* `embed()`/`embedBatch()` — never at construction, never cached — so a
|
|
6
|
+
* later call re-asks the credential rather than reusing a token that may
|
|
7
|
+
* already be stale. Mirrors `sap-core-ai-provider.ts`'s `buildDestination`
|
|
8
|
+
* (not imported from there: this package does not depend on `sap-aicore-llm`).
|
|
9
|
+
*/
|
|
10
|
+
async function buildDestination(cfg) {
|
|
11
|
+
return {
|
|
12
|
+
url: cfg.apiBaseUrl,
|
|
13
|
+
authentication: 'NoAuthentication',
|
|
14
|
+
headers: { Authorization: `Bearer ${await cfg.credential.token()}` },
|
|
15
|
+
};
|
|
16
|
+
}
|
|
3
17
|
export class OrchestrationScenarioEmbedder {
|
|
4
18
|
model;
|
|
5
19
|
resourceGroup;
|
|
20
|
+
apiBaseUrl;
|
|
21
|
+
credential;
|
|
6
22
|
constructor(config) {
|
|
7
23
|
this.model = config.model;
|
|
8
24
|
this.resourceGroup = config.resourceGroup;
|
|
25
|
+
this.apiBaseUrl = config.apiBaseUrl;
|
|
26
|
+
this.credential = config.credential;
|
|
9
27
|
}
|
|
10
28
|
async embed(text, _options) {
|
|
11
|
-
const
|
|
29
|
+
const destination = await buildDestination({
|
|
30
|
+
apiBaseUrl: this.apiBaseUrl,
|
|
31
|
+
credential: this.credential,
|
|
32
|
+
});
|
|
33
|
+
const client = await this.createClient(destination);
|
|
12
34
|
const response = await client.embed({ input: text });
|
|
13
35
|
const embeddings = response.getEmbeddings();
|
|
14
36
|
if (!embeddings || embeddings.length === 0) {
|
|
@@ -19,7 +41,11 @@ export class OrchestrationScenarioEmbedder {
|
|
|
19
41
|
async embedBatch(texts, _options) {
|
|
20
42
|
if (texts.length === 0)
|
|
21
43
|
return [];
|
|
22
|
-
const
|
|
44
|
+
const destination = await buildDestination({
|
|
45
|
+
apiBaseUrl: this.apiBaseUrl,
|
|
46
|
+
credential: this.credential,
|
|
47
|
+
});
|
|
48
|
+
const client = await this.createClient(destination);
|
|
23
49
|
const response = await client.embed({ input: texts });
|
|
24
50
|
const embeddings = response.getEmbeddings();
|
|
25
51
|
if (!embeddings || embeddings.length === 0) {
|
|
@@ -28,11 +54,21 @@ export class OrchestrationScenarioEmbedder {
|
|
|
28
54
|
const sorted = [...embeddings].sort((a, b) => a.index - b.index);
|
|
29
55
|
return sorted.map((e) => ({ vector: decodeEmbedding(e.embedding) }));
|
|
30
56
|
}
|
|
31
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Create an OrchestrationEmbeddingClient for the given destination.
|
|
59
|
+
*
|
|
60
|
+
* `destination` is built by the caller via `buildDestination()`, per call —
|
|
61
|
+
* same split as `SapCoreAIProvider.createClient()` in `sap-aicore-llm`,
|
|
62
|
+
* deliberately: it lets a test spy on this method and observe the
|
|
63
|
+
* destination (and the credential's token behind it) that `embed()`/
|
|
64
|
+
* `embedBatch()` actually computed, the way `sap-core-ai-provider.test.ts`
|
|
65
|
+
* already does for the LLM provider.
|
|
66
|
+
*/
|
|
67
|
+
async createClient(destination) {
|
|
32
68
|
const { OrchestrationEmbeddingClient } = await import('@sap-ai-sdk/orchestration');
|
|
33
69
|
const modelName = this
|
|
34
70
|
.model;
|
|
35
|
-
return new OrchestrationEmbeddingClient({ embeddings: { model: { name: modelName } } }, this.resourceGroup ? { resourceGroup: this.resourceGroup } : undefined);
|
|
71
|
+
return new OrchestrationEmbeddingClient({ embeddings: { model: { name: modelName } } }, this.resourceGroup ? { resourceGroup: this.resourceGroup } : undefined, destination);
|
|
36
72
|
}
|
|
37
73
|
}
|
|
38
74
|
//# sourceMappingURL=orchestration-embedder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestration-embedder.js","sourceRoot":"","sources":["../src/orchestration-embedder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"orchestration-embedder.js","sourceRoot":"","sources":["../src/orchestration-embedder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { IBearerCredential } from '@mcp-abap-adt/interfaces-auth';
|
|
1
2
|
import type { CallOptions, IEmbedderBatch, IEmbedResult } from '@mcp-abap-adt/llm-agent';
|
|
2
|
-
import { type FoundationModelsCredentials } from './foundation-embedder.js';
|
|
3
3
|
export type SapAiCoreEmbedderScenario = 'foundation-models' | 'orchestration';
|
|
4
4
|
export interface SapAiCoreEmbedderConfig {
|
|
5
5
|
/** Embedding model name (e.g. 'text-embedding-3-small', 'gemini-embedding') */
|
|
@@ -17,13 +17,17 @@ export interface SapAiCoreEmbedderConfig {
|
|
|
17
17
|
*/
|
|
18
18
|
scenario?: SapAiCoreEmbedderScenario;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* The bearer credential presented to SAP AI Core, for both scenarios.
|
|
21
|
+
* Resolved fresh per call by the backend — never cached here. Build one
|
|
22
|
+
* from a service key with `serviceKeyCredential` (`@mcp-abap-adt/sap-aicore-auth`).
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
credential: IBearerCredential;
|
|
25
|
+
/**
|
|
26
|
+
* SAP AI Core base URL (orchestration or REST inference, depending on
|
|
27
|
+
* `scenario`). Not part of the credential (§4.6.3).
|
|
28
|
+
*/
|
|
29
|
+
apiBaseUrl: string;
|
|
25
30
|
}
|
|
26
|
-
export type { FoundationModelsCredentials };
|
|
27
31
|
export declare class SapAiCoreEmbedder implements IEmbedderBatch {
|
|
28
32
|
private readonly backend;
|
|
29
33
|
constructor(config: SapAiCoreEmbedderConfig);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sap-ai-core-embedder.d.ts","sourceRoot":"","sources":["../src/sap-ai-core-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACb,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"sap-ai-core-embedder.d.ts","sourceRoot":"","sources":["../src/sap-ai-core-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACb,MAAM,yBAAyB,CAAC;AAIjC,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAE9E,MAAM,WAAW,uBAAuB;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC;;;;OAIG;IACH,UAAU,EAAE,iBAAiB,CAAC;IAC9B;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;gBAE7B,MAAM,EAAE,uBAAuB;IAmB3C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIjE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAG5E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FoundationModelsEmbedder
|
|
1
|
+
import { FoundationModelsEmbedder } from './foundation-embedder.js';
|
|
2
2
|
import { OrchestrationScenarioEmbedder } from './orchestration-embedder.js';
|
|
3
3
|
export class SapAiCoreEmbedder {
|
|
4
4
|
backend;
|
|
@@ -8,13 +8,16 @@ export class SapAiCoreEmbedder {
|
|
|
8
8
|
this.backend = new OrchestrationScenarioEmbedder({
|
|
9
9
|
model: config.model,
|
|
10
10
|
resourceGroup: config.resourceGroup,
|
|
11
|
+
credential: config.credential,
|
|
12
|
+
apiBaseUrl: config.apiBaseUrl,
|
|
11
13
|
});
|
|
12
14
|
}
|
|
13
15
|
else {
|
|
14
16
|
this.backend = new FoundationModelsEmbedder({
|
|
15
17
|
model: config.model,
|
|
16
18
|
resourceGroup: config.resourceGroup,
|
|
17
|
-
|
|
19
|
+
credential: config.credential,
|
|
20
|
+
apiBaseUrl: config.apiBaseUrl,
|
|
18
21
|
});
|
|
19
22
|
}
|
|
20
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sap-ai-core-embedder.js","sourceRoot":"","sources":["../src/sap-ai-core-embedder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sap-ai-core-embedder.js","sourceRoot":"","sources":["../src/sap-ai-core-embedder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAgC5E,MAAM,OAAO,iBAAiB;IACX,OAAO,CAAiB;IAEzC,YAAY,MAA+B;QACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,eAAe,CAAC;QACpD,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,GAAG,IAAI,6BAA6B,CAAC;gBAC/C,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,IAAI,wBAAwB,CAAC;gBAC1C,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAY,EAAE,OAAqB;QACvC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,UAAU,CAAC,KAAe,EAAE,OAAqB;QAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/sap-aicore-embedder",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "28.0.0",
|
|
4
4
|
"description": "SAP AI Core embedding provider (IEmbedder) for @mcp-abap-adt/llm-agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
"test": "node --import tsx/esm --test --test-reporter=spec 'src/**/*.test.ts'"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@sap-ai-sdk/orchestration": "^2.15.0"
|
|
27
|
+
"@sap-ai-sdk/orchestration": "^2.16.0"
|
|
29
28
|
},
|
|
30
29
|
"license": "LGPL-3.0-only",
|
|
31
30
|
"repository": {
|
|
@@ -34,5 +33,10 @@
|
|
|
34
33
|
},
|
|
35
34
|
"publishConfig": {
|
|
36
35
|
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@mcp-abap-adt/interfaces-auth": "^2.1.0",
|
|
39
|
+
"@mcp-abap-adt/llm-agent": "^28.0.0",
|
|
40
|
+
"@mcp-abap-adt/sap-aicore-auth": "^28.0.0"
|
|
37
41
|
}
|
|
38
42
|
}
|
package/dist/auth.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface TokenProviderConfig {
|
|
2
|
-
clientId: string;
|
|
3
|
-
clientSecret: string;
|
|
4
|
-
tokenUrl: string;
|
|
5
|
-
}
|
|
6
|
-
export interface GetTokenOptions {
|
|
7
|
-
/**
|
|
8
|
-
* Skip the local expiry cache. Note: if another `getToken()` call is already
|
|
9
|
-
* fetching a token, this flag coalesces into that in-flight request rather
|
|
10
|
-
* than starting a second one.
|
|
11
|
-
*/
|
|
12
|
-
forceRefresh?: boolean;
|
|
13
|
-
}
|
|
14
|
-
export declare class TokenProvider {
|
|
15
|
-
private readonly cfg;
|
|
16
|
-
private cachedToken;
|
|
17
|
-
private cachedExpiryMs;
|
|
18
|
-
private inFlight;
|
|
19
|
-
constructor(cfg: TokenProviderConfig);
|
|
20
|
-
getToken(options?: GetTokenOptions): Promise<string>;
|
|
21
|
-
private fetchToken;
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAKD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsB;IAC1C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAgC;gBAEpC,GAAG,EAAE,mBAAmB;IAI9B,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;YAwB5C,UAAU;CA+BzB"}
|
package/dist/auth.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/** Refresh the token when less than this many ms remain on it. */
|
|
2
|
-
const REFRESH_WINDOW_MS = 60_000;
|
|
3
|
-
export class TokenProvider {
|
|
4
|
-
cfg;
|
|
5
|
-
cachedToken = null;
|
|
6
|
-
cachedExpiryMs = 0;
|
|
7
|
-
inFlight = null;
|
|
8
|
-
constructor(cfg) {
|
|
9
|
-
this.cfg = cfg;
|
|
10
|
-
}
|
|
11
|
-
async getToken(options) {
|
|
12
|
-
if (!options?.forceRefresh &&
|
|
13
|
-
this.cachedToken &&
|
|
14
|
-
Date.now() < this.cachedExpiryMs - REFRESH_WINDOW_MS) {
|
|
15
|
-
return this.cachedToken;
|
|
16
|
-
}
|
|
17
|
-
// Dedupe concurrent callers, including those with forceRefresh (see GetTokenOptions).
|
|
18
|
-
if (this.inFlight)
|
|
19
|
-
return this.inFlight;
|
|
20
|
-
this.inFlight = this.fetchToken()
|
|
21
|
-
.then((result) => {
|
|
22
|
-
this.cachedToken = result.token;
|
|
23
|
-
this.cachedExpiryMs = Date.now() + result.expiresInMs;
|
|
24
|
-
return result.token;
|
|
25
|
-
})
|
|
26
|
-
.finally(() => {
|
|
27
|
-
this.inFlight = null;
|
|
28
|
-
});
|
|
29
|
-
return this.inFlight;
|
|
30
|
-
}
|
|
31
|
-
async fetchToken() {
|
|
32
|
-
const basic = Buffer.from(`${this.cfg.clientId}:${this.cfg.clientSecret}`).toString('base64');
|
|
33
|
-
const res = await fetch(this.cfg.tokenUrl, {
|
|
34
|
-
method: 'POST',
|
|
35
|
-
headers: {
|
|
36
|
-
Authorization: `Basic ${basic}`,
|
|
37
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
38
|
-
Accept: 'application/json',
|
|
39
|
-
},
|
|
40
|
-
body: 'grant_type=client_credentials',
|
|
41
|
-
});
|
|
42
|
-
if (!res.ok) {
|
|
43
|
-
const text = await res.text().catch(() => '');
|
|
44
|
-
throw new Error(`SAP AI Core token request failed: ${res.status} ${res.statusText} ${text}`);
|
|
45
|
-
}
|
|
46
|
-
const body = (await res.json());
|
|
47
|
-
if (!body.access_token) {
|
|
48
|
-
throw new Error('SAP AI Core token response missing access_token');
|
|
49
|
-
}
|
|
50
|
-
return {
|
|
51
|
-
token: body.access_token,
|
|
52
|
-
expiresInMs: (body.expires_in ?? 3600) * 1000,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAeA,kEAAkE;AAClE,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC,MAAM,OAAO,aAAa;IACP,GAAG,CAAsB;IAClC,WAAW,GAAkB,IAAI,CAAC;IAClC,cAAc,GAAG,CAAC,CAAC;IACnB,QAAQ,GAA2B,IAAI,CAAC;IAEhD,YAAY,GAAwB;QAClC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAyB;QACtC,IACE,CAAC,OAAO,EAAE,YAAY;YACtB,IAAI,CAAC,WAAW;YAChB,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,cAAc,GAAG,iBAAiB,EACpD,CAAC;YACD,OAAO,IAAI,CAAC,WAAW,CAAC;QAC1B,CAAC;QACD,sFAAsF;QACtF,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QAExC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE;aAC9B,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACf,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;YAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;YACtD,OAAO,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACvB,CAAC,CAAC,CAAC;QAEL,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CACvB,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAChD,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,SAAS,KAAK,EAAE;gBAC/B,cAAc,EAAE,mCAAmC;gBACnD,MAAM,EAAE,kBAAkB;aAC3B;YACD,IAAI,EAAE,+BAA+B;SACtC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,MAAM,IAAI,KAAK,CACb,qCAAqC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,IAAI,IAAI,EAAE,CAC5E,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QACD,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,YAAY;YACxB,WAAW,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,IAAI;SAC9C,CAAC;IACJ,CAAC;CACF"}
|
package/dist/service-key.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export interface ParsedServiceKey {
|
|
2
|
-
clientId: string;
|
|
3
|
-
clientSecret: string;
|
|
4
|
-
/** Fully qualified token endpoint incl. `/oauth/token`. */
|
|
5
|
-
tokenUrl: string;
|
|
6
|
-
/** AI Core REST API base URL (no trailing slash). */
|
|
7
|
-
apiBaseUrl: string;
|
|
8
|
-
}
|
|
9
|
-
export declare function parseServiceKey(raw: string): ParsedServiceKey;
|
|
10
|
-
//# sourceMappingURL=service-key.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service-key.d.ts","sourceRoot":"","sources":["../src/service-key.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;CACpB;AASD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAgC7D"}
|
package/dist/service-key.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export function parseServiceKey(raw) {
|
|
2
|
-
let obj;
|
|
3
|
-
try {
|
|
4
|
-
obj = JSON.parse(raw);
|
|
5
|
-
}
|
|
6
|
-
catch (err) {
|
|
7
|
-
throw new Error(`AICORE_SERVICE_KEY is not valid JSON: ${err.message}`);
|
|
8
|
-
}
|
|
9
|
-
const clientId = obj.clientid;
|
|
10
|
-
const clientSecret = obj.clientsecret;
|
|
11
|
-
const authUrl = obj.url;
|
|
12
|
-
const apiBaseUrl = obj.serviceurls?.AI_API_URL;
|
|
13
|
-
if (!clientId || !clientSecret || !authUrl || !apiBaseUrl) {
|
|
14
|
-
throw new Error('AICORE_SERVICE_KEY is missing required fields (clientid, clientsecret, url, serviceurls.AI_API_URL)');
|
|
15
|
-
}
|
|
16
|
-
const trimmedAuth = authUrl.replace(/\/+$/, '');
|
|
17
|
-
const tokenUrl = trimmedAuth.endsWith('/oauth/token')
|
|
18
|
-
? trimmedAuth
|
|
19
|
-
: `${trimmedAuth}/oauth/token`;
|
|
20
|
-
return {
|
|
21
|
-
clientId,
|
|
22
|
-
clientSecret,
|
|
23
|
-
tokenUrl,
|
|
24
|
-
apiBaseUrl: apiBaseUrl.replace(/\/+$/, ''),
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=service-key.js.map
|
package/dist/service-key.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service-key.js","sourceRoot":"","sources":["../src/service-key.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,GAAkB,CAAC;IACvB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,yCAA0C,GAAa,CAAC,OAAO,EAAE,CAClE,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC9B,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC;IACxB,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC;IAE/C,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,qGAAqG,CACtG,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC;QACnD,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,GAAG,WAAW,cAAc,CAAC;IAEjC,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,QAAQ;QACR,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC"}
|