functions.php
119 lines
| 1 | <?php |
| 2 | |
| 3 | trait Meow_MWAI_Engines_Trait_Functions { |
| 4 | /** |
| 5 | * Check if model supports functions |
| 6 | */ |
| 7 | protected function supports_functions( $model ) { |
| 8 | // Get model info from core |
| 9 | $models = $this->core->get_models(); |
| 10 | foreach ( $models as $m ) { |
| 11 | if ( $m['model'] === $model ) { |
| 12 | return !empty( $m['tags'] ) && in_array( 'functions', $m['tags'] ); |
| 13 | } |
| 14 | } |
| 15 | return false; |
| 16 | } |
| 17 | |
| 18 | /** |
| 19 | * Build function definitions for API |
| 20 | */ |
| 21 | protected function build_function_definitions( $query ) { |
| 22 | if ( empty( $query->functions ) ) { |
| 23 | return null; |
| 24 | } |
| 25 | |
| 26 | $tools = []; |
| 27 | foreach ( $query->functions as $function ) { |
| 28 | $tools[] = [ |
| 29 | 'type' => 'function', |
| 30 | 'function' => [ |
| 31 | 'name' => $function['name'], |
| 32 | 'description' => $function['description'] ?? '', |
| 33 | 'parameters' => $function['parameters'] ?? [ |
| 34 | 'type' => 'object', |
| 35 | 'properties' => [] |
| 36 | ] |
| 37 | ] |
| 38 | ]; |
| 39 | } |
| 40 | |
| 41 | return $tools; |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * Extract function calls from response |
| 46 | */ |
| 47 | protected function extract_function_calls( $data ) { |
| 48 | $calls = []; |
| 49 | |
| 50 | // OpenAI format |
| 51 | if ( isset( $data['choices'][0]['message']['tool_calls'] ) ) { |
| 52 | foreach ( $data['choices'][0]['message']['tool_calls'] as $tool_call ) { |
| 53 | if ( $tool_call['type'] === 'function' ) { |
| 54 | $calls[] = [ |
| 55 | 'id' => $tool_call['id'], |
| 56 | 'name' => $tool_call['function']['name'], |
| 57 | 'arguments' => $tool_call['function']['arguments'] |
| 58 | ]; |
| 59 | } |
| 60 | } |
| 61 | } |
| 62 | // Anthropic format |
| 63 | elseif ( isset( $data['content'] ) ) { |
| 64 | foreach ( $data['content'] as $content ) { |
| 65 | if ( $content['type'] === 'tool_use' ) { |
| 66 | $calls[] = [ |
| 67 | 'id' => $content['id'], |
| 68 | 'name' => $content['name'], |
| 69 | 'arguments' => json_encode( $content['input'] ) |
| 70 | ]; |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | return $calls; |
| 76 | } |
| 77 | |
| 78 | /** |
| 79 | * Build function result message |
| 80 | */ |
| 81 | protected function build_function_result_message( $call_id, $result ) { |
| 82 | return [ |
| 83 | 'role' => 'tool', |
| 84 | 'tool_call_id' => $call_id, |
| 85 | 'content' => is_string( $result ) ? $result : json_encode( $result ) |
| 86 | ]; |
| 87 | } |
| 88 | |
| 89 | /** |
| 90 | * Check if response contains function calls |
| 91 | */ |
| 92 | protected function has_function_calls( $data ) { |
| 93 | // OpenAI format |
| 94 | if ( isset( $data['choices'][0]['message']['tool_calls'] ) ) { |
| 95 | return count( $data['choices'][0]['message']['tool_calls'] ) > 0; |
| 96 | } |
| 97 | |
| 98 | // Anthropic format |
| 99 | if ( isset( $data['content'] ) ) { |
| 100 | foreach ( $data['content'] as $content ) { |
| 101 | if ( $content['type'] === 'tool_use' ) { |
| 102 | return true; |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | // Google format |
| 108 | if ( isset( $data['candidates'][0]['content']['parts'] ) ) { |
| 109 | foreach ( $data['candidates'][0]['content']['parts'] as $part ) { |
| 110 | if ( isset( $part['functionCall'] ) ) { |
| 111 | return true; |
| 112 | } |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | return false; |
| 117 | } |
| 118 | } |
| 119 |