...
This commit is contained in:
70
examples/aiexamples/groq.vsh
Executable file
70
examples/aiexamples/groq.vsh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
module main
|
||||
|
||||
import freeflowuniverse.herolib.clients.openai
|
||||
import os
|
||||
|
||||
|
||||
fn test1(mut client openai.OpenAI)!{
|
||||
|
||||
// Create a chat completion request
|
||||
res := client.chat_completion(msgs:openai.Messages{
|
||||
messages: [
|
||||
openai.Message{
|
||||
role: .user
|
||||
content: 'What are the key differences between Groq and other AI inference providers?'
|
||||
},
|
||||
]
|
||||
})!
|
||||
|
||||
// Print the response
|
||||
println('\nGroq AI Response:')
|
||||
println('==================')
|
||||
println(res.choices[0].message.content)
|
||||
println('\nUsage Statistics:')
|
||||
println('Prompt tokens: ${res.usage.prompt_tokens}')
|
||||
println('Completion tokens: ${res.usage.completion_tokens}')
|
||||
println('Total tokens: ${res.usage.total_tokens}')
|
||||
|
||||
}
|
||||
|
||||
|
||||
fn test2(mut client openai.OpenAI)!{
|
||||
|
||||
// Create a chat completion request
|
||||
res := client.chat_completion(
|
||||
model:"deepseek-r1-distill-llama-70b",
|
||||
msgs:openai.Messages{
|
||||
messages: [
|
||||
openai.Message{
|
||||
role: .user
|
||||
content: 'A story of 10 lines?'
|
||||
},
|
||||
]
|
||||
})!
|
||||
|
||||
println('\nGroq AI Response:')
|
||||
println('==================')
|
||||
println(res.choices[0].message.content)
|
||||
println('\nUsage Statistics:')
|
||||
println('Prompt tokens: ${res.usage.prompt_tokens}')
|
||||
println('Completion tokens: ${res.usage.completion_tokens}')
|
||||
println('Total tokens: ${res.usage.total_tokens}')
|
||||
|
||||
}
|
||||
|
||||
|
||||
println('
|
||||
TO USE:
|
||||
export AIKEY=\'gsk_...\'
|
||||
export AIURL=\'https://api.groq.com/openai/v1\'
|
||||
export AIMODEL=\'llama-3.3-70b-versatile\'
|
||||
')
|
||||
|
||||
mut client:=openai.get(name:"test")!
|
||||
println(client)
|
||||
|
||||
|
||||
// test1(mut client)!
|
||||
test2(mut client)!
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.clients.jina
|
||||
import freeflowuniverse.herolib.osal
|
||||
import os
|
||||
|
||||
// Example of using the Jina client
|
||||
|
||||
fn main() {
|
||||
// Set environment variable for testing
|
||||
// In production, you would set this in your environment
|
||||
// osal.env_set(key: 'JINAKEY', value: 'your-api-key')
|
||||
|
||||
// Check if JINAKEY environment variable exists
|
||||
if !osal.env_exists('JINAKEY') {
|
||||
println('JINAKEY environment variable not set. Please set it before running this example.')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Create a Jina client instance
|
||||
mut client := jina.get(name: 'default')!
|
||||
|
||||
println('Jina client initialized successfully.')
|
||||
|
||||
// Example: Create embeddings
|
||||
model := 'jina-embeddings-v3'
|
||||
texts := ['Hello, world!', 'How are you doing?']
|
||||
|
||||
println('Creating embeddings for texts: ${texts}')
|
||||
result := client.create_embeddings(texts, model, 'retrieval.query')!
|
||||
|
||||
println('Embeddings created successfully.')
|
||||
println('Model: ${result['model']}')
|
||||
println('Data count: ${result['data'].arr().len}')
|
||||
|
||||
// Example: List classifiers
|
||||
println('\nListing classifiers:')
|
||||
classifiers := client.list_classifiers() or {
|
||||
println('Failed to list classifiers: ${err}')
|
||||
return
|
||||
}
|
||||
|
||||
println('Classifiers retrieved successfully.')
|
||||
|
||||
// Example: Create a classifier
|
||||
println('\nTraining a classifier:')
|
||||
examples := [
|
||||
jina.TrainingExample{
|
||||
text: 'This movie was great!'
|
||||
label: 'positive'
|
||||
},
|
||||
jina.TrainingExample{
|
||||
text: 'I did not like this movie.'
|
||||
label: 'negative'
|
||||
},
|
||||
jina.TrainingExample{
|
||||
text: 'The movie was okay.'
|
||||
label: 'neutral'
|
||||
},
|
||||
]
|
||||
|
||||
training_result := client.train(examples, model, 'private') or {
|
||||
println('Failed to train classifier: ${err}')
|
||||
return
|
||||
}
|
||||
|
||||
println('Classifier trained successfully.')
|
||||
println('Classifier ID: ${training_result['classifier_id']}')
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.clients.qdrant
|
||||
import freeflowuniverse.herolib.installers.db.qdrant as qdrant_installer
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import rand
|
||||
|
||||
mut i:=qdrant_installer.get()!
|
||||
i.install()!
|
||||
|
||||
// 1. Get the qdrant client
|
||||
mut qdrant_client := qdrant.get()!
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export GROQ_API_KEY="your-groq-api-key-here"
|
||||
@@ -1,64 +0,0 @@
|
||||
# Groq AI Client Example
|
||||
|
||||
This example demonstrates how to use Groq's AI API with the herolib OpenAI client. Groq provides API compatibility with OpenAI's client libraries, allowing you to leverage Groq's fast inference speeds with minimal changes to your existing code.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- V programming language installed
|
||||
- A Groq API key (get one from [Groq's website](https://console.groq.com/keys))
|
||||
|
||||
## Setup
|
||||
|
||||
1. Copy the `.env.example` file to `.env`:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. Edit the `.env` file and replace `your-groq-api-key-here` with your actual Groq API key.
|
||||
|
||||
3. Load the environment variables:
|
||||
|
||||
```bash
|
||||
source .env
|
||||
```
|
||||
|
||||
## Running the Example
|
||||
|
||||
Execute the script with:
|
||||
|
||||
```bash
|
||||
v run groq_client.vsh
|
||||
```
|
||||
|
||||
Or make it executable first:
|
||||
|
||||
```bash
|
||||
chmod +x groq_client.vsh
|
||||
./groq_client.vsh
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
The example uses the existing OpenAI client from herolib but configures it to use Groq's API endpoint:
|
||||
|
||||
1. It retrieves the Groq API key from the environment variables
|
||||
2. Configures the OpenAI client with the Groq API key
|
||||
3. Overrides the default OpenAI URL with Groq's API URL (`https://api.groq.com/openai/v1`)
|
||||
4. Sends a chat completion request to Groq's API
|
||||
5. Displays the response
|
||||
|
||||
## Supported Models
|
||||
|
||||
Groq supports various models including:
|
||||
|
||||
- llama2-70b-4096
|
||||
- mixtral-8x7b-32768
|
||||
- gemma-7b-it
|
||||
|
||||
For a complete and up-to-date list of supported models, refer to the [Groq API documentation](https://console.groq.com/docs/models).
|
||||
|
||||
## Notes
|
||||
|
||||
- The example uses the `gpt_3_5_turbo` enum from the OpenAI client, but Groq will automatically map this to an appropriate model on their end.
|
||||
- For production use, you may want to explicitly specify one of Groq's supported models.
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
module main
|
||||
|
||||
import freeflowuniverse.herolib.clients.openai
|
||||
import os
|
||||
|
||||
fn main() {
|
||||
// Get API key from environment variable
|
||||
key := os.getenv('GROQ_API_KEY')
|
||||
if key == '' {
|
||||
println('Error: GROQ_API_KEY environment variable not set')
|
||||
println('Please set it by running: source .env')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
// Get the configured client
|
||||
mut client := openai.OpenAI{
|
||||
name: 'groq'
|
||||
api_key: key
|
||||
server_url: 'https://api.groq.com/openai/v1'
|
||||
}
|
||||
|
||||
// Define the model and message for chat completion
|
||||
// Note: Use a model that Groq supports, like llama2-70b-4096 or mixtral-8x7b-32768
|
||||
model := 'qwen-2.5-coder-32b'
|
||||
|
||||
// Create a chat completion request
|
||||
res := client.chat_completion(model, openai.Messages{
|
||||
messages: [
|
||||
openai.Message{
|
||||
role: .user
|
||||
content: 'What are the key differences between Groq and other AI inference providers?'
|
||||
},
|
||||
]
|
||||
})!
|
||||
|
||||
// Print the response
|
||||
println('\nGroq AI Response:')
|
||||
println('==================')
|
||||
println(res.choices[0].message.content)
|
||||
println('\nUsage Statistics:')
|
||||
println('Prompt tokens: ${res.usage.prompt_tokens}')
|
||||
println('Completion tokens: ${res.usage.completion_tokens}')
|
||||
println('Total tokens: ${res.usage.total_tokens}')
|
||||
}
|
||||
12
install_v.sh
12
install_v.sh
@@ -446,9 +446,12 @@ v-install() {
|
||||
|
||||
v-analyzer() {
|
||||
|
||||
set -ex
|
||||
|
||||
# Install v-analyzer if requested
|
||||
if [ "$INSTALL_ANALYZER" = true ]; then
|
||||
echo "Installing v-analyzer..."
|
||||
cd /tmp
|
||||
v download -RD https://raw.githubusercontent.com/vlang/v-analyzer/main/install.vsh
|
||||
|
||||
# Check if v-analyzer bin directory exists
|
||||
@@ -517,10 +520,7 @@ if [ "$RESET" = true ] || ! command_exists v; then
|
||||
|
||||
v-install
|
||||
|
||||
# Only install v-analyzer if not in GitHub Actions environment
|
||||
if ! is_github_actions; then
|
||||
v-analyzer
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
@@ -534,6 +534,10 @@ fi
|
||||
|
||||
|
||||
if [ "$INSTALL_ANALYZER" = true ]; then
|
||||
# Only install v-analyzer if not in GitHub Actions environment
|
||||
if ! is_github_actions; then
|
||||
v-analyzer
|
||||
fi
|
||||
echo "Run 'source ~/.bashrc' or 'source ~/.zshrc' to update PATH for v-analyzer"
|
||||
fi
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ fn (mut f OpenAI) create_audio_request(args AudioArgs, endpoint string) !AudioRe
|
||||
@[params]
|
||||
pub struct CreateSpeechArgs {
|
||||
pub:
|
||||
model ModelType = .tts_1
|
||||
model string = "tts_1"
|
||||
input string @[required]
|
||||
voice Voice = .alloy
|
||||
response_format AudioFormat = .mp3
|
||||
@@ -135,7 +135,7 @@ pub fn (mut f OpenAI) create_speech(args CreateSpeechArgs) ! {
|
||||
mut output_file := os.open_file(args.output_path, 'w+')!
|
||||
|
||||
req := CreateSpeechRequest{
|
||||
model: modelname_str(args.model)
|
||||
model: args.model
|
||||
input: args.input
|
||||
voice: voice_str(args.voice)
|
||||
response_format: audio_format_str(args.response_format)
|
||||
|
||||
@@ -3,14 +3,15 @@ module openai
|
||||
import os
|
||||
|
||||
fn test_chat_completion() {
|
||||
key := os.getenv('OPENAI_API_KEY')
|
||||
heroscript := '!!openai.configure api_key: "${key}"'
|
||||
|
||||
play(heroscript: heroscript)!
|
||||
|
||||
mut client := get()!
|
||||
|
||||
res := client.chat_completion(.gpt_4o_2024_08_06.str(), Messages{
|
||||
client.model_default = 'llama-3.3-70b-versatile'
|
||||
|
||||
println(client.list_models()!)
|
||||
|
||||
raise("sss")
|
||||
|
||||
res := client.chat_completion( Messages{
|
||||
messages: [
|
||||
Message{
|
||||
role: .user
|
||||
@@ -24,82 +25,82 @@ fn test_chat_completion() {
|
||||
assert res.choices[0].message.content == 'AI is getting out of hand'
|
||||
}
|
||||
|
||||
fn test_embeddings() {
|
||||
key := os.getenv('OPENAI_API_KEY')
|
||||
heroscript := '!!openai.configure api_key: "${key}"'
|
||||
// fn test_embeddings() {
|
||||
// key := os.getenv('OPENAI_API_KEY')
|
||||
// heroscript := '!!openai.configure api_key: "${key}"'
|
||||
|
||||
play(heroscript: heroscript)!
|
||||
// play(heroscript: heroscript)!
|
||||
|
||||
mut client := get()!
|
||||
// mut client := get()!
|
||||
|
||||
res := client.create_embeddings(
|
||||
input: ['The food was delicious and the waiter..']
|
||||
model: .text_embedding_ada
|
||||
)!
|
||||
// res := client.create_embeddings(
|
||||
// input: ['The food was delicious and the waiter..']
|
||||
// model: .text_embedding_ada
|
||||
// )!
|
||||
|
||||
assert res.data.len == 1
|
||||
assert res.data[0].embedding.len == 1536
|
||||
}
|
||||
// assert res.data.len == 1
|
||||
// assert res.data[0].embedding.len == 1536
|
||||
// }
|
||||
|
||||
fn test_files() {
|
||||
key := os.getenv('OPENAI_API_KEY')
|
||||
heroscript := '!!openai.configure api_key: "${key}"'
|
||||
// fn test_files() {
|
||||
// key := os.getenv('OPENAI_API_KEY')
|
||||
// heroscript := '!!openai.configure api_key: "${key}"'
|
||||
|
||||
play(heroscript: heroscript)!
|
||||
// play(heroscript: heroscript)!
|
||||
|
||||
mut client := get()!
|
||||
uploaded_file := client.upload_file(
|
||||
filepath: '${os.dir(@FILE) + '/testdata/testfile.txt'}'
|
||||
purpose: .assistants
|
||||
)!
|
||||
// mut client := get()!
|
||||
// uploaded_file := client.upload_file(
|
||||
// filepath: '${os.dir(@FILE) + '/testdata/testfile.txt'}'
|
||||
// purpose: .assistants
|
||||
// )!
|
||||
|
||||
assert uploaded_file.filename == 'testfile.txt'
|
||||
assert uploaded_file.purpose == 'assistants'
|
||||
// assert uploaded_file.filename == 'testfile.txt'
|
||||
// assert uploaded_file.purpose == 'assistants'
|
||||
|
||||
got_file := client.get_file(uploaded_file.id)!
|
||||
assert got_file == uploaded_file
|
||||
// got_file := client.get_file(uploaded_file.id)!
|
||||
// assert got_file == uploaded_file
|
||||
|
||||
uploaded_file2 := client.upload_file(
|
||||
filepath: '${os.dir(@FILE) + '/testdata/testfile2.txt'}'
|
||||
purpose: .assistants
|
||||
)!
|
||||
// uploaded_file2 := client.upload_file(
|
||||
// filepath: '${os.dir(@FILE) + '/testdata/testfile2.txt'}'
|
||||
// purpose: .assistants
|
||||
// )!
|
||||
|
||||
assert uploaded_file2.filename == 'testfile2.txt'
|
||||
assert uploaded_file2.purpose == 'assistants'
|
||||
// assert uploaded_file2.filename == 'testfile2.txt'
|
||||
// assert uploaded_file2.purpose == 'assistants'
|
||||
|
||||
mut got_list := client.list_files()!
|
||||
// mut got_list := client.list_files()!
|
||||
|
||||
assert got_list.data.len >= 2 // there could be other older files
|
||||
// assert got_list.data.len >= 2 // there could be other older files
|
||||
|
||||
mut ids := []string{}
|
||||
for file in got_list.data {
|
||||
ids << file.id
|
||||
}
|
||||
// mut ids := []string{}
|
||||
// for file in got_list.data {
|
||||
// ids << file.id
|
||||
// }
|
||||
|
||||
assert uploaded_file.id in ids
|
||||
assert uploaded_file2.id in ids
|
||||
// assert uploaded_file.id in ids
|
||||
// assert uploaded_file2.id in ids
|
||||
|
||||
for file in got_list.data {
|
||||
client.delete_file(file.id)!
|
||||
}
|
||||
// for file in got_list.data {
|
||||
// client.delete_file(file.id)!
|
||||
// }
|
||||
|
||||
got_list = client.list_files()!
|
||||
assert got_list.data.len == 0
|
||||
}
|
||||
// got_list = client.list_files()!
|
||||
// assert got_list.data.len == 0
|
||||
// }
|
||||
|
||||
fn test_audio() {
|
||||
key := os.getenv('OPENAI_API_KEY')
|
||||
heroscript := '!!openai.configure api_key: "${key}"'
|
||||
// fn test_audio() {
|
||||
// key := os.getenv('OPENAI_API_KEY')
|
||||
// heroscript := '!!openai.configure api_key: "${key}"'
|
||||
|
||||
play(heroscript: heroscript)!
|
||||
// play(heroscript: heroscript)!
|
||||
|
||||
mut client := get()!
|
||||
// mut client := get()!
|
||||
|
||||
// create speech
|
||||
client.create_speech(
|
||||
input: 'the quick brown fox jumps over the lazy dog'
|
||||
output_path: '/tmp/output.mp3'
|
||||
)!
|
||||
// // create speech
|
||||
// client.create_speech(
|
||||
// input: 'the quick brown fox jumps over the lazy dog'
|
||||
// output_path: '/tmp/output.mp3'
|
||||
// )!
|
||||
|
||||
assert os.exists('/tmp/output.mp3')
|
||||
}
|
||||
// assert os.exists('/tmp/output.mp3')
|
||||
// }
|
||||
|
||||
@@ -48,13 +48,25 @@ mut:
|
||||
messages []MessageRaw
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct CompletionArgs{
|
||||
pub mut:
|
||||
model string
|
||||
msgs Messages
|
||||
|
||||
}
|
||||
|
||||
// creates a new chat completion given a list of messages
|
||||
// each message consists of message content and the role of the author
|
||||
pub fn (mut f OpenAI) chat_completion(model_type string, msgs Messages) !ChatCompletion {
|
||||
mut m := ChatMessagesRaw{
|
||||
model: model_type
|
||||
pub fn (mut f OpenAI) chat_completion(args_ CompletionArgs) !ChatCompletion {
|
||||
mut args:=args_
|
||||
if args.model==""{
|
||||
args.model = f.model_default
|
||||
}
|
||||
for msg in msgs.messages {
|
||||
mut m := ChatMessagesRaw{
|
||||
model: args.model
|
||||
}
|
||||
for msg in args.msgs.messages {
|
||||
mr := MessageRaw{
|
||||
role: roletype_str(msg.role)
|
||||
content: msg.content
|
||||
@@ -62,10 +74,10 @@ pub fn (mut f OpenAI) chat_completion(model_type string, msgs Messages) !ChatCom
|
||||
m.messages << mr
|
||||
}
|
||||
data := json.encode(m)
|
||||
println('data: ${data}')
|
||||
// println('data: ${data}')
|
||||
mut conn := f.connection()!
|
||||
r := conn.post_json_str(prefix: 'chat/completions', data: data)!
|
||||
println('res: ${r}')
|
||||
// println('res: ${r}')
|
||||
|
||||
res := json.decode(ChatCompletion, r)!
|
||||
return res
|
||||
|
||||
@@ -1,57 +1,5 @@
|
||||
module openai
|
||||
|
||||
pub enum ModelType {
|
||||
gpt_4o_2024_08_06
|
||||
gpt_3_5_turbo
|
||||
gpt_4
|
||||
gpt_4_0613
|
||||
gpt_4_32k
|
||||
gpt_4_32k_0613
|
||||
gpt_3_5_turbo_0613
|
||||
gpt_3_5_turbo_16k
|
||||
gpt_3_5_turbo_16k_0613
|
||||
whisper_1
|
||||
tts_1
|
||||
}
|
||||
|
||||
fn modelname_str(e ModelType) string {
|
||||
return match e {
|
||||
.tts_1 {
|
||||
'tts-1'
|
||||
}
|
||||
.gpt_4o_2024_08_06 {
|
||||
'gpt-4o-2024-08-06'
|
||||
}
|
||||
.gpt_4 {
|
||||
'gpt-4'
|
||||
}
|
||||
.gpt_3_5_turbo {
|
||||
'gpt-3.5-turbo'
|
||||
}
|
||||
.gpt_4_0613 {
|
||||
'gpt-4-0613'
|
||||
}
|
||||
.gpt_4_32k {
|
||||
'gpt-4-32k'
|
||||
}
|
||||
.gpt_4_32k_0613 {
|
||||
'gpt-4-32k-0613'
|
||||
}
|
||||
.gpt_3_5_turbo_0613 {
|
||||
'gpt-3.5-turbo-0613'
|
||||
}
|
||||
.gpt_3_5_turbo_16k {
|
||||
'gpt-3.5-turbo-16k'
|
||||
}
|
||||
.gpt_3_5_turbo_16k_0613 {
|
||||
'gpt-3.5-turbo-16k-0613'
|
||||
}
|
||||
.whisper_1 {
|
||||
'whisper-1'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum RoleType {
|
||||
system
|
||||
user
|
||||
|
||||
112
lib/clients/openai/openai_factory_.v
Normal file
112
lib/clients/openai/openai_factory_.v
Normal file
@@ -0,0 +1,112 @@
|
||||
module openai
|
||||
|
||||
import freeflowuniverse.herolib.core.base
|
||||
import freeflowuniverse.herolib.core.playbook
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
__global (
|
||||
openai_global map[string]&OpenAI
|
||||
openai_default string
|
||||
)
|
||||
|
||||
/////////FACTORY
|
||||
|
||||
@[params]
|
||||
pub struct ArgsGet {
|
||||
pub mut:
|
||||
name string
|
||||
}
|
||||
|
||||
fn args_get(args_ ArgsGet) ArgsGet {
|
||||
mut args := args_
|
||||
if args.name == '' {
|
||||
args.name = 'default'
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
pub fn get(args_ ArgsGet) !&OpenAI {
|
||||
mut context := base.context()!
|
||||
mut args := args_get(args_)
|
||||
mut obj := OpenAI{name:args.name}
|
||||
if args.name !in openai_global {
|
||||
if !exists(args)! {
|
||||
set(obj)!
|
||||
} else {
|
||||
heroscript := context.hero_config_get('openai', args.name)!
|
||||
mut obj_ := heroscript_loads(heroscript)!
|
||||
set_in_mem(obj_)!
|
||||
}
|
||||
}
|
||||
return openai_global[args.name] or {
|
||||
println(openai_global)
|
||||
// bug if we get here because should be in globals
|
||||
panic('could not get config for openai with name, is bug, was for: ${args.name}')
|
||||
}
|
||||
}
|
||||
|
||||
// register the config for the future
|
||||
pub fn set(o OpenAI) ! {
|
||||
set_in_mem(o)!
|
||||
mut context := base.context()!
|
||||
heroscript := heroscript_dumps(o)!
|
||||
context.hero_config_set('openai', o.name, heroscript)!
|
||||
}
|
||||
|
||||
// does the config exists?
|
||||
pub fn exists(args_ ArgsGet) !bool {
|
||||
mut context := base.context()!
|
||||
mut args := args_get(args_)
|
||||
return context.hero_config_exists('openai', args.name)
|
||||
}
|
||||
|
||||
pub fn delete(args_ ArgsGet) ! {
|
||||
mut args := args_get(args_)
|
||||
mut context := base.context()!
|
||||
context.hero_config_delete('openai', args.name)!
|
||||
if args.name in openai_global {
|
||||
// del openai_global[args.name]
|
||||
}
|
||||
}
|
||||
|
||||
// only sets in mem, does not set as config
|
||||
fn set_in_mem(o OpenAI) ! {
|
||||
mut o2 := obj_init(o)!
|
||||
openai_global[o.name] = &o2
|
||||
openai_default = o.name
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct PlayArgs {
|
||||
pub mut:
|
||||
heroscript string // if filled in then plbook will be made out of it
|
||||
plbook ?playbook.PlayBook
|
||||
reset bool
|
||||
}
|
||||
|
||||
pub fn play(args_ PlayArgs) ! {
|
||||
mut args := args_
|
||||
|
||||
mut plbook := args.plbook or { playbook.new(text: args.heroscript)! }
|
||||
|
||||
mut install_actions := plbook.find(filter: 'openai.configure')!
|
||||
if install_actions.len > 0 {
|
||||
for install_action in install_actions {
|
||||
heroscript := install_action.heroscript()
|
||||
mut obj2 := heroscript_loads(heroscript)!
|
||||
set(obj2)!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// switch instance to be used for openai
|
||||
pub fn switch(name string) {
|
||||
openai_default = name
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
@[params]
|
||||
pub struct DefaultConfigArgs {
|
||||
instance string = 'default'
|
||||
}
|
||||
93
lib/clients/openai/openai_model.v
Normal file
93
lib/clients/openai/openai_model.v
Normal file
@@ -0,0 +1,93 @@
|
||||
module openai
|
||||
|
||||
import freeflowuniverse.herolib.data.encoderhero
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import os
|
||||
|
||||
pub const version = '0.0.0'
|
||||
const singleton = false
|
||||
const default = true
|
||||
|
||||
// THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED
|
||||
|
||||
// @[heap]
|
||||
// pub struct OpenAIBase {
|
||||
// pub mut:
|
||||
// name string = 'default'
|
||||
// api_key string
|
||||
// url string
|
||||
// model_default string
|
||||
// }
|
||||
|
||||
@[heap]
|
||||
pub struct OpenAI {
|
||||
pub mut:
|
||||
name string = 'default'
|
||||
api_key string
|
||||
url string
|
||||
model_default string
|
||||
conn ?&httpconnection.HTTPConnection @[skip; str: skip]
|
||||
}
|
||||
|
||||
// your checking & initialization code if needed
|
||||
fn obj_init(mycfg_ OpenAI) !OpenAI {
|
||||
mut mycfg := mycfg_
|
||||
if mycfg.api_key==""{
|
||||
|
||||
mut k:=os.getenv('AIKEY')
|
||||
if k != ""{
|
||||
mycfg.api_key = k
|
||||
k=os.getenv('AIURL')
|
||||
if k != ""{
|
||||
mycfg.url = k
|
||||
}else{
|
||||
return error("found AIKEY in env, but not AIURL")
|
||||
}
|
||||
k=os.getenv('AIMODEL')
|
||||
if k != ""{
|
||||
mycfg.model_default = k
|
||||
}
|
||||
return mycfg
|
||||
}
|
||||
mycfg.url = "https://api.openai.com/v1/models"
|
||||
k=os.getenv('OPENAI_API_KEY')
|
||||
if k != ""{
|
||||
mycfg.api_key = k
|
||||
return mycfg
|
||||
}
|
||||
k=os.getenv('OPENROUTER_API_KEY')
|
||||
if k != ""{
|
||||
mycfg.api_key = k
|
||||
mycfg.url = "https://openrouter.ai/api/v1"
|
||||
return mycfg
|
||||
}
|
||||
}
|
||||
return mycfg
|
||||
}
|
||||
|
||||
pub fn (mut client OpenAI) connection() !&httpconnection.HTTPConnection {
|
||||
mut c := client.conn or {
|
||||
mut c2 := httpconnection.new(
|
||||
name: 'openaiconnection_${client.name}'
|
||||
url: client.url
|
||||
cache: false
|
||||
retry: 20
|
||||
)!
|
||||
c2
|
||||
}
|
||||
c.default_header.set(.authorization, 'Bearer ${client.api_key}')
|
||||
client.conn = c
|
||||
return c
|
||||
}
|
||||
|
||||
|
||||
/////////////NORMALLY NO NEED TO TOUCH
|
||||
|
||||
pub fn heroscript_dumps(obj OpenAI) !string {
|
||||
return encoderhero.encode[OpenAI](obj)!
|
||||
}
|
||||
|
||||
pub fn heroscript_loads(heroscript string) !OpenAI {
|
||||
mut obj := encoderhero.decode[OpenAI](heroscript)!
|
||||
return obj
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
module openai
|
||||
|
||||
import freeflowuniverse.herolib.data.paramsparser
|
||||
import freeflowuniverse.herolib.core.httpconnection
|
||||
import os
|
||||
|
||||
pub const version = '1.14.3'
|
||||
const singleton = false
|
||||
const default = true
|
||||
|
||||
// TODO: THIS IS EXAMPLE CODE AND NEEDS TO BE CHANGED IN LINE TO STRUCT BELOW, IS STRUCTURED AS HEROSCRIPT
|
||||
pub fn heroscript_default() !string {
|
||||
heroscript := "
|
||||
!!openai.configure
|
||||
name:'openai'
|
||||
api_key: ${os.getenv('OPENAI_API_KEY')}
|
||||
"
|
||||
|
||||
return heroscript
|
||||
}
|
||||
|
||||
// THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED
|
||||
|
||||
pub struct OpenAI {
|
||||
pub mut:
|
||||
name string = 'default'
|
||||
api_key string @[secret]
|
||||
server_url string
|
||||
conn ?&httpconnection.HTTPConnection
|
||||
}
|
||||
|
||||
// fn cfg_play(p paramsparser.Params) ! {
|
||||
// // THIS IS EXAMPLE CODE AND NEEDS TO BE CHANGED IN LINE WITH struct above
|
||||
// mut mycfg := OpenAI{
|
||||
// name: p.get_default('name', 'default')!
|
||||
// api_key: p.get('api_key')!
|
||||
// }
|
||||
// set(mycfg)!
|
||||
// }
|
||||
|
||||
fn obj_init(obj_ OpenAI) !OpenAI {
|
||||
// never call get here, only thing we can do here is work on object itself
|
||||
mut obj := obj_
|
||||
return obj
|
||||
}
|
||||
|
||||
pub fn (mut client OpenAI) connection() !&httpconnection.HTTPConnection {
|
||||
server_url := if client.server_url != '' {
|
||||
client.server_url
|
||||
} else {
|
||||
'https://api.openai.com/v1'
|
||||
}
|
||||
mut c := client.conn or {
|
||||
mut c2 := httpconnection.new(
|
||||
name: 'openaiconnection_${client.name}'
|
||||
url: server_url
|
||||
cache: false
|
||||
retry: 20
|
||||
)!
|
||||
c2
|
||||
}
|
||||
|
||||
c.default_header.set(.authorization, 'Bearer ${client.api_key}')
|
||||
|
||||
client.conn = c
|
||||
return c
|
||||
}
|
||||
@@ -20,8 +20,5 @@ client...
|
||||
## example heroscript
|
||||
|
||||
```hero
|
||||
!!openai.configure
|
||||
secret: '...'
|
||||
host: 'localhost'
|
||||
port: 8888
|
||||
!!openai.configure key
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@ fn args_get (args_ ArgsGet) ArgsGet {
|
||||
pub fn get(args_ ArgsGet) !&${args.classname} {
|
||||
mut context:=base.context()!
|
||||
mut args := args_get(args_)
|
||||
mut obj := ${args.classname}{}
|
||||
mut obj := ${args.classname}{name:args.name}
|
||||
if !(args.name in ${args.name}_global) {
|
||||
if ! exists(args)!{
|
||||
set(obj)!
|
||||
|
||||
@@ -43,22 +43,3 @@ config := mcp.ServerConfiguration{
|
||||
mut server := mcp.new_server(handlers, config)!
|
||||
server.start()!
|
||||
```
|
||||
|
||||
## Development Tools
|
||||
|
||||
The module includes several development tools accessible through the `v_do` directory:
|
||||
|
||||
- **test**: Run tests for V files
|
||||
- **run**: Execute V files
|
||||
- **compile**: Compile V files
|
||||
- **vet**: Perform static analysis on V files
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `freeflowuniverse.herolib.schemas.jsonrpc`: For JSON-RPC communication
|
||||
- `x.json2`: For JSON serialization/deserialization
|
||||
- Standard V libraries: `time`, `os`, `log`
|
||||
|
||||
## License
|
||||
|
||||
This module is part of the HeroLib project. See the project's license for more information.
|
||||
|
||||
@@ -56,6 +56,15 @@ pub fn env_get(key string) !string {
|
||||
return os.environ()[key]!
|
||||
}
|
||||
|
||||
pub fn env_exists(key string) !bool {
|
||||
k:=os.environ()
|
||||
if key in k{
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// Returns the requested environment variable if it exists or returns the provided default value if it does not
|
||||
pub fn env_get_default(key string, def string) string {
|
||||
return os.environ()[key] or { return def }
|
||||
|
||||
Reference in New Issue
Block a user