1+ function [text , message , response ] = callOpenAIChatAPI(messages , functions , nvp )
2+ % This function is undocumented and will change in a future release
3+
4+ % callOpenAIChatAPI Calls the openAI chat completions API.
5+ %
6+ % MESSAGES and FUNCTIONS should be structs matching the json format
7+ % required by the OpenAI Chat Completions API.
8+ % Ref: https://platform.openai.com/docs/guides/gpt/chat-completions-api
9+ %
10+ % Currently, the supported NVP are, including the equivalent name in the API:
11+ % - FunctionCall (function_call)
12+ % - ModelName (model)
13+ % - Temperature (temperature)
14+ % - TopProbabilityMass (top_p)
15+ % - NumCompletions (n)
16+ % - StopSequences (stop)
17+ % - MaxNumTokens (max_tokens)
18+ % - PresencePenalty (presence_penalty)
19+ % - FrequencyPenalty (frequence_penalty)
20+ % - ApiKey
21+ % More details on the parameters: https://platform.openai.com/docs/api-reference/chat/create
22+ %
23+ % Example
24+ %
25+ % % Create messages struct
26+ % messages = {struct("role", "system",...
27+ % "content", "You are a helpful assistant");
28+ % struct("role", "user", ...
29+ % "content", "What is the edit distance between hi and hello?")};
30+ %
31+ % % Create functions struct
32+ % functions = {struct("name", "editDistance", ...
33+ % "description", "Find edit distance between two strings or documents.", ...
34+ % "parameters", struct( ...
35+ % "type", "object", ...
36+ % "properties", struct(...
37+ % "str1", struct(...
38+ % "description", "Source string.", ...
39+ % "type", "string"),...
40+ % "str2", struct(...
41+ % "description", "Target string.", ...
42+ % "type", "string")),...
43+ % "required", ["str1", "str2"]))};
44+ %
45+ % % Define your API key
46+ % apiKey = "your-api-key-here"
47+ %
48+ % % Send a request
49+ % [text, message] = llms.internal.callOpenAIChatAPI(messages, functions, ApiKey=apiKey)
50+
51+ % Copyright 2023 The MathWorks, Inc.
52+
53+ arguments
54+ messages
55+ functions
56+ nvp.FunctionCall = []
57+ nvp.ModelName = " gpt-3.5-turbo"
58+ nvp.Temperature = 1
59+ nvp.TopProbabilityMass = 1
60+ nvp.NumCompletions = 1
61+ nvp.StopSequences = []
62+ nvp.MaxNumTokens = inf
63+ nvp.PresencePenalty = 0
64+ nvp.FrequencyPenalty = 0
65+ nvp.ApiKey = " "
66+ end
67+
68+ END_POINT = " https://api.openai.com/v1/chat/completions" ;
69+
70+ parameters = buildParametersCall(messages , functions , nvp );
71+
72+ response = llms .internal .sendRequest(parameters ,nvp .ApiKey , END_POINT );
73+
74+ % If call errors, "choices" will not be part of response.Body.Data, instead
75+ % we get response.Body.Data.error
76+ if response .StatusCode ==" OK"
77+ % Outputs the first generation
78+ message = response .Body .Data .choices(1 ).message;
79+ if isfield(message , " function_call" )
80+ text = " " ;
81+ else
82+ text = string(message .content );
83+ end
84+ else
85+ text = " " ;
86+ message = struct();
87+ end
88+ end
89+
90+ function parameters = buildParametersCall(messages , functions , nvp )
91+ % Builds a struct in the format that is expected by the API, combining
92+ % MESSAGES, FUNCTIONS and parameters in NVP.
93+
94+ parameters = struct();
95+ parameters.messages = messages ;
96+ if ~isempty(functions )
97+ parameters.functions = functions ;
98+ end
99+
100+ if ~isempty(nvp .FunctionCall )
101+ parameters.function_call = nvp .FunctionCall ;
102+ end
103+
104+ parameters.model = nvp .ModelName ;
105+
106+ dict = mapNVPToParameters ;
107+
108+ nvpOptions = keys(dict );
109+ for i= 1 : length(nvpOptions )
110+ if isfield(nvp , nvpOptions(i ))
111+ parameters.(dict(nvpOptions(i ))) = nvp.(nvpOptions(i ));
112+ end
113+ end
114+ end
115+
116+ function dict = mapNVPToParameters()
117+ dict = dictionary();
118+ dict(" Temperature" ) = " temperature" ;
119+ dict(" TopProbabilityMass" ) = " top_p" ;
120+ dict(" NumCompletions" ) = " n" ;
121+ dict(" StopSequences" ) = " stop" ;
122+ dict(" MaxNumTokens" ) = " max_tokens" ;
123+ dict(" PresencePenalty" ) = " presence_penalty" ;
124+ dict(" FrequencyPenalty " ) = " frequency_penalty" ;
125+ end
0 commit comments