attempts to submit data to the Gemini API

This commit is contained in:
Jeff Carr 2025-09-01 00:29:48 -05:00
parent eba85c6b97
commit 4a800a7cfd
10 changed files with 138 additions and 72 deletions

View File

@ -2,7 +2,7 @@ VERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d_%H%M)
default: install
regex --json tmp/regex.bf203df1-ce24-42ea-93e9-10e0d8b5e8b0.gemini-api-request.64.json
regex playback
vet:
@GO111MODULE=off go vet

View File

@ -27,9 +27,11 @@ type EmptyCmd struct {
}
type PlaybackCmd struct {
List *EmptyCmd `arg:"subcommand:list" help:"list memories"`
Long *EmptyCmd `arg:"subcommand:long" help:"show info on each chat"`
Purge *EmptyCmd `arg:"subcommand:purge" help:"verify chat uuids & purge empty chats"`
Last *EmptyCmd `arg:"subcommand:last" help:"dump the last one"`
List *EmptyCmd `arg:"subcommand:list" help:"list memories"`
Long *EmptyCmd `arg:"subcommand:long" help:"show info on each chat"`
Purge *EmptyCmd `arg:"subcommand:purge" help:"verify chat uuids & purge empty chats"`
Submit *EmptyCmd `arg:"subcommand:submit" help:"convert and submit the last entry"`
}
func (args) Version() string {

View File

@ -24,7 +24,7 @@ func (args) doBashAuto() {
// argv.doBashHelp()
switch argv.BashAuto[0] {
case "playback":
fmt.Println("long --uuid purge")
fmt.Println("long --uuid purge last submit")
case "clean":
fmt.Println("user devel master")
default:

28
convertToGenai.go Normal file
View File

@ -0,0 +1,28 @@
package main
import (
"go.wit.com/lib/protobuf/chatpb"
"google.golang.org/genai"
)
// convertToGenai transforms the parsed JSON request into the genai.Content format.
func convertToGenai(req *chatpb.GeminiRequest) ([]*genai.Content, error) {
var contents []*genai.Content
for _, c := range req.Contents {
genaiParts := []*genai.Part{} // Create a slice of the interface type
for _, p := range c.Parts {
if p.Text != "" {
// genai.Text returns a Part interface, which is what we need
var tmp *genai.Part
tmp = new(genai.Part)
tmp.Text = p.Text
genaiParts = append(genaiParts, tmp)
}
}
contents = append(contents, &genai.Content{
Role: c.Role,
Parts: genaiParts,
})
}
return contents, nil
}

View File

@ -10,25 +10,25 @@ import (
)
// doConnect initializes the Gemini client and handles the request flow.
func doConnect() (*genai.Client, error) {
func doConnect() error {
apiKey := os.Getenv("GEMINI_API_KEY")
if apiKey == "" {
return nil, log.Errorf("GEMINI_API_KEY environment variable not set")
return log.Errorf("GEMINI_API_KEY environment variable not set")
}
ctx := context.Background()
client, err := genai.NewClient(ctx, &genai.ClientConfig{APIKey: apiKey})
me.ctx = context.Background()
var err error
me.client, err = genai.NewClient(me.ctx, &genai.ClientConfig{APIKey: apiKey})
if err != nil {
return nil, log.Errorf("failed to create new genai client: %w", err)
return log.Errorf("failed to create new genai client: %w", err)
}
return client, err
return nil
}
// sampleHello sends a hardcoded prompt to the model and prints the response.
func simpleHello(client *genai.Client) error {
func simpleHello() error {
log.Info("Sending 'hello, how are you' to the Gemini API...")
ctx := context.Background()
// Create the parts slice
parts := []*genai.Part{
@ -37,7 +37,24 @@ func simpleHello(client *genai.Client) error {
content := []*genai.Content{{Parts: parts}}
resp, err := client.Models.GenerateContent(ctx, "gemini-2.5-flash", content, nil)
resp, err := me.client.Models.GenerateContent(me.ctx, "gemini-2.5-flash", content, nil)
if err != nil {
return log.Errorf("error sending message: %v", err)
}
log.Info("Response from API:")
for _, cand := range resp.Candidates {
if cand.Content != nil {
for _, part := range cand.Content.Parts {
fmt.Println(part)
}
}
}
return nil
}
func submitChat(content []*genai.Content) error {
resp, err := me.client.Models.GenerateContent(me.ctx, "gemini-2.5-flash", content, nil)
if err != nil {
return log.Errorf("error sending message: %v", err)
}

43
doJSON.go Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0
package main
// An app to submit patches for the 30 GO GUI repos
import (
"path/filepath"
"strconv"
"strings"
"go.wit.com/lib/protobuf/chatpb"
"go.wit.com/log"
)
func doJSON() {
// now try to Marshal() into a protobuf
pb, err := parsePB(argv.JsonFile)
if err != nil {
badExit(err)
}
log.Info("GeminiContent pb.Marshal() worked pb.Contents len =", len(pb.Contents))
_, filename := filepath.Split(argv.JsonFile)
parts := strings.Split(filename, ".")
if len(parts) == 5 {
uuid := parts[1]
num, _ := strconv.Atoi(parts[3])
log.Info(uuid, parts)
if chat := me.chats.FindByUuid(uuid); chat != nil {
log.Info("FOUND CHAT", uuid, num)
newEntry := new(chatpb.ChatEntry)
newEntry.GeminiRequest = pb
newEntry.ContentFile = filename
newEntry.RequestCounter = int32(num)
chat.AppendEntry(newEntry)
me.chats.ConfigSave()
}
} else {
}
okExit("")
}

View File

@ -9,10 +9,31 @@ func dumpEntry(entry *chatpb.ChatEntry) {
log.Printf(entry.FormatTEXT())
}
func dumpchat(chat *chatpb.Chat) {
func dumpchat(chat *chatpb.Chat) error {
entries := chat.GetEntries()
var lastEntry *chatpb.ChatEntry
if len(entries) > 0 {
lastEntry := entries[len(entries)-1]
lastEntry = entries[len(entries)-1]
} else {
return log.Errorf("no entries")
}
if argv.Playback.Last != nil {
dumpEntry(lastEntry)
}
if argv.Playback.Submit != nil {
if lastEntry.GeminiRequest == nil {
return log.Errorf("lastEntry.GeminiRequest == nil")
}
aichat, err := convertToGenai(lastEntry.GeminiRequest)
if err != nil {
log.Info("convertToGenai() returned with error", err)
return err
}
err = submitChat(aichat)
if err != nil {
log.Info("submitChat() returned with error", err)
return err
}
}
return nil
}

23
json.go
View File

@ -6,7 +6,6 @@ import (
"go.wit.com/lib/protobuf/chatpb"
"go.wit.com/log"
"google.golang.org/genai"
)
// GeminiRequest matches the overall structure of the gemini-cli JSON output.
@ -124,25 +123,3 @@ func dumpFullJSON(req *GeminiRequest) {
}
}
}
// convertToGenai transforms the parsed JSON request into the genai.Content format.
func convertToGenai(req *GeminiRequest) ([]*genai.Content, error) {
var contents []*genai.Content
for _, c := range req.Contents {
genaiParts := []*genai.Part{} // Create a slice of the interface type
for _, p := range c.Parts {
if p.Text != "" {
// genai.Text returns a Part interface, which is what we need
var tmp *genai.Part
tmp = new(genai.Part)
tmp.Text = p.Text
genaiParts = append(genaiParts, tmp)
}
}
contents = append(contents, &genai.Content{
Role: c.Role,
Parts: genaiParts,
})
}
return contents, nil
}

33
main.go
View File

@ -8,9 +8,6 @@ package main
import (
"embed"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/google/uuid"
"go.wit.com/dev/alexflint/arg"
@ -61,43 +58,19 @@ func main() {
me.chats.ConfigSave()
}
aiClient, err := doConnect()
err := doConnect()
if err != nil {
badExit(err)
}
_ = aiClient
if argv.JsonFile != "" {
// now try to Marshal() into a protobuf
pb, err := parsePB(argv.JsonFile)
if err != nil {
badExit(err)
}
log.Info("GeminiContent pb.Marshal() worked pb.Contents len =", len(pb.Contents))
_, filename := filepath.Split(argv.JsonFile)
parts := strings.Split(filename, ".")
if len(parts) == 5 {
uuid := parts[1]
num, _ := strconv.Atoi(parts[3])
log.Info(uuid, parts)
if chat := me.chats.FindByUuid(uuid); chat != nil {
log.Info("FOUND CHAT", uuid, num)
newEntry := new(chatpb.ChatEntry)
newEntry.GeminiRequest = pb
newEntry.ContentFile = filename
newEntry.RequestCounter = int32(num)
chat.AppendEntry(newEntry)
me.chats.ConfigSave()
}
} else {
}
doJSON()
okExit("")
}
if argv.Interact != nil {
log.Info("testing AI client with simpleHello()")
err = simpleHello(aiClient)
err = simpleHello()
if err != nil {
badExit(err)
}

View File

@ -4,16 +4,21 @@
package main
import (
"context"
"go.wit.com/dev/alexflint/arg"
"go.wit.com/gui"
"go.wit.com/lib/protobuf/chatpb"
"google.golang.org/genai"
)
var me *mainType
// this app's variables
type mainType struct {
pp *arg.Parser // for parsing the command line args. Yay to alexf lint!
chats *chatpb.Chats // all our prior conversations with regex
myGui *gui.Node // the gui toolkit handle
pp *arg.Parser // for parsing the command line args. Yay to alexf lint!
chats *chatpb.Chats // all our prior conversations with regex
myGui *gui.Node // the gui toolkit handle
client *genai.Client // the Google Gemini AI client variable
ctx context.Context
}