@adobe/spacecat-shared-gpt-client 1.4.6 → 1.5.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/CHANGELOG.md +14 -0
- package/README.md +79 -6
- package/package.json +2 -2
- package/src/clients/genvar-client.js +182 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-gpt-client-v1.5.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-gpt-client-v1.4.7...@adobe/spacecat-shared-gpt-client-v1.5.0) (2025-02-17)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add Client to interact with Genvar APIs ([#596](https://github.com/adobe/spacecat-shared/issues/596)) ([cd69beb](https://github.com/adobe/spacecat-shared/commit/cd69beb153b543c59f70ea702c0d0c72c458515d))
|
|
7
|
+
|
|
8
|
+
# [@adobe/spacecat-shared-gpt-client-v1.4.7](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-gpt-client-v1.4.6...@adobe/spacecat-shared-gpt-client-v1.4.7) (2025-02-16)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **deps:** update external fixes ([#603](https://github.com/adobe/spacecat-shared/issues/603)) ([b58d4c7](https://github.com/adobe/spacecat-shared/commit/b58d4c7237fb2522bba9b722e9eed7b0ae9e5f70))
|
|
14
|
+
|
|
1
15
|
# [@adobe/spacecat-shared-gpt-client-v1.4.6](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-gpt-client-v1.4.5...@adobe/spacecat-shared-gpt-client-v1.4.6) (2025-02-08)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Spacecat Shared - GPT Client
|
|
2
2
|
|
|
3
|
+
## Firefall
|
|
3
4
|
The `FirefallClient` library offers a streamlined way to interact with the Firefall API, enabling applications to fetch insights, recommendations, and codes based on provided prompts. Designed with simplicity and efficiency in mind, this client handles all aspects of communication with the Firefall API, including request authentication, error handling, and response parsing.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
### Configuration
|
|
6
7
|
|
|
7
8
|
To use the `FirefallClient`, you need to configure it with the following parameters:
|
|
8
9
|
|
|
@@ -24,9 +25,9 @@ Additionally, the configuration for the `@adobe/spacecat-shared-ims-client` libr
|
|
|
24
25
|
- `IMS_CLIENT_CODE`: Your IMS client code, used for authentication.
|
|
25
26
|
- `IMS_CLIENT_SECRET`: Your IMS client secret, used for authentication.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
### Usage Examples
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
#### Instantiating the Firefall Client
|
|
30
31
|
|
|
31
32
|
```javascript
|
|
32
33
|
import FirefallClient from 'path/to/firefall-client';
|
|
@@ -45,9 +46,9 @@ try {
|
|
|
45
46
|
}
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
#### Fetching Insights
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
1. Via Capability Execution endpoint
|
|
51
52
|
|
|
52
53
|
```javascript
|
|
53
54
|
/**
|
|
@@ -78,7 +79,7 @@ async function fetchInsights(prompt) {
|
|
|
78
79
|
fetchInsights('How can we improve customer satisfaction?');
|
|
79
80
|
```
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
2. Via Chat Completions endpoint
|
|
82
83
|
|
|
83
84
|
```javascript
|
|
84
85
|
/**
|
|
@@ -115,6 +116,78 @@ fetchCompletions('Identify all food items in this image', { imageUrls: ['data:im
|
|
|
115
116
|
|
|
116
117
|
Ensure that you replace `'path/to/firefall-client'` with the actual path to the `FirefallClient` class in your project and adjust the configuration parameters according to your Firefall API credentials.
|
|
117
118
|
|
|
119
|
+
## Genvar Client
|
|
120
|
+
|
|
121
|
+
The `Genvar client` library provides a convenient way to interact with the Genvar APIs.
|
|
122
|
+
|
|
123
|
+
### Configuration
|
|
124
|
+
To use the `GenvarClient`, you need to configure it with the following parameters:
|
|
125
|
+
|
|
126
|
+
- `GENVAR_HOST`: The hostname for Genvar API.
|
|
127
|
+
- `GENVAR_IMS_ORG_ID`: The IMS ORG ID to use when calling the Genvar APIs and tracking the request.
|
|
128
|
+
|
|
129
|
+
These parameters can be set through environment variables or passed directly to the `GenvarClient.createFrom` method.
|
|
130
|
+
|
|
131
|
+
Additionally, the configuration for the `@adobe/spacecat-shared-ims-client` library is required to fetch the service access token from the IMS API:
|
|
132
|
+
|
|
133
|
+
- `IMS_HOST`: The hostname of the IMS API.
|
|
134
|
+
- `IMS_CLIENT_ID`: Your IMS client ID.
|
|
135
|
+
- `IMS_CLIENT_CODE`: Your IMS client code, used for authentication.
|
|
136
|
+
- `IMS_CLIENT_SECRET`: Your IMS client secret, used for authentication.
|
|
137
|
+
|
|
138
|
+
### Usage Examples
|
|
139
|
+
|
|
140
|
+
#### Instantiating the Genvar Client
|
|
141
|
+
```javascript
|
|
142
|
+
import GenvarClient from 'path/to/genvar-client';
|
|
143
|
+
|
|
144
|
+
// Assuming environment variables are set
|
|
145
|
+
const context = {
|
|
146
|
+
env: process.env,
|
|
147
|
+
log: console, // Using console for logging in this example
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const client = GenvarClient.createFrom(context);
|
|
152
|
+
console.log('GenvarClient created successfully.');
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error('Error creating GenvarClient:', error.message);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### Calling Genvar API
|
|
159
|
+
|
|
160
|
+
- Using `generateSuggestions` method which first submits the job and then polls the job status
|
|
161
|
+
```javascript
|
|
162
|
+
/**
|
|
163
|
+
* Call Genvar API with generate suggestions method
|
|
164
|
+
*/
|
|
165
|
+
async function generateAISuggestions() {
|
|
166
|
+
try {
|
|
167
|
+
const client = GenvarClient.createFrom({
|
|
168
|
+
env: {
|
|
169
|
+
GENVAR_HOST: 'https://12345-genvarapi-seotest.adobeioruntime.net',
|
|
170
|
+
GENVAR_IMS_ORG_ID: 'abcd@AdobeOrg',
|
|
171
|
+
IMS_HOST: 'ims.example.com',
|
|
172
|
+
IMS_CLIENT_ID: 'yourClientId',
|
|
173
|
+
IMS_CLIENT_CODE: 'yourClientCode',
|
|
174
|
+
IMS_CLIENT_SECRET: 'yourClientSecret',
|
|
175
|
+
},
|
|
176
|
+
log: console,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const requestBody = {
|
|
180
|
+
param1: 'some-value',
|
|
181
|
+
};
|
|
182
|
+
const endpoint = '/some-endpoint';
|
|
183
|
+
const response = await client.generateSuggestions(requestBody, endpoint);
|
|
184
|
+
console.log('Genvar API response:', response);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.error('Failed to call genvar API:', error.message);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
118
191
|
## Testing
|
|
119
192
|
|
|
120
193
|
To run tests:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/spacecat-shared-gpt-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Shared modules of the Spacecat Services - GPT Client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@adobe/spacecat-shared-utils": "1.26.4"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"chai": "5.
|
|
43
|
+
"chai": "5.2.0",
|
|
44
44
|
"chai-as-promised": "8.0.1",
|
|
45
45
|
"nock": "14.0.1",
|
|
46
46
|
"sinon": "19.0.2",
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { createUrl } from '@adobe/fetch';
|
|
14
|
+
import { ImsClient } from '@adobe/spacecat-shared-ims-client';
|
|
15
|
+
import {
|
|
16
|
+
hasText, isNonEmptyObject,
|
|
17
|
+
isValidUrl,
|
|
18
|
+
tracingFetch,
|
|
19
|
+
} from '@adobe/spacecat-shared-utils';
|
|
20
|
+
|
|
21
|
+
export default class GenvarClient {
|
|
22
|
+
static createFrom(context) {
|
|
23
|
+
const { log = console } = context;
|
|
24
|
+
const imsClient = ImsClient.createFrom(context);
|
|
25
|
+
const {
|
|
26
|
+
GENVAR_HOST: genvarHost,
|
|
27
|
+
GENVAR_IMS_ORG_ID: genvarImsOrgId,
|
|
28
|
+
GENVAR_API_POLL_INTERVAL: pollInterval = 3000,
|
|
29
|
+
} = context.env;
|
|
30
|
+
|
|
31
|
+
if (!isValidUrl(genvarHost)) {
|
|
32
|
+
throw new Error('Missing Genvar API endpoint');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!hasText(genvarImsOrgId)) {
|
|
36
|
+
throw new Error('Missing Genvar Ims org');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return new GenvarClient({
|
|
40
|
+
genvarHost,
|
|
41
|
+
imsClient,
|
|
42
|
+
imsOrg: genvarImsOrgId,
|
|
43
|
+
pollInterval,
|
|
44
|
+
}, log);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new Genvar client
|
|
49
|
+
*
|
|
50
|
+
* @param {Object} config - The configuration object.
|
|
51
|
+
* @param {string} config.apiEndpoint - The API endpoint for Genvar.
|
|
52
|
+
* @param {ImsClient} config.imsClient - The IMS Client.
|
|
53
|
+
* @param {string} config.imsOrg - The IMS Org for Genvar.
|
|
54
|
+
* @param {number} config.pollInterval - The interval to poll for job status.
|
|
55
|
+
* @param {Object} log - The Logger.
|
|
56
|
+
* @returns {GenvarClient} - the Genvar client.
|
|
57
|
+
*/
|
|
58
|
+
constructor(config, log) {
|
|
59
|
+
this.config = config;
|
|
60
|
+
this.log = log;
|
|
61
|
+
this.imsClient = config.imsClient;
|
|
62
|
+
this.apiAuth = null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async #getApiAuth() {
|
|
66
|
+
if (!this.apiAuth) {
|
|
67
|
+
this.apiAuth = (await this.imsClient.getServiceAccessToken()).access_token;
|
|
68
|
+
}
|
|
69
|
+
return this.apiAuth;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
#logDuration(message, startTime) {
|
|
73
|
+
const endTime = process.hrtime.bigint();
|
|
74
|
+
const duration = (endTime - startTime) / BigInt(1e6);
|
|
75
|
+
this.log.debug(`${message}: took ${duration}ms`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async #submitJob(body, path) {
|
|
79
|
+
const apiAuth = await this.#getApiAuth();
|
|
80
|
+
const url = createUrl(`${this.config.genvarHost}${path}`);
|
|
81
|
+
const headers = {
|
|
82
|
+
'Content-Type': 'application/json',
|
|
83
|
+
Authorization: `Bearer ${apiAuth}`,
|
|
84
|
+
'x-gw-ims-org-id': this.config.imsOrg,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
this.log.info(`[Genvar API Call] URL: ${url}, Headers: ${JSON.stringify({ ...headers, Authorization: '***' })}`);
|
|
88
|
+
|
|
89
|
+
let response;
|
|
90
|
+
let responseJsonObj;
|
|
91
|
+
try {
|
|
92
|
+
response = await tracingFetch(url, {
|
|
93
|
+
method: 'POST',
|
|
94
|
+
headers,
|
|
95
|
+
body,
|
|
96
|
+
});
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
const errorMessage = await response.text();
|
|
99
|
+
throw new Error(`Job submission failed with status code ${response.status} and error: ${errorMessage}`);
|
|
100
|
+
}
|
|
101
|
+
responseJsonObj = await response.json();
|
|
102
|
+
} catch (err) {
|
|
103
|
+
this.log.error(`Genvar Job submit failed with error: ${err.message}`);
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
return responseJsonObj;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* eslint-disable no-await-in-loop */
|
|
110
|
+
async #pollJobStatus(jobId, path) {
|
|
111
|
+
const apiAuth = await this.#getApiAuth();
|
|
112
|
+
let jobStatusResponse;
|
|
113
|
+
do {
|
|
114
|
+
await new Promise(
|
|
115
|
+
(resolve) => { setTimeout(resolve, this.config.pollInterval); },
|
|
116
|
+
); // Wait for 3 seconds(default) before polling
|
|
117
|
+
|
|
118
|
+
const url = `${this.config.genvarHost}${path}?jobId=${jobId}`;
|
|
119
|
+
const headers = {
|
|
120
|
+
Authorization: `Bearer ${apiAuth}`,
|
|
121
|
+
'x-gw-ims-org-id': this.config.imsOrg,
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
this.log.info(`[Genvar API Call] URL: ${url}, Headers: ${JSON.stringify({ ...headers, Authorization: '***' })}`);
|
|
125
|
+
|
|
126
|
+
let response;
|
|
127
|
+
try {
|
|
128
|
+
response = await tracingFetch(
|
|
129
|
+
createUrl(url),
|
|
130
|
+
{
|
|
131
|
+
method: 'GET',
|
|
132
|
+
headers,
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
throw new Error(`Job polling failed with status code ${response.status}`);
|
|
137
|
+
}
|
|
138
|
+
jobStatusResponse = await response.json();
|
|
139
|
+
} catch (err) {
|
|
140
|
+
this.log.error(`Genvar Job poll failed with error: ${err.message}`);
|
|
141
|
+
throw err;
|
|
142
|
+
}
|
|
143
|
+
} while (jobStatusResponse.status === 'running');
|
|
144
|
+
|
|
145
|
+
if (jobStatusResponse.status !== 'completed') {
|
|
146
|
+
throw new Error(`Job did not succeed, status: ${jobStatusResponse.status}.\n${JSON.stringify(jobStatusResponse, null, 2)}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return jobStatusResponse;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Fetches data from Genvar API. Follows the flow: submit job and polls job status
|
|
154
|
+
* @param body The request body to provide to Genvar
|
|
155
|
+
* @param path The Genvar request path
|
|
156
|
+
* @returns {string} - API Response
|
|
157
|
+
*/
|
|
158
|
+
async generateSuggestions(body, path) {
|
|
159
|
+
if (!body) {
|
|
160
|
+
throw new Error('Invalid body received');
|
|
161
|
+
}
|
|
162
|
+
if (!path) {
|
|
163
|
+
throw new Error('Invalid path received');
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const startTime = process.hrtime.bigint();
|
|
167
|
+
|
|
168
|
+
const jobSubmissionResponse = await this.#submitJob(body, path);
|
|
169
|
+
const jobStatusResponse = await this.#pollJobStatus(jobSubmissionResponse.jobId, path);
|
|
170
|
+
this.#logDuration('Genvar API Execution call took ms: ', startTime);
|
|
171
|
+
|
|
172
|
+
const { result } = jobStatusResponse;
|
|
173
|
+
if (!isNonEmptyObject(result)) {
|
|
174
|
+
throw new Error('Job completed but no output was found');
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
} catch (error) {
|
|
178
|
+
this.log.error('Error while calling Genvar API: ', error.message);
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
package/src/index.d.ts
CHANGED