-
Notifications
You must be signed in to change notification settings - Fork 1
/
palm.txt.explain.code.R
199 lines (194 loc) · 8.54 KB
/
palm.txt.explain.code.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#' Explain code based on a query using the Google PaLM 2 text model
#'
#' This function sends a query with a code snippet to the Google PaLM 2 text model and generates a detailed explanation of the code. It supports
#' various programming languages and allows you to customize the explanation.
#'
#' @param model.parameter A character vector containing the API key, model version, and proxy status. Model version and type
#' are specified by Google. See function \code{\link{palm.connect}} for detail.
#' @param prompt A character string representing the code snippet for explanation. The length of the code snippet should be between
#' 1 and 8196 characters, inclusive.
#' @param language A character string specifying the programming language used in the code (default: "R").
#' @param temperature A numeric value between 0.0 and 1.0, inclusive (default: 0.7). Controls the randomness of the generated explanation.
#' A higher value (e.g., 0.9) results in more creative responses, while a lower value (e.g., 0.3) produces more straightforward explanations.
#' @param maxOutputTokens An integer value (default: 1024). Specifies the maximum number of tokens to include
#' in the generated explanation.
#' @param topP A numeric value (default: 0.95). Defines the maximum cumulative probability of tokens considered
#' when sampling. It controls the diversity of the explanation generated.
#' @param topK An integer value (default: 40). Sets the maximum number of tokens to consider when sampling.
#' @param htUnspecified Safety setting threshold for unspecified harm. The default threshold is "meda". Valid options are as follows.
#'
#' \itemize{
#' \item{"unsp"}{HARM_BLOCK_THRESHOLD_UNSPECIFIED}
#' \item{"lowa"}{BLOCK_LOW_AND_ABOVE}
#' \item{"meda"}{BLOCK_MEDIUM_AND_ABOVE}
#' \item{"high"}{BLOCK_ONLY_HIGH}
#' \item{"none"}{BLOCK_NONE}
#' }
#'
#' @param htDerogatory Safety setting threshold for derogatory harm. The default threshold is "meda". Valid options are as follows.
#'
#' \itemize{
#' \item{"unsp"}{HARM_BLOCK_THRESHOLD_UNSPECIFIED}
#' \item{"lowa"}{BLOCK_LOW_AND_ABOVE}
#' \item{"meda"}{BLOCK_MEDIUM_AND_ABOVE}
#' \item{"high"}{BLOCK_ONLY_HIGH}
#' \item{"none"}{BLOCK_NONE}
#' }
#'
#' @param htToxicity Safety setting threshold for toxicity harm. The default threshold is "meda". Valid options are as follows.
#'
#' \itemize{
#' \item{"unsp"}{HARM_BLOCK_THRESHOLD_UNSPECIFIED}
#' \item{"lowa"}{BLOCK_LOW_AND_ABOVE}
#' \item{"meda"}{BLOCK_MEDIUM_AND_ABOVE}
#' \item{"high"}{BLOCK_ONLY_HIGH}
#' \item{"none"}{BLOCK_NONE}
#' }
#'
#' @param htViolence Safety setting threshold for violence harm. The default threshold is "meda". Valid options are as follows.
#'
#' \itemize{
#' \item{"unsp"}{HARM_BLOCK_THRESHOLD_UNSPECIFIED}
#' \item{"lowa"}{BLOCK_LOW_AND_ABOVE}
#' \item{"meda"}{BLOCK_MEDIUM_AND_ABOVE}
#' \item{"high"}{BLOCK_ONLY_HIGH}
#' \item{"none"}{BLOCK_NONE}
#' }
#'
#' @param htSexual Safety setting threshold for sexual harm. The default threshold is "meda". Valid options are as follows.
#'
#' \itemize{
#' \item{"unsp"}{HARM_BLOCK_THRESHOLD_UNSPECIFIED}
#' \item{"lowa"}{BLOCK_LOW_AND_ABOVE}
#' \item{"meda"}{BLOCK_MEDIUM_AND_ABOVE}
#' \item{"high"}{BLOCK_ONLY_HIGH}
#' \item{"none"}{BLOCK_NONE}
#' }
#'
#' @param htMedical Safety setting threshold for medical harm. The default threshold is "meda". Valid options are as follows.
#'
#' \itemize{
#' \item{"unsp"}{HARM_BLOCK_THRESHOLD_UNSPECIFIED}
#' \item{"lowa"}{BLOCK_LOW_AND_ABOVE}
#' \item{"meda"}{BLOCK_MEDIUM_AND_ABOVE}
#' \item{"high"}{BLOCK_ONLY_HIGH}
#' \item{"none"}{BLOCK_NONE}
#' }
#'
#' @param htDangerous Safety setting threshold for dangerous harm. The default threshold is "meda". Valid options are as follows.
#'
#' \itemize{
#' \item{"unsp"}{HARM_BLOCK_THRESHOLD_UNSPECIFIED}
#' \item{"lowa"}{BLOCK_LOW_AND_ABOVE}
#' \item{"meda"}{BLOCK_MEDIUM_AND_ABOVE}
#' \item{"high"}{BLOCK_ONLY_HIGH}
#' \item{"none"}{BLOCK_NONE}
#' }
#'
#' @return A character string containing the detailed explanation of the provided code snippet based on the query and parameters.
#'
#' @details
#' This function interacts with the Google PaLM model by sending a code query to explain code. It allows you to customize the generated
#' code explanations by specifying the programming language, and additional parameters like temperature, token limits, and safety settings.
#'
#' If the function is successful, it returns a detailed explanation of the provided code as a character string. If an error occurs during the
#' API request, it will stop execution and provide an error message.
#'
#' The `model.parameter` argument should be a character vector with the API key, model version, and model type provided by
#' Google. You can obtain this information by following the instructions provided by Google for using the PaLM API.
#'
#' The safety settings control the content's safety level based on different harm categories. Harm thresholds are
#' specified as per Google's guidelines and can be customized to control the content generated.
#'
#' @examples
#' \dontrun{
#' # Connect to the model, replace API_KEY with your api key
#' palm.model = palm.connect("v1beta2",
#' "API_KEY",
#' FALSE)
#'
#' prompt = "foo <- function(n) {
#' if (n <= 0) {
#' return(0)
#' } else if (n == 1) {
#' return(1)
#' } else {
#' return(foo(n - 1) + foo(n - 2))
#' }
#' }"
#' code.explanation = palm.txt.explain.code(palm.model,
#' prompt)
#' cat(code.explanation)
#' }
#'
#' @seealso
#' \href{https://palmr.ly.gd.edu.kg/documentation/}{PaLMr - Documentation}
#'
#' \href{https://ai.google.dev/api/rest/v1beta/SafetySetting}{Safety Setting - Google AI for Developers}
#'
#' \href{https://ai.google.dev/api/rest/v1beta/HarmCategory}{HarmCategory - Google AI for Developers}
#'
#' @export
#'
#' @importFrom jsonlite toJSON
#' @importFrom httr GET POST add_headers content
palm.txt.explain.code = function(model.parameter,
prompt,
language = "R",
temperature = 0.7,
maxOutputTokens = 1024,
topP = 0.95,
topK = 40,
htUnspecified = "meda",
htDerogatory = "meda",
htToxicity = "meda",
htViolence = "meda",
htSexual = "meda",
htMedical = "meda",
htDangerous = "meda") {
model.parameter["version"] = match.arg(model.parameter["version"],
c("v1beta2", "v1beta3"),
several.ok = FALSE)
apiURL = ifelse(
model.parameter["proxy"],
paste0(
"https://api.genai.gd.edu.kg/google/",
model.parameter["version"],
"/models/text-bison-001",
":generateText?key=",
model.parameter["api"]
),
paste0(
"https://generativelanguage.googleapis.com/",
model.parameter["version"],
"/models/text-bison-001",
":generateText?key=",
model.parameter["api"]
)
)
requestBody = list(
prompt = list(
text = paste0("Explain the following", language, "code:\n",
"# Code starts #\n",
prompt, "\n",
"# Code ends #\n")
),
safetySettings = generateSafetySettings(htUnspecified,
htDerogatory,
htToxicity,
htViolence,
htSexual,
htMedical,
htDangerous),
temperature = temperature,
maxOutputTokens = as.integer(maxOutputTokens),
topP = topP,
topK = as.integer(topK)
)
requestBodyJSON = jsonlite::toJSON(requestBody, auto_unbox = TRUE)
response = httr::POST(url = apiURL,
body = requestBodyJSON,
httr::add_headers("Content-Type" = "application/json"))
responseJSON = httr::content(response, "parsed")
generateOutput(responseJSON)
}