106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"inou/lib"
|
|
"os"
|
|
)
|
|
|
|
const summaryPrompt = `Analyze this medical document and extract structured data.
|
|
|
|
Respond with JSON only:
|
|
|
|
{
|
|
"document": {
|
|
"type": "consultation | lab_report | imaging_report | discharge_summary | prescription | other",
|
|
"specialty": "neurology | cardiology | ophthalmology | etc",
|
|
"date": "YYYY-MM-DD",
|
|
"patient_age_at_doc": "9 months | 3 years | etc",
|
|
"institution": "hospital or clinic name",
|
|
"provider": "doctor name",
|
|
"topics": ["searchable keywords"],
|
|
"summary": "1-2 sentences: what information is in this document (not conclusions)"
|
|
},
|
|
|
|
"events": [
|
|
// Things that happened at a point in time. Examples:
|
|
// - procedures, surgeries, device implants
|
|
// - hospitalizations
|
|
// - medications started/stopped/changed
|
|
// - lab tests and values
|
|
// - vital measurements
|
|
// - symptoms reported
|
|
// - therapy sessions
|
|
// - vaccinations
|
|
// - milestones (developmental)
|
|
// Include date/timeframe. Attribute opinions to provider.
|
|
],
|
|
|
|
"assessments": [
|
|
// Clinical opinions by providers. Another doctor might disagree.
|
|
// Always attribute: {"by": "Dr. X", "states": "..."}
|
|
// Diagnoses are assessments, not facts.
|
|
],
|
|
|
|
"attributes": {
|
|
// Characteristics of the person (extract if present):
|
|
// - birth: all birth-related info as one object
|
|
// - allergies: list
|
|
// - conditions: permanent states (deaf, diabetic, etc)
|
|
// - family_history: relevant family medical history
|
|
// - other attributes mentioned
|
|
},
|
|
|
|
"content": "Full document text converted to clean markdown. Preserve structure with headers."
|
|
}
|
|
|
|
Guidelines:
|
|
- Events: things that happened, with dates (even approximate: "May 2020", "at 3 months")
|
|
- Assessments: opinions attributed to provider, never stated as fact
|
|
- Attributes: characteristics of the person, flexible structure
|
|
- Content: full text as markdown for future reprocessing`
|
|
|
|
func main() {
|
|
if err := lib.CryptoInit("/tank/inou/master.key"); err != nil {
|
|
fmt.Fprintf(os.Stderr, "CryptoInit: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
lib.ConfigInit()
|
|
|
|
pdfPath := "/tank/inou/anastasiia-restored/documents/Консультация невролога.pdf"
|
|
pdfBytes, err := os.ReadFile(pdfPath)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "ReadFile: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
b64 := base64.StdEncoding.EncodeToString(pdfBytes)
|
|
parts := []lib.GeminiPart{
|
|
{Text: summaryPrompt},
|
|
{
|
|
InlineData: &lib.GeminiInlineData{
|
|
MimeType: "application/pdf",
|
|
Data: b64,
|
|
},
|
|
},
|
|
}
|
|
|
|
resp, err := lib.CallGeminiMultimodal(parts, nil)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Gemini: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Pretty print the JSON
|
|
var result map[string]interface{}
|
|
if err := json.Unmarshal([]byte(resp), &result); err != nil {
|
|
fmt.Println("Raw response:", resp)
|
|
return
|
|
}
|
|
|
|
pretty, _ := json.MarshalIndent(result, "", " ")
|
|
fmt.Println(string(pretty))
|
|
}
|