88import com .fasterxml .jackson .databind .node .ObjectNode ;
99import com .google .common .annotations .Beta ;
1010import com .sap .ai .sdk .core .AiCoreService ;
11- import com .sap .ai .sdk .core .DeploymentResolutionException ;
12- import com .sap .ai .sdk .core .common .ClientResponseHandler ;
13- import com .sap .ai .sdk .core .common .ClientStreamingHandler ;
14- import com .sap .ai .sdk .core .common .StreamedDelta ;
1511import com .sap .ai .sdk .orchestration .model .CompletionPostRequest ;
1612import com .sap .ai .sdk .orchestration .model .CompletionPostResponseSynchronous ;
13+ import com .sap .ai .sdk .orchestration .model .EmbeddingsPostRequest ;
14+ import com .sap .ai .sdk .orchestration .model .EmbeddingsPostResponse ;
1715import com .sap .ai .sdk .orchestration .model .ModuleConfigs ;
1816import com .sap .ai .sdk .orchestration .model .OrchestrationConfig ;
19- import com .sap .cloud .sdk .cloudplatform .connectivity .ApacheHttpClient5Accessor ;
2017import com .sap .cloud .sdk .cloudplatform .connectivity .HttpDestination ;
21- import com .sap .cloud .sdk .cloudplatform .connectivity .exception .DestinationAccessException ;
22- import com .sap .cloud .sdk .cloudplatform .connectivity .exception .DestinationNotFoundException ;
23- import com .sap .cloud .sdk .cloudplatform .connectivity .exception .HttpClientInstantiationException ;
24- import java .io .IOException ;
2518import java .util .function .Supplier ;
2619import java .util .stream .Stream ;
2720import javax .annotation .Nonnull ;
2821import lombok .extern .slf4j .Slf4j ;
2922import lombok .val ;
30- import org .apache .hc .client5 .http .classic .methods .HttpPost ;
31- import org .apache .hc .core5 .http .ContentType ;
32- import org .apache .hc .core5 .http .io .entity .StringEntity ;
33- import org .apache .hc .core5 .http .message .BasicClassicHttpRequest ;
3423
3524/** Client to execute requests to the orchestration service. */
3625@ Slf4j
@@ -39,12 +28,13 @@ public class OrchestrationClient {
3928
4029 static final ObjectMapper JACKSON = getOrchestrationObjectMapper ();
4130
42- @ Nonnull private final Supplier < HttpDestination > destinationSupplier ;
31+ private final OrchestrationHttpExecutor executor ;
4332
4433 /** Default constructor. */
4534 public OrchestrationClient () {
46- destinationSupplier =
35+ final Supplier < HttpDestination > destinationSupplier =
4736 () -> new AiCoreService ().getInferenceDestination ().forScenario (DEFAULT_SCENARIO );
37+ this .executor = new OrchestrationHttpExecutor (destinationSupplier );
4838 }
4939
5040 /**
@@ -64,7 +54,7 @@ public OrchestrationClient() {
6454 */
6555 @ Beta
6656 public OrchestrationClient (@ Nonnull final HttpDestination destination ) {
67- this .destinationSupplier = ( ) -> destination ;
57+ this .executor = new OrchestrationHttpExecutor (( ) -> destination ) ;
6858 }
6959
7060 /**
@@ -150,15 +140,7 @@ private static void throwOnContentFilter(@Nonnull final OrchestrationChatComplet
150140 @ Nonnull
151141 public CompletionPostResponseSynchronous executeRequest (
152142 @ Nonnull final CompletionPostRequest request ) throws OrchestrationClientException {
153- final String jsonRequest ;
154- try {
155- jsonRequest = JACKSON .writeValueAsString (request );
156- log .debug ("Serialized request into JSON payload: {}" , jsonRequest );
157- } catch (final JsonProcessingException e ) {
158- throw new OrchestrationClientException ("Failed to serialize request parameters" , e );
159- }
160-
161- return executeRequest (jsonRequest );
143+ return executor .execute ("/completion" , request , CompletionPostResponseSynchronous .class );
162144 }
163145
164146 /**
@@ -199,38 +181,8 @@ public OrchestrationChatResponse executeRequestFromJsonModuleConfig(
199181 }
200182 requestJson .set ("orchestration_config" , moduleConfigJson );
201183
202- final String body ;
203- try {
204- body = JACKSON .writeValueAsString (requestJson );
205- } catch (JsonProcessingException e ) {
206- throw new OrchestrationClientException ("Failed to serialize request to JSON" , e );
207- }
208- return new OrchestrationChatResponse (executeRequest (body ));
209- }
210-
211- @ Nonnull
212- CompletionPostResponseSynchronous executeRequest (@ Nonnull final String request ) {
213- val postRequest = new HttpPost ("/completion" );
214- postRequest .setEntity (new StringEntity (request , ContentType .APPLICATION_JSON ));
215-
216- try {
217- val destination = destinationSupplier .get ();
218- log .debug ("Using destination {} to connect to orchestration service" , destination );
219- val client = ApacheHttpClient5Accessor .getHttpClient (destination );
220- val handler =
221- new ClientResponseHandler <>(
222- CompletionPostResponseSynchronous .class ,
223- OrchestrationError .class ,
224- OrchestrationClientException ::new )
225- .objectMapper (JACKSON );
226- return client .execute (postRequest , handler );
227- } catch (DeploymentResolutionException
228- | DestinationAccessException
229- | DestinationNotFoundException
230- | HttpClientInstantiationException
231- | IOException e ) {
232- throw new OrchestrationClientException ("Failed to execute request" , e );
233- }
184+ return new OrchestrationChatResponse (
185+ executor .execute ("/completion" , requestJson , CompletionPostResponseSynchronous .class ));
234186 }
235187
236188 /**
@@ -245,42 +197,20 @@ CompletionPostResponseSynchronous executeRequest(@Nonnull final String request)
245197 public Stream <OrchestrationChatCompletionDelta > streamChatCompletionDeltas (
246198 @ Nonnull final CompletionPostRequest request ) throws OrchestrationClientException {
247199 request .getOrchestrationConfig ().setStream (true );
248- return executeStream ("/completion" , request , OrchestrationChatCompletionDelta .class );
249- }
250-
251- @ Nonnull
252- private <D extends StreamedDelta > Stream <D > executeStream (
253- @ Nonnull final String path ,
254- @ Nonnull final Object payload ,
255- @ Nonnull final Class <D > deltaType ) {
256- final var request = new HttpPost (path );
257- serializeAndSetHttpEntity (request , payload );
258- return streamRequest (request , deltaType );
259- }
260-
261- private static void serializeAndSetHttpEntity (
262- @ Nonnull final BasicClassicHttpRequest request , @ Nonnull final Object payload ) {
263- try {
264- final var json = JACKSON .writeValueAsString (payload );
265- request .setEntity (new StringEntity (json , ContentType .APPLICATION_JSON ));
266- } catch (final JsonProcessingException e ) {
267- throw new OrchestrationClientException ("Failed to serialize request parameters" , e );
268- }
200+ return executor .stream (request );
269201 }
270202
203+ /**
204+ * Generate embeddings for the given request.
205+ *
206+ * @param request the request containing the input text and other parameters.
207+ * @return the response containing the embeddings.
208+ * @throws OrchestrationClientException if the request fails
209+ * @since 1.9.0
210+ */
271211 @ Nonnull
272- private <D extends StreamedDelta > Stream <D > streamRequest (
273- final BasicClassicHttpRequest request , @ Nonnull final Class <D > deltaType ) {
274- try {
275- val destination = destinationSupplier .get ();
276- log .debug ("Using destination {} to connect to orchestration service" , destination );
277- val client = ApacheHttpClient5Accessor .getHttpClient (destination );
278- return new ClientStreamingHandler <>(
279- deltaType , OrchestrationError .class , OrchestrationClientException ::new )
280- .objectMapper (JACKSON )
281- .handleStreamingResponse (client .executeOpen (null , request , null ));
282- } catch (final IOException e ) {
283- throw new OrchestrationClientException ("Request to the Orchestration service failed" , e );
284- }
212+ public EmbeddingsPostResponse embed (@ Nonnull final EmbeddingsPostRequest request )
213+ throws OrchestrationClientException {
214+ return executor .execute ("/v2/embeddings" , request , EmbeddingsPostResponse .class );
285215 }
286216}
0 commit comments