summaryrefslogtreecommitdiff
path: root/json.go
diff options
context:
space:
mode:
Diffstat (limited to 'json.go')
-rw-r--r--json.go134
1 files changed, 134 insertions, 0 deletions
diff --git a/json.go b/json.go
new file mode 100644
index 0000000..129046d
--- /dev/null
+++ b/json.go
@@ -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
+}