Skip to content

Commit 846d2c4

Browse files
committed
feat: Support compressed requests in the RPT client
1 parent 4aef0b1 commit 846d2c4

File tree

12 files changed

+393
-15
lines changed

12 files changed

+393
-15
lines changed

.changeset/new-tigers-guess.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sap-ai-sdk/rpt': minor
3+
---
4+
5+
[feat] Add generic HTTP request configuration support.
6+
The `predictWithSchema()` and `predictWithoutSchema()` methods now accept an optional `customRequest` parameter of type `RptRequestOptions`, allowing configuration of custom HTTP request options such as headers, timeout, and middlewares.

.changeset/true-dolls-say.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@sap-ai-sdk/rpt': minor
3+
---
4+
5+
[feat] Add predict request compression support.
6+
All requests with a body of 1024 bytes or larger will be automatically compressed with `gzip` by default, unless configured otherwise.
7+
Compression configuration is available via the `requestCompression` property on the `RptClientConfig` object.
8+
Supported compression algorithms include `gzip`, `brotli`, `deflate`, and `zstd` (requires Node.js v22.15.0+).

packages/rpt/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"@sap-ai-sdk/ai-api": "workspace:^",
4141
"@sap-ai-sdk/core": "workspace:^",
4242
"@sap-cloud-sdk/connectivity": "^4.4.0",
43+
"@sap-cloud-sdk/http-client": "^4.4.0",
4344
"@sap-cloud-sdk/util": "^4.4.0"
4445
}
4546
}

packages/rpt/src/client.ts

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import {
22
getFoundationModelDeploymentId,
33
getResourceGroup
44
} from '@sap-ai-sdk/ai-api/internal.js';
5-
import { RptApi } from './internal.js';
6-
import { type DataSchema, type PredictionData } from './types.js';
5+
import { createLogger } from '@sap-cloud-sdk/util';
6+
import { executeRequest } from '@sap-ai-sdk/core';
7+
import { compressRequest } from './vendor/index.js';
8+
import type { DataSchema, PredictionData, RptRequestOptions } from './types.js';
79
import type {
810
PredictRequestPayload,
911
PredictResponsePayload
@@ -12,6 +14,11 @@ import type { SapRptModel } from '@sap-ai-sdk/core/internal.js';
1214
import type { ModelDeployment } from '@sap-ai-sdk/ai-api';
1315
import type { HttpDestinationOrFetchOptions } from '@sap-cloud-sdk/connectivity';
1416

17+
const logger = createLogger({
18+
package: 'rpt',
19+
messageContext: 'RptClient'
20+
});
21+
1522
/**
1623
* Representation of an RPT client to make predictions.
1724
* @experimental This class is experimental and may change at any time without prior notice.
@@ -32,36 +39,42 @@ export class RptClient {
3239
* Prefer using this method when the data schema is known.
3340
* @param dataSchema - Prediction data follows this schema. When using TypeScript, the data schema type is used to infer the types of the prediction data. In that case, the data schema must be provided as a constant (`as const`).
3441
* @param predictionData - Data to base prediction on.
42+
* @param customRequest - Custom request options.
3543
* @returns Prediction response.
3644
*/
3745
async predictWithSchema<const T extends DataSchema>(
3846
dataSchema: T,
39-
predictionData: PredictionData<T>
47+
predictionData: PredictionData<T>,
48+
customRequest: RptRequestOptions = {}
4049
): Promise<PredictResponsePayload> {
41-
return this.executePrediction(predictionData, dataSchema);
50+
return this.executePrediction(predictionData, dataSchema, customRequest);
4251
}
4352

4453
/**
4554
* Predict based on prediction data with data schema inferred.
4655
* Prefer using `predictWithSchema` when the data schema is known.
4756
* @param predictionData - Data to base prediction on.
57+
* @param customRequest - Custom request options.
4858
* @returns Prediction response.
4959
*/
5060
async predictWithoutSchema(
51-
predictionData: PredictionData<DataSchema>
61+
predictionData: PredictionData<DataSchema>,
62+
customRequest: RptRequestOptions = {}
5263
): Promise<PredictResponsePayload> {
53-
return this.executePrediction(predictionData);
64+
return this.executePrediction(predictionData, undefined, customRequest);
5465
}
5566

5667
/**
5768
* Predict based on data schema and prediction data.
5869
* @param predictionData - Data to base prediction on.
5970
* @param dataSchema - Prediction data follows this schema.
71+
* @param customRequestAll - Custom request options.
6072
* @returns Prediction response.
6173
*/
6274
private async executePrediction<const T extends DataSchema>(
6375
predictionData: PredictionData<T>,
64-
dataSchema?: T
76+
dataSchema?: T,
77+
customRequestAll: RptRequestOptions = {}
6578
): Promise<PredictResponsePayload> {
6679
const deploymentId = await getFoundationModelDeploymentId(
6780
this.modelDeployment,
@@ -83,9 +96,32 @@ export class RptClient {
8396
...predictionData
8497
} satisfies PredictRequestPayload;
8598

86-
return RptApi.predict(body)
87-
.setBasePath(`/inference/deployments/${deploymentId}`)
88-
.addCustomHeaders({ 'ai-resource-group': resourceGroup || 'default' })
89-
.execute(this.destination);
99+
const { requestCompression, ...customRequest } = customRequestAll;
100+
101+
if (requestCompression?.mode !== false) {
102+
if (customRequest.middlewares) {
103+
logger.warn(
104+
'Custom middlewares are not supported when request compression is enabled. ' +
105+
'The compression middleware will not be applied. ' +
106+
'Please disable request compression in RptRequestOptions to avoid this warning (`requestCompression.mode = false`).'
107+
);
108+
}
109+
customRequest.middlewares = [compressRequest(requestCompression)];
110+
}
111+
112+
const response = await executeRequest(
113+
{
114+
url: `/inference/deployments/${deploymentId}/predict`,
115+
resourceGroup: resourceGroup || 'default'
116+
},
117+
body,
118+
customRequest,
119+
this.destination
120+
);
121+
122+
if (response.data) {
123+
return response.data;
124+
}
125+
throw new Error('No data received from RPT prediction request');
90126
}
91127
}

packages/rpt/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
export * from './client.js';
2-
export type { PredictionData, DateString } from './types.js';
2+
export type { PredictionData, DateString, RptRequestOptions } from './types.js';
33
export type {
44
PredictResponseMetadata,
55
PredictResponsePayload,
66
PredictResponseStatus
77
} from './client/rpt/schema/index.js';
8+
export type {
9+
RequestCompressionMiddlewareOptions,
10+
RequestCompressionAlgorithm
11+
} from './vendor/index.js';

packages/rpt/src/types.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import type { Xor } from '@sap-cloud-sdk/util';
22
import type { ColumnType, SchemaFieldConfig } from './client/rpt/index.js';
3+
import type { CustomRequestConfig } from '@sap-cloud-sdk/http-client';
4+
import type {
5+
RequestCompressionMiddlewareOptions,
6+
RequestCompressionAlgorithm
7+
} from './vendor/index.js';
8+
9+
export type {
10+
RequestCompressionMiddlewareOptions,
11+
RequestCompressionAlgorithm
12+
} from './vendor/index.js';
313

414
/**
515
* Represents a string literal type that includes all column names from the data schema.
@@ -121,3 +131,19 @@ export type PredictionData<T extends DataSchema> = {
121131
columns: ColType<T>;
122132
}
123133
>;
134+
135+
/**
136+
* Custom options for how requests are made to the RPT service endpoint are performed.
137+
* @template C - The compression algorithm type.
138+
*/
139+
export interface RptRequestOptions<
140+
C extends RequestCompressionAlgorithm = RequestCompressionAlgorithm
141+
> extends CustomRequestConfig {
142+
/**
143+
* Options to configure request compression.
144+
* @remarks This option does not affect responses, only requests.
145+
* Prediction requests with parquet will not be compressed even if the option is set, as they are already in a compressed binary format.
146+
* Compression will be disabled if custom middlewares are provided in the destination or fetch options.
147+
*/
148+
requestCompression?: RequestCompressionMiddlewareOptions<C>;
149+
}

0 commit comments

Comments
 (0)