diff options
| author | Jeff Carr <[email protected]> | 2025-08-30 14:42:57 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-08-30 14:42:57 -0500 |
| commit | 7f8f5e3b9b37fccbb357b70e6490823a8b22ae7e (patch) | |
| tree | 11b6f74e8d3f33b3fdb82421cb79653f65685fe8 /json.go | |
| parent | c971bfddf74d48d87f10f5f050b1eef3fd12bf20 (diff) | |
basic JSON parsing into genai struc
Diffstat (limited to 'json.go')
| -rw-r--r-- | json.go | 134 |
1 files changed, 134 insertions, 0 deletions
@@ -0,0 +1,134 @@ +package main + +import ( + "encoding/json" + "os" + + "go.wit.com/log" + "google.golang.org/genai" +) + +// GeminiRequest matches the overall structure of the gemini-cli JSON output. +type GeminiRequest struct { + Model string `json:"model"` + Contents []Content `json:"contents"` + // Config is left as a raw message because its structure is complex and not needed for now. + Config json.RawMessage `json:"config"` +} + +// Content matches the 'contents' array elements. +type Content struct { + Role string `json:"role"` + Parts []Part `json:"parts"` +} + +// Part matches the 'parts' array elements. +// It can contain one of several types of data. +type Part struct { + Text string `json:"text,omitempty"` + ThoughtSignature string `json:"thoughtSignature,omitempty"` + FunctionCall *FunctionCall `json:"functionCall,omitempty"` + FunctionResponse *FunctionResponse `json:"functionResponse,omitempty"` +} + +// FunctionCall matches the 'functionCall' object. +type FunctionCall struct { + Name string `json:"name"` + Args map[string]string `json:"args"` +} + +// FunctionResponse matches the 'functionResponse' object. +type FunctionResponse struct { + ID string `json:"id"` + Name string `json:"name"` + Response map[string]interface{} `json:"response"` +} + +// parseJSON opens the given file, reads it, and unmarshals it into our structs. +func parseJSON(filename string) (*GeminiRequest, error) { + log.Infof("Attempting to parse file: %s\n", filename) + + // Read the entire file + data, err := os.ReadFile(filename) + if err != nil { + return nil, log.Errorf("failed to read file %s: %w", filename, err) + } + + // Unmarshal the JSON data + var req *GeminiRequest + req = new(GeminiRequest) + if err := json.Unmarshal(data, &req); err != nil { + return nil, log.Errorf("failed to unmarshal JSON from %s: %w", filename, err) + } + + dumpSummaryJSON(req) + return req, nil +} + +func dumpSummaryJSON(req *GeminiRequest) { + var totalFC, totalTexts, totalFR int + + // Log the parsed data to confirm it worked + + // Example of accessing deeper data + for _, content := range req.Contents { + // log.Infof("Content[%d] Role: %s", i, content.Role) + for _, part := range content.Parts { + if part.Text != "" { + // log.Infof(" Part[%d] Text: %.60s...", j, part.Text) // Print snippet + totalTexts += 1 + } + if part.FunctionCall != nil { + // log.Infof(" Part[%d] FunctionCall: %s", j, part.FunctionCall.Name) + totalFC += 1 + } + if part.FunctionResponse != nil { + // log.Infof(" Part[%d] FunctionCall: %s", j, part.FunctionCall.Name) + totalFR += 1 + } + } + } + log.Printf("Parsed JSON (Model: %s) (# of content blocks %d) (Text #=%d) (FC=%d) (FR=%d)\n", req.Model, len(req.Contents), totalTexts, totalFC, totalFR) +} + +func dumpFullJSON(req *GeminiRequest) { + // Log the parsed data to confirm it worked + log.Info("Successfully parsed JSON file.") + log.Infof("Model: %s", req.Model) + log.Infof("Number of content blocks: %d", len(req.Contents)) + + // Example of accessing deeper data + for i, content := range req.Contents { + log.Infof("Content[%d] Role: %s", i, content.Role) + for j, part := range content.Parts { + if part.Text != "" { + log.Infof(" Part[%d] Text: %.60s...", j, part.Text) // Print snippet + } + if part.FunctionCall != nil { + log.Infof(" Part[%d] FunctionCall: %s", j, part.FunctionCall.Name) + } + } + } +} + +// 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 +} |
