| 176 | |
| 177 | template <bool fastpath, AiFunctions::AI_PLATFORM platform> |
| 178 | StringVal AiFunctions::AiGenerateTextInternal(FunctionContext* ctx, |
| 179 | const std::string_view& endpoint_sv, const StringVal& prompt, const StringVal& model, |
| 180 | const StringVal& auth_credential, const StringVal& platform_params, |
| 181 | const StringVal& impala_options, const bool dry_run) { |
| 182 | // Generate the header for the POST request |
| 183 | vector<string> headers; |
| 184 | headers.emplace_back(OPEN_AI_REQUEST_FIELD_CONTENT_TYPE_HEADER); |
| 185 | string authHeader; |
| 186 | AiFunctions::AiFunctionsOptions ai_options; |
| 187 | Document impala_options_document; |
| 188 | |
| 189 | if (!fastpath) { |
| 190 | try { |
| 191 | ParseImpalaOptions(impala_options, impala_options_document, ai_options); |
| 192 | } catch (const std::runtime_error& e) { |
| 193 | std::stringstream ss; |
| 194 | ss << AI_GENERATE_TXT_JSON_PARSE_ERROR << ": " << e.what(); |
| 195 | LOG(WARNING) << ss.str(); |
| 196 | const Status err_status(ss.str()); |
| 197 | RETURN_STRINGVAL_IF_ERROR(ctx, err_status); |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | if (!fastpath && auth_credential.ptr != nullptr && auth_credential.len != 0) { |
| 202 | if (ai_options.credential_type == CREDENTIAL_TYPE::PLAIN) { |
| 203 | // Use the credential as a plain text token. |
| 204 | std::string_view token( |
| 205 | reinterpret_cast<char*>(auth_credential.ptr), auth_credential.len); |
| 206 | RETURN_STRINGVAL_IF_ERROR( |
| 207 | ctx, getAuthorizationHeader<platform>(authHeader, token, ai_options)); |
| 208 | } else { |
| 209 | DCHECK(ai_options.credential_type == CREDENTIAL_TYPE::JCEKS); |
| 210 | // Use the credential as JCEKS secret and fetch API key. |
| 211 | string api_key; |
| 212 | string api_key_secret( |
| 213 | reinterpret_cast<char*>(auth_credential.ptr), auth_credential.len); |
| 214 | RETURN_STRINGVAL_IF_ERROR(ctx, |
| 215 | ExecEnv::GetInstance()->frontend()->GetSecretFromKeyStore( |
| 216 | api_key_secret, &api_key)); |
| 217 | RETURN_STRINGVAL_IF_ERROR( |
| 218 | ctx, getAuthorizationHeader<platform>(authHeader, api_key, ai_options)); |
| 219 | } |
| 220 | } else { |
| 221 | RETURN_STRINGVAL_IF_ERROR( |
| 222 | ctx, getAuthorizationHeader<platform>(authHeader, ai_api_key_, ai_options)); |
| 223 | } |
| 224 | headers.emplace_back(authHeader); |
| 225 | |
| 226 | string payload_str; |
| 227 | if (!fastpath && !ai_options.ai_custom_payload.empty()) { |
| 228 | payload_str = |
| 229 | string(ai_options.ai_custom_payload.data(), ai_options.ai_custom_payload.size()); |
| 230 | } else { |
| 231 | // Generate the payload for the POST request |
| 232 | Document payload; |
| 233 | payload.SetObject(); |
| 234 | Document::AllocatorType& payload_allocator = payload.GetAllocator(); |
| 235 | // Azure Open AI endpoint doesn't expect model as a separate param since it's |
nothing calls this directly
no test coverage detected