1
1
package com .genexus .util .saia ;
2
2
3
3
import com .fasterxml .jackson .databind .ObjectMapper ;
4
+ import com .genexus .GXProcedure ;
4
5
import com .genexus .SdtMessages_Message ;
5
6
import com .genexus .common .interfaces .SpecificImplementation ;
6
7
import com .genexus .diagnostics .core .ILogger ;
7
8
import com .genexus .diagnostics .core .LogManager ;
8
9
import com .genexus .internet .HttpClient ;
10
+ import com .genexus .util .ChatResult ;
11
+ import com .genexus .util .GXProperties ;
9
12
import org .json .JSONObject ;
10
13
import com .genexus .util .CallResult ;
11
14
import org .slf4j .Logger ;
12
15
import org .slf4j .LoggerFactory ;
13
16
17
+ import java .util .ArrayList ;
18
+
14
19
public class SaiaService {
15
20
private static final ILogger logger = LogManager .getLogger (SaiaService .class );
16
21
private static final String apiKey = (String ) SpecificImplementation .Application .getProperty ("AI_PROVIDER_API_KEY" , "" );;
17
22
private static final String aiProvider = (String ) SpecificImplementation .Application .getProperty ("AI_PROVIDER" , "" );
18
23
private static final Logger log = LoggerFactory .getLogger (SaiaService .class );
19
24
20
- public static OpenAIResponse call (OpenAIRequest request , HttpClient client , CallResult result ) {
21
- return call (request , false , client , result );
25
+ public static OpenAIResponse call (GXProcedure proc , OpenAIRequest request , HttpClient client , String agent , boolean stream , GXProperties properties , ArrayList < OpenAIResponse . Message > messages , CallResult result , ChatResult chatResult ) {
26
+ return call (proc , request , false , client , agent , stream , properties , messages , result , chatResult );
22
27
}
23
28
24
29
public static OpenAIResponse call (OpenAIRequest request , boolean isEmbedding , CallResult result ) {
25
- return call (request , isEmbedding , new HttpClient (), result );
30
+ return call (null , request , isEmbedding , new HttpClient (), null , false , null , null , result , null );
26
31
}
27
32
28
- public static OpenAIResponse call (OpenAIRequest request , boolean isEmbedding , HttpClient client , CallResult result ) {
33
+ public static OpenAIResponse call (GXProcedure proc , OpenAIRequest request , boolean isEmbedding , HttpClient client , String agent , boolean stream , GXProperties properties , ArrayList < OpenAIResponse . Message > messages , CallResult result , ChatResult chatResult ) {
29
34
try {
30
35
String jsonRequest = new ObjectMapper ().writeValueAsString (request );
31
36
logger .debug ("Agent payload: " + jsonRequest );
@@ -44,25 +49,8 @@ public static OpenAIResponse call(OpenAIRequest request, boolean isEmbedding, Ht
44
49
if (client .getStatusCode () == 200 ) {
45
50
String saiaResponse ;
46
51
if (client .getHeader ("Content-Type" ).contains ("text/event-stream" )){
47
- saiaResponse = client .readChunk ();
48
- int index = saiaResponse .indexOf ("data:" ) + "data:" .length ();
49
- String chunkJson = saiaResponse .substring (index ).trim ();
50
- try {
51
- JSONObject jsonResponse = new JSONObject (chunkJson );
52
- OpenAIResponse chunkResponse = new ObjectMapper ().readValue (jsonResponse .toString (), OpenAIResponse .class );
53
- OpenAIResponse .Choice choise = chunkResponse .getChoices ().get (0 );
54
- if (choise .getFinishReason () != null && choise .getFinishReason ().equals ("tool_calls" )){
55
- saiaResponse = chunkJson ;
56
- }
57
- else {
58
- client .unreadChunk ();
59
- return null ;
60
- }
61
- }
62
- catch (Exception e ) {
63
- client .unreadChunk ();
64
- return null ;
65
- }
52
+ getChunkedSaiaResponse (proc , client , agent , stream , properties , messages , result , chatResult );
53
+ return null ;
66
54
}
67
55
else {
68
56
saiaResponse = client .getString ();
@@ -88,6 +76,38 @@ public static OpenAIResponse call(OpenAIRequest request, boolean isEmbedding, Ht
88
76
return null ;
89
77
}
90
78
79
+ private static void getChunkedSaiaResponse (GXProcedure proc , HttpClient client , String agent , boolean stream , GXProperties properties , ArrayList <OpenAIResponse .Message > messages , CallResult result , ChatResult chatResult ) {
80
+ String saiaChunkResponse = client .readChunk ();;
81
+ String chunkJson ;
82
+ while (!client .getEof ()) {
83
+ logger .debug ("Agent response chunk: " + saiaChunkResponse );
84
+ if (saiaChunkResponse .isEmpty () || saiaChunkResponse .equals ("data: [DONE]" )) {
85
+ saiaChunkResponse = client .readChunk ();
86
+ continue ;
87
+ }
88
+ int index = saiaChunkResponse .indexOf ("data:" ) + "data:" .length ();
89
+ chunkJson = saiaChunkResponse .substring (index ).trim ();
90
+ try {
91
+ JSONObject jsonResponse = new JSONObject (chunkJson );
92
+ OpenAIResponse chunkResponse = new ObjectMapper ().readValue (jsonResponse .toString (), OpenAIResponse .class );
93
+ if (!chunkResponse .getChoices ().isEmpty ()) {
94
+ OpenAIResponse .Choice choice = chunkResponse .getChoices ().get (0 );
95
+ if (choice .getFinishReason () != null && choice .getFinishReason ().equals ("tool_calls" )) {
96
+ messages .add (choice .getMessage ());
97
+ proc .processNotChunkedResponse (agent , stream , properties , messages , result , chatResult , choice .getMessage ().getToolCalls ());
98
+ ;
99
+ } else if (choice .getDelta () != null && choice .getDelta ().getContent () != null ) {
100
+ chatResult .addChunk (((OpenAIResponse .StringContent ) choice .getDelta ().getContent ()).getValue ());
101
+ }
102
+ }
103
+ saiaChunkResponse = client .readChunk ();
104
+ }
105
+ catch (Exception e ) {
106
+ logger .warn ("Error deserializing the response chunk" , e );
107
+ saiaChunkResponse = client .readChunk ();
108
+ }
109
+ }
110
+ }
91
111
92
112
private static void addResultMessage (String id , byte type , String description , CallResult result ){
93
113
if (type == 1 )
0 commit comments