Coverage Report

Created: 2026-04-15 19:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/ai/ai_functions.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <gen_cpp/FrontendService.h>
21
#include <gen_cpp/PaloInternalService_types.h>
22
#include <glog/logging.h>
23
24
#include <algorithm>
25
#include <cctype>
26
#include <cstdlib>
27
#include <memory>
28
#include <string>
29
#include <type_traits>
30
#include <vector>
31
32
#include "common/config.h"
33
#include "common/status.h"
34
#include "core/column/column_array.h"
35
#include "core/column/column_const.h"
36
#include "core/column/column_nullable.h"
37
#include "core/cow.h"
38
#include "core/data_type/data_type_array.h"
39
#include "core/data_type/data_type_number.h"
40
#include "core/data_type/define_primitive_type.h"
41
#include "core/data_type/primitive_type.h"
42
#include "exprs/function/ai/ai_adapter.h"
43
#include "exprs/function/function.h"
44
#include "runtime/query_context.h"
45
#include "runtime/runtime_state.h"
46
#include "service/http/http_client.h"
47
#include "util/security.h"
48
#include "util/threadpool.h"
49
50
namespace doris {
51
52
// Base class for AI-based functions
53
template <typename Derived>
54
class AIFunction : public IFunction {
55
public:
56
11
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_17FunctionAIExtractEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_14FunctionAIMaskEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_19FunctionAITranslateEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE8get_nameB5cxx11Ev
Line
Count
Source
56
1
    std::string get_name() const override { return assert_cast<const Derived&>(*this).name; }
57
58
    // If the user doesn't provide the first arg, `resource_name`
59
    // FE will add the `resource_name` to the arguments list using the Session Variable.
60
    // So the value here should be the maximum number that the function can accept.
61
0
    size_t get_number_of_arguments() const override {
62
0
        return assert_cast<const Derived&>(*this).number_of_arguments;
63
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE23get_number_of_argumentsEv
64
65
0
    bool is_blockable() const override { return true; }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12is_blockableEv
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE12is_blockableEv
66
67
    virtual Status build_prompt(const Block& block, const ColumnNumbers& arguments, size_t row_num,
68
44
                                std::string& prompt) const {
69
44
        const ColumnWithTypeAndName& text_column = block.get_by_position(arguments[1]);
70
44
        StringRef text_ref = text_column.column->get_data_at(row_num);
71
44
        prompt = std::string(text_ref.data, text_ref.size);
72
73
44
        return Status::OK();
74
44
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
68
2
                                std::string& prompt) const {
69
2
        const ColumnWithTypeAndName& text_column = block.get_by_position(arguments[1]);
70
2
        StringRef text_ref = text_column.column->get_data_at(row_num);
71
2
        prompt = std::string(text_ref.data, text_ref.size);
72
73
2
        return Status::OK();
74
2
    }
_ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
68
1
                                std::string& prompt) const {
69
1
        const ColumnWithTypeAndName& text_column = block.get_by_position(arguments[1]);
70
1
        StringRef text_ref = text_column.column->get_data_at(row_num);
71
1
        prompt = std::string(text_ref.data, text_ref.size);
72
73
1
        return Status::OK();
74
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
68
1
                                std::string& prompt) const {
69
1
        const ColumnWithTypeAndName& text_column = block.get_by_position(arguments[1]);
70
1
        StringRef text_ref = text_column.column->get_data_at(row_num);
71
1
        prompt = std::string(text_ref.data, text_ref.size);
72
73
1
        return Status::OK();
74
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
68
36
                                std::string& prompt) const {
69
36
        const ColumnWithTypeAndName& text_column = block.get_by_position(arguments[1]);
70
36
        StringRef text_ref = text_column.column->get_data_at(row_num);
71
36
        prompt = std::string(text_ref.data, text_ref.size);
72
73
36
        return Status::OK();
74
36
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE12build_promptERKNS_5BlockERKSt6vectorIjSaIjEEmRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Line
Count
Source
68
4
                                std::string& prompt) const {
69
4
        const ColumnWithTypeAndName& text_column = block.get_by_position(arguments[1]);
70
4
        StringRef text_ref = text_column.column->get_data_at(row_num);
71
4
        prompt = std::string(text_ref.data, text_ref.size);
72
73
4
        return Status::OK();
74
4
    }
75
76
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
77
67
                        uint32_t result, size_t input_rows_count) const override {
78
67
        TAIResource config;
79
67
        std::shared_ptr<AIAdapter> adapter;
80
67
        if (Status status = assert_cast<const Derived*>(this)->_init_from_resource(
81
67
                    context, block, arguments, config, adapter);
82
67
            !status.ok()) {
83
2
            return status;
84
2
        }
85
86
65
        return assert_cast<const Derived&>(*this).execute_with_adapter(
87
65
                context, block, arguments, result, input_rows_count, config, adapter);
88
67
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
77
3
                        uint32_t result, size_t input_rows_count) const override {
78
3
        TAIResource config;
79
3
        std::shared_ptr<AIAdapter> adapter;
80
3
        if (Status status = assert_cast<const Derived*>(this)->_init_from_resource(
81
3
                    context, block, arguments, config, adapter);
82
3
            !status.ok()) {
83
2
            return status;
84
2
        }
85
86
1
        return assert_cast<const Derived&>(*this).execute_with_adapter(
87
1
                context, block, arguments, result, input_rows_count, config, adapter);
88
3
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
77
20
                        uint32_t result, size_t input_rows_count) const override {
78
20
        TAIResource config;
79
20
        std::shared_ptr<AIAdapter> adapter;
80
20
        if (Status status = assert_cast<const Derived*>(this)->_init_from_resource(
81
20
                    context, block, arguments, config, adapter);
82
20
            !status.ok()) {
83
0
            return status;
84
0
        }
85
86
20
        return assert_cast<const Derived&>(*this).execute_with_adapter(
87
20
                context, block, arguments, result, input_rows_count, config, adapter);
88
20
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
77
34
                        uint32_t result, size_t input_rows_count) const override {
78
34
        TAIResource config;
79
34
        std::shared_ptr<AIAdapter> adapter;
80
34
        if (Status status = assert_cast<const Derived*>(this)->_init_from_resource(
81
34
                    context, block, arguments, config, adapter);
82
34
            !status.ok()) {
83
0
            return status;
84
0
        }
85
86
34
        return assert_cast<const Derived&>(*this).execute_with_adapter(
87
34
                context, block, arguments, result, input_rows_count, config, adapter);
88
34
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
77
10
                        uint32_t result, size_t input_rows_count) const override {
78
10
        TAIResource config;
79
10
        std::shared_ptr<AIAdapter> adapter;
80
10
        if (Status status = assert_cast<const Derived*>(this)->_init_from_resource(
81
10
                    context, block, arguments, config, adapter);
82
10
            !status.ok()) {
83
0
            return status;
84
0
        }
85
86
10
        return assert_cast<const Derived&>(*this).execute_with_adapter(
87
10
                context, block, arguments, result, input_rows_count, config, adapter);
88
10
    }
89
90
protected:
91
    // Derived classes can override this method for non-text/default behavior.
92
    // The base implementation keeps previous text-oriented processing unchanged.
93
    Status execute_with_adapter(FunctionContext* context, Block& block,
94
                                const ColumnNumbers& arguments, uint32_t result,
95
                                size_t input_rows_count, const TAIResource& config,
96
1
                                std::shared_ptr<AIAdapter>& adapter) const {
97
1
        DataTypePtr return_type_impl =
98
1
                assert_cast<const Derived&>(*this).get_return_type_impl(DataTypes());
99
1
        if (return_type_impl->get_primitive_type() != PrimitiveType::TYPE_STRING) {
100
0
            return Status::InternalError("{} must override execute for non-string return type",
101
0
                                         get_name());
102
0
        }
103
1
        MutableColumnPtr col_result = ColumnString::create();
104
105
2
        for (size_t i = 0; i < input_rows_count; ++i) {
106
            // Build AI prompt text
107
1
            std::string prompt;
108
1
            RETURN_IF_ERROR(
109
1
                    assert_cast<const Derived&>(*this).build_prompt(block, arguments, i, prompt));
110
111
1
            std::string string_result;
112
1
            RETURN_IF_ERROR(
113
1
                    execute_single_request(prompt, string_result, config, adapter, context));
114
1
            assert_cast<ColumnString&>(*col_result)
115
1
                    .insert_data(string_result.data(), string_result.size());
116
1
        }
117
118
1
        block.replace_by_position(result, std::move(col_result));
119
1
        return Status::OK();
120
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
96
1
                                std::shared_ptr<AIAdapter>& adapter) const {
97
1
        DataTypePtr return_type_impl =
98
1
                assert_cast<const Derived&>(*this).get_return_type_impl(DataTypes());
99
1
        if (return_type_impl->get_primitive_type() != PrimitiveType::TYPE_STRING) {
100
0
            return Status::InternalError("{} must override execute for non-string return type",
101
0
                                         get_name());
102
0
        }
103
1
        MutableColumnPtr col_result = ColumnString::create();
104
105
2
        for (size_t i = 0; i < input_rows_count; ++i) {
106
            // Build AI prompt text
107
1
            std::string prompt;
108
1
            RETURN_IF_ERROR(
109
1
                    assert_cast<const Derived&>(*this).build_prompt(block, arguments, i, prompt));
110
111
1
            std::string string_result;
112
1
            RETURN_IF_ERROR(
113
1
                    execute_single_request(prompt, string_result, config, adapter, context));
114
1
            assert_cast<ColumnString&>(*col_result)
115
1
                    .insert_data(string_result.data(), string_result.size());
116
1
        }
117
118
1
        block.replace_by_position(result, std::move(col_result));
119
1
        return Status::OK();
120
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE20execute_with_adapterEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmRKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
121
122
    // The endpoint `v1/completions` does not support `system_prompt`.
123
    // To ensure a clear structure and stable AI results.
124
    // Convert from `v1/completions` to `v1/chat/completions`
125
68
    static void normalize_endpoint(TAIResource& config) {
126
68
        if (config.endpoint.ends_with("v1/completions")) {
127
1
            static constexpr std::string_view legacy_suffix = "v1/completions";
128
1
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
129
1
                                    legacy_suffix.size(), "v1/chat/completions");
130
1
        }
131
68
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_18FunctionAIClassifyEE18normalize_endpointERNS_11TAIResourceE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_17FunctionAIExtractEE18normalize_endpointERNS_11TAIResourceE
_ZN5doris10AIFunctionINS_19FunctionAISentimentEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
125
4
    static void normalize_endpoint(TAIResource& config) {
126
4
        if (config.endpoint.ends_with("v1/completions")) {
127
1
            static constexpr std::string_view legacy_suffix = "v1/completions";
128
1
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
129
1
                                    legacy_suffix.size(), "v1/chat/completions");
130
1
        }
131
4
    }
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAISummarizeEE18normalize_endpointERNS_11TAIResourceE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_14FunctionAIMaskEE18normalize_endpointERNS_11TAIResourceE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_18FunctionAIGenerateEE18normalize_endpointERNS_11TAIResourceE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_20FunctionAIFixGrammarEE18normalize_endpointERNS_11TAIResourceE
Unexecuted instantiation: _ZN5doris10AIFunctionINS_19FunctionAITranslateEE18normalize_endpointERNS_11TAIResourceE
_ZN5doris10AIFunctionINS_20FunctionAISimilarityEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
125
20
    static void normalize_endpoint(TAIResource& config) {
126
20
        if (config.endpoint.ends_with("v1/completions")) {
127
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
128
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
129
0
                                    legacy_suffix.size(), "v1/chat/completions");
130
0
        }
131
20
    }
_ZN5doris10AIFunctionINS_16FunctionAIFilterEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
125
34
    static void normalize_endpoint(TAIResource& config) {
126
34
        if (config.endpoint.ends_with("v1/completions")) {
127
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
128
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
129
0
                                    legacy_suffix.size(), "v1/chat/completions");
130
0
        }
131
34
    }
_ZN5doris10AIFunctionINS_13FunctionEmbedEE18normalize_endpointERNS_11TAIResourceE
Line
Count
Source
125
10
    static void normalize_endpoint(TAIResource& config) {
126
10
        if (config.endpoint.ends_with("v1/completions")) {
127
0
            static constexpr std::string_view legacy_suffix = "v1/completions";
128
0
            config.endpoint.replace(config.endpoint.size() - legacy_suffix.size(),
129
0
                                    legacy_suffix.size(), "v1/chat/completions");
130
0
        }
131
10
    }
132
133
    // The ai resource must be literal
134
    Status _init_from_resource(FunctionContext* context, const Block& block,
135
                               const ColumnNumbers& arguments, TAIResource& config,
136
67
                               std::shared_ptr<AIAdapter>& adapter) const {
137
        // 1. Initialize config
138
67
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
139
67
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
140
67
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
141
142
67
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
143
67
                context->state()->get_query_ctx()->get_ai_resources();
144
67
        if (!ai_resources) {
145
1
            return Status::InternalError("AI resources metadata missing in QueryContext");
146
1
        }
147
66
        auto it = ai_resources->find(resource_name);
148
66
        if (it == ai_resources->end()) {
149
1
            return Status::InvalidArgument("AI resource not found: " + resource_name);
150
1
        }
151
65
        config = it->second;
152
153
65
        normalize_endpoint(config);
154
155
        // 2. Create an adapter based on provider_type
156
65
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
157
65
        if (!adapter) {
158
0
            return Status::InvalidArgument("Unsupported AI provider type: " + config.provider_type);
159
0
        }
160
65
        adapter->init(config);
161
162
65
        return Status::OK();
163
65
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
136
3
                               std::shared_ptr<AIAdapter>& adapter) const {
137
        // 1. Initialize config
138
3
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
139
3
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
140
3
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
141
142
3
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
143
3
                context->state()->get_query_ctx()->get_ai_resources();
144
3
        if (!ai_resources) {
145
1
            return Status::InternalError("AI resources metadata missing in QueryContext");
146
1
        }
147
2
        auto it = ai_resources->find(resource_name);
148
2
        if (it == ai_resources->end()) {
149
1
            return Status::InvalidArgument("AI resource not found: " + resource_name);
150
1
        }
151
1
        config = it->second;
152
153
1
        normalize_endpoint(config);
154
155
        // 2. Create an adapter based on provider_type
156
1
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
157
1
        if (!adapter) {
158
0
            return Status::InvalidArgument("Unsupported AI provider type: " + config.provider_type);
159
0
        }
160
1
        adapter->init(config);
161
162
1
        return Status::OK();
163
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
136
20
                               std::shared_ptr<AIAdapter>& adapter) const {
137
        // 1. Initialize config
138
20
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
139
20
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
140
20
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
141
142
20
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
143
20
                context->state()->get_query_ctx()->get_ai_resources();
144
20
        if (!ai_resources) {
145
0
            return Status::InternalError("AI resources metadata missing in QueryContext");
146
0
        }
147
20
        auto it = ai_resources->find(resource_name);
148
20
        if (it == ai_resources->end()) {
149
0
            return Status::InvalidArgument("AI resource not found: " + resource_name);
150
0
        }
151
20
        config = it->second;
152
153
20
        normalize_endpoint(config);
154
155
        // 2. Create an adapter based on provider_type
156
20
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
157
20
        if (!adapter) {
158
0
            return Status::InvalidArgument("Unsupported AI provider type: " + config.provider_type);
159
0
        }
160
20
        adapter->init(config);
161
162
20
        return Status::OK();
163
20
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
136
34
                               std::shared_ptr<AIAdapter>& adapter) const {
137
        // 1. Initialize config
138
34
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
139
34
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
140
34
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
141
142
34
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
143
34
                context->state()->get_query_ctx()->get_ai_resources();
144
34
        if (!ai_resources) {
145
0
            return Status::InternalError("AI resources metadata missing in QueryContext");
146
0
        }
147
34
        auto it = ai_resources->find(resource_name);
148
34
        if (it == ai_resources->end()) {
149
0
            return Status::InvalidArgument("AI resource not found: " + resource_name);
150
0
        }
151
34
        config = it->second;
152
153
34
        normalize_endpoint(config);
154
155
        // 2. Create an adapter based on provider_type
156
34
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
157
34
        if (!adapter) {
158
0
            return Status::InvalidArgument("Unsupported AI provider type: " + config.provider_type);
159
0
        }
160
34
        adapter->init(config);
161
162
34
        return Status::OK();
163
34
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE19_init_from_resourceEPNS_15FunctionContextERKNS_5BlockERKSt6vectorIjSaIjEERNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEE
Line
Count
Source
136
10
                               std::shared_ptr<AIAdapter>& adapter) const {
137
        // 1. Initialize config
138
10
        const ColumnWithTypeAndName& resource_column = block.get_by_position(arguments[0]);
139
10
        StringRef resource_name_ref = resource_column.column->get_data_at(0);
140
10
        std::string resource_name = std::string(resource_name_ref.data, resource_name_ref.size);
141
142
10
        const std::shared_ptr<std::map<std::string, TAIResource>>& ai_resources =
143
10
                context->state()->get_query_ctx()->get_ai_resources();
144
10
        if (!ai_resources) {
145
0
            return Status::InternalError("AI resources metadata missing in QueryContext");
146
0
        }
147
10
        auto it = ai_resources->find(resource_name);
148
10
        if (it == ai_resources->end()) {
149
0
            return Status::InvalidArgument("AI resource not found: " + resource_name);
150
0
        }
151
10
        config = it->second;
152
153
10
        normalize_endpoint(config);
154
155
        // 2. Create an adapter based on provider_type
156
10
        adapter = AIAdapterFactory::create_adapter(config.provider_type);
157
10
        if (!adapter) {
158
0
            return Status::InvalidArgument("Unsupported AI provider type: " + config.provider_type);
159
0
        }
160
10
        adapter->init(config);
161
162
10
        return Status::OK();
163
10
    }
164
165
    // Executes the actual HTTP request
166
    Status do_send_request(HttpClient* client, const std::string& request_body,
167
                           std::string& response, const TAIResource& config,
168
3
                           std::shared_ptr<AIAdapter>& adapter, FunctionContext* context) const {
169
3
        RETURN_IF_ERROR(client->init(config.endpoint, false));
170
171
3
        QueryContext* query_ctx = context->state()->get_query_ctx();
172
3
        int64_t remaining_query_time = query_ctx->get_remaining_query_time_seconds();
173
3
        if (remaining_query_time <= 0) {
174
0
            return Status::TimedOut("Query timeout exceeded before AI request");
175
0
        }
176
177
3
        client->set_timeout_ms(remaining_query_time * 1000);
178
179
3
        if (!config.api_key.empty()) {
180
3
            RETURN_IF_ERROR(adapter->set_authentication(client));
181
3
        }
182
183
3
        Status st = client->execute_post_request(request_body, &response);
184
3
        long http_status = client->get_http_status();
185
186
3
        if (!st.ok()) {
187
1
            LOG(INFO) << "AI HTTP request failed before status validation, provider="
188
1
                      << config.provider_type << ", model=" << config.model_name
189
1
                      << ", endpoint=" << mask_token(config.endpoint)
190
1
                      << ", exec_status=" << st.to_string() << ", response_body=" << response;
191
1
            return st;
192
1
        }
193
2
        if (http_status != 200) {
194
1
            return Status::HttpError(
195
1
                    "http status code is not 200, code={}, url={}, response_body={}", http_status,
196
1
                    mask_token(config.endpoint), response);
197
1
        }
198
1
        return Status::OK();
199
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
168
3
                           std::shared_ptr<AIAdapter>& adapter, FunctionContext* context) const {
169
3
        RETURN_IF_ERROR(client->init(config.endpoint, false));
170
171
3
        QueryContext* query_ctx = context->state()->get_query_ctx();
172
3
        int64_t remaining_query_time = query_ctx->get_remaining_query_time_seconds();
173
3
        if (remaining_query_time <= 0) {
174
0
            return Status::TimedOut("Query timeout exceeded before AI request");
175
0
        }
176
177
3
        client->set_timeout_ms(remaining_query_time * 1000);
178
179
3
        if (!config.api_key.empty()) {
180
3
            RETURN_IF_ERROR(adapter->set_authentication(client));
181
3
        }
182
183
3
        Status st = client->execute_post_request(request_body, &response);
184
3
        long http_status = client->get_http_status();
185
186
3
        if (!st.ok()) {
187
1
            LOG(INFO) << "AI HTTP request failed before status validation, provider="
188
1
                      << config.provider_type << ", model=" << config.model_name
189
1
                      << ", endpoint=" << mask_token(config.endpoint)
190
1
                      << ", exec_status=" << st.to_string() << ", response_body=" << response;
191
1
            return st;
192
1
        }
193
2
        if (http_status != 200) {
194
1
            return Status::HttpError(
195
1
                    "http status code is not 200, code={}, url={}, response_body={}", http_status,
196
1
                    mask_token(config.endpoint), response);
197
1
        }
198
1
        return Status::OK();
199
2
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE15do_send_requestEPNS_10HttpClientERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSA_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
200
201
    // Sends the request with retry mechanism for handling transient failures
202
    Status send_request_to_llm(const std::string& request_body, std::string& response,
203
                               const TAIResource& config, std::shared_ptr<AIAdapter>& adapter,
204
0
                               FunctionContext* context) const {
205
0
        return HttpClient::execute_with_retry(config.max_retries, config.retry_delay_second,
206
0
                                              [this, &request_body, &response, &config, &adapter,
207
0
                                               context](HttpClient* client) -> Status {
208
0
                                                  return this->do_send_request(client, request_body,
209
0
                                                                               response, config,
210
0
                                                                               adapter, context);
211
0
                                              });
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAISentimentEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_14FunctionAIMaskEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_17FunctionAIExtractEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_19FunctionAITranslateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_16FunctionAIFilterEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
Unexecuted instantiation: _ZZNK5doris10AIFunctionINS_13FunctionEmbedEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextEENKUlPNS_10HttpClientEE_clESM_
212
0
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISentimentEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_16FunctionAIFilterEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_13FunctionEmbedEE19send_request_to_llmERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
213
214
    // Wrapper for executing a single LLM request
215
    Status execute_single_request(const std::string& input, std::string& result,
216
                                  const TAIResource& config, std::shared_ptr<AIAdapter>& adapter,
217
56
                                  FunctionContext* context) const {
218
56
        std::vector<std::string> inputs = {input};
219
56
        std::vector<std::string> results;
220
221
56
        std::string request_body;
222
56
        RETURN_IF_ERROR(adapter->build_request_payload(
223
56
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
224
225
56
        std::string response;
226
56
        if (config.provider_type == "MOCK") {
227
            // Mock path for UT
228
56
            response = "this is a mock response. " + input;
229
56
        } else {
230
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
231
0
        }
232
233
56
        RETURN_IF_ERROR(adapter->parse_response(response, results));
234
56
        if (results.empty()) {
235
0
            return Status::InternalError("AI returned empty result");
236
0
        }
237
238
56
        result = std::move(results[0]);
239
56
        return Status::OK();
240
56
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIClassifyEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_17FunctionAIExtractEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
217
1
                                  FunctionContext* context) const {
218
1
        std::vector<std::string> inputs = {input};
219
1
        std::vector<std::string> results;
220
221
1
        std::string request_body;
222
1
        RETURN_IF_ERROR(adapter->build_request_payload(
223
1
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
224
225
1
        std::string response;
226
1
        if (config.provider_type == "MOCK") {
227
            // Mock path for UT
228
1
            response = "this is a mock response. " + input;
229
1
        } else {
230
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
231
0
        }
232
233
1
        RETURN_IF_ERROR(adapter->parse_response(response, results));
234
1
        if (results.empty()) {
235
0
            return Status::InternalError("AI returned empty result");
236
0
        }
237
238
1
        result = std::move(results[0]);
239
1
        return Status::OK();
240
1
    }
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAISummarizeEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_14FunctionAIMaskEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_18FunctionAIGenerateEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_20FunctionAIFixGrammarEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Unexecuted instantiation: _ZNK5doris10AIFunctionINS_19FunctionAITranslateEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
_ZNK5doris10AIFunctionINS_20FunctionAISimilarityEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
217
20
                                  FunctionContext* context) const {
218
20
        std::vector<std::string> inputs = {input};
219
20
        std::vector<std::string> results;
220
221
20
        std::string request_body;
222
20
        RETURN_IF_ERROR(adapter->build_request_payload(
223
20
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
224
225
20
        std::string response;
226
20
        if (config.provider_type == "MOCK") {
227
            // Mock path for UT
228
20
            response = "this is a mock response. " + input;
229
20
        } else {
230
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
231
0
        }
232
233
20
        RETURN_IF_ERROR(adapter->parse_response(response, results));
234
20
        if (results.empty()) {
235
0
            return Status::InternalError("AI returned empty result");
236
0
        }
237
238
20
        result = std::move(results[0]);
239
20
        return Status::OK();
240
20
    }
_ZNK5doris10AIFunctionINS_16FunctionAIFilterEE22execute_single_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS8_RKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
217
35
                                  FunctionContext* context) const {
218
35
        std::vector<std::string> inputs = {input};
219
35
        std::vector<std::string> results;
220
221
35
        std::string request_body;
222
35
        RETURN_IF_ERROR(adapter->build_request_payload(
223
35
                inputs, assert_cast<const Derived&>(*this).system_prompt, request_body));
224
225
35
        std::string response;
226
35
        if (config.provider_type == "MOCK") {
227
            // Mock path for UT
228
35
            response = "this is a mock response. " + input;
229
35
        } else {
230
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
231
0
        }
232
233
35
        RETURN_IF_ERROR(adapter->parse_response(response, results));
234
35
        if (results.empty()) {
235
0
            return Status::InternalError("AI returned empty result");
236
0
        }
237
238
35
        result = std::move(results[0]);
239
35
        return Status::OK();
240
35
    }
241
242
    Status execute_single_request(const std::string& input, std::vector<float>& result,
243
                                  const TAIResource& config, std::shared_ptr<AIAdapter>& adapter,
244
3
                                  FunctionContext* context) const {
245
3
        std::vector<std::string> inputs = {input};
246
3
        std::vector<std::vector<float>> results;
247
248
3
        std::string request_body;
249
3
        RETURN_IF_ERROR(adapter->build_embedding_request(inputs, request_body));
250
251
3
        std::string response;
252
3
        if (config.provider_type == "MOCK") {
253
            // Mock path for UT
254
3
            response = "{\"embedding\": [0, 1, 2, 3, 4]}";
255
3
        } else {
256
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
257
0
        }
258
259
3
        RETURN_IF_ERROR(adapter->parse_embedding_response(response, results));
260
3
        if (results.empty()) {
261
0
            return Status::InternalError("AI returned empty result");
262
0
        }
263
264
3
        result = std::move(results[0]);
265
3
        return Status::OK();
266
3
    }
267
268
    // Sends a pre-built embedding request body and parses the float vector result.
269
    // Used when the request body has already been constructed (e.g., multimodal embedding).
270
    Status execute_embedding_request(const std::string& request_body, std::vector<float>& result,
271
                                     const TAIResource& config, std::shared_ptr<AIAdapter>& adapter,
272
6
                                     FunctionContext* context) const {
273
6
        std::vector<std::vector<float>> results;
274
6
        std::string response;
275
6
        if (config.provider_type == "MOCK") {
276
6
            response = "{\"embedding\": [0, 1, 2, 3, 4]}";
277
6
        } else {
278
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
279
0
        }
280
6
        RETURN_IF_ERROR(adapter->parse_embedding_response(response, results));
281
6
        if (results.empty()) {
282
1
            return Status::InternalError("AI returned empty result");
283
1
        }
284
5
        result = std::move(results[0]);
285
5
        return Status::OK();
286
6
    }
_ZNK5doris10AIFunctionINS_13FunctionEmbedEE25execute_embedding_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIfSaIfEERKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
272
4
                                     FunctionContext* context) const {
273
4
        std::vector<std::vector<float>> results;
274
4
        std::string response;
275
4
        if (config.provider_type == "MOCK") {
276
4
            response = "{\"embedding\": [0, 1, 2, 3, 4]}";
277
4
        } else {
278
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
279
0
        }
280
4
        RETURN_IF_ERROR(adapter->parse_embedding_response(response, results));
281
4
        if (results.empty()) {
282
0
            return Status::InternalError("AI returned empty result");
283
0
        }
284
4
        result = std::move(results[0]);
285
4
        return Status::OK();
286
4
    }
_ZNK5doris10AIFunctionINS_19FunctionAISentimentEE25execute_embedding_requestERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIfSaIfEERKNS_11TAIResourceERSt10shared_ptrINS_9AIAdapterEEPNS_15FunctionContextE
Line
Count
Source
272
2
                                     FunctionContext* context) const {
273
2
        std::vector<std::vector<float>> results;
274
2
        std::string response;
275
2
        if (config.provider_type == "MOCK") {
276
2
            response = "{\"embedding\": [0, 1, 2, 3, 4]}";
277
2
        } else {
278
0
            RETURN_IF_ERROR(send_request_to_llm(request_body, response, config, adapter, context));
279
0
        }
280
2
        RETURN_IF_ERROR(adapter->parse_embedding_response(response, results));
281
2
        if (results.empty()) {
282
1
            return Status::InternalError("AI returned empty result");
283
1
        }
284
1
        result = std::move(results[0]);
285
1
        return Status::OK();
286
2
    }
287
};
288
289
} // namespace doris