forked from Ddiidev/sdk_gemini
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgemini_api.v
More file actions
144 lines (123 loc) · 3.41 KB
/
Copy pathgemini_api.v
File metadata and controls
144 lines (123 loc) · 3.41 KB
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
module sdk_gemini
import os
import json
import structs
import net.http
import log
pub struct GeminiSDK {
pub:
api_key string
}
const base_url = 'https://generativelanguage.googleapis.com/v1beta/models'
// get_api_key Reads an Gemini API key from an environment variable.
pub fn get_api_key(key_var string) !string {
api_key := os.getenv(key_var)
if api_key == '' {
return structs.KeyEmptyError{}
}
if !api_key.starts_with('AIza') {
return structs.KeySequenceError{}
}
return api_key
}
// new Returns a GeminiSDK.
pub fn new(api_key string) GeminiSDK {
return GeminiSDK{
api_key: api_key
}
}
// completation Sends a request to the Gemini API and returns the response or an error.
// Log level 'debug' logs the full model response body in case of an error occuring.
pub fn (mut sdk GeminiSDK) completation(model structs.Models, req_payload structs.GeminiRequest) !structs.GeminiResponse {
url := '${base_url}/${model}:generateContent?key=${sdk.api_key}'
payload := if model.is_gemma() {
req_payload_addapted := adapt_to_gemma(req_payload)
json.encode(req_payload_addapted)
} else {
json.encode(req_payload)
}
mut req := http.new_request(.post, url, payload)
req.header.set(.content_type, 'application/json')
resp := req.do()!
match resp.status_code {
400 {
log.debug(resp.body)
return structs.InvalidPayloadError{}
}
429 {
log.debug(resp.body)
return structs.ExceededQuotaError{}
}
503 {
log.debug(resp.body)
return structs.ModelOverloadedError{}
}
else {
if resp.status_code != 200 {
log.debug(resp.body)
return structs.UnknownResponseError{
code: resp.status_code
}
}
}
}
decoded := json.decode(structs.GeminiResponse, resp.body)!
return decoded
}
// adapt_to_gemma Adapts a GeminiRequest to the Gemma model.
// Gemma models do not support system instructions.
// This function moves the system instruction to the first content part.
fn adapt_to_gemma(req_payload structs.GeminiRequest) structs.GeminiRequest {
mut req_payload_addapted := req_payload
if req_payload_addapted.system_instruction != none {
mut contents := []structs.Content{}
for i, curr_content in req_payload_addapted.contents {
if i == 0 {
mut parts := curr_content.parts.clone()
parts << req_payload_addapted.system_instruction.parts
contents << structs.Content{
role: .user
parts: parts
}
} else {
contents << curr_content
}
}
req_payload_addapted = structs.GeminiRequest{
...req_payload_addapted
contents: contents
system_instruction: none
}
}
return req_payload_addapted
}
// send_prompt Sends a prompt to the Gemini API and returns the model's response.
pub fn (mut sdk GeminiSDK) send_prompt(model structs.Models, prompt string, system_instruction string) !structs.GeminiResponse {
// Criar as partes do conteúdo
user_part := structs.Part{
text: prompt
}
user_content := structs.Content{
role: .user
parts: [user_part]
}
mut sys_instruction := structs.SystemInstruction{}
if system_instruction != '' {
sys_part := structs.Part{
text: system_instruction
}
sys_instruction = structs.SystemInstruction{
parts: [sys_part]
}
}
gen_config := structs.GenerationConfig{
temperature: 0.7
max_output_tokens: 1024
}
request := structs.GeminiRequest{
contents: [user_content]
system_instruction: sys_instruction
generation_config: gen_config
}
return sdk.completation(model, request)
}