new table + translate call

This commit is contained in:
lehel 2025-10-08 15:08:35 +02:00
parent 77c0396623
commit 2bd7333233
No known key found for this signature in database
GPG Key ID: 9C4F9D6111EE5CFA
6 changed files with 51 additions and 0 deletions

View File

@ -8,6 +8,7 @@ type Config struct {
LLM struct {
ExtractKeywordsPrompt string `yaml:"extract_keywords_prompt"`
DisambiguatePrompt string `yaml:"disambiguate_prompt"`
TranslatePrompt string `yaml:"translate_prompt"`
} `yaml:"llm"`
}

View File

@ -1,3 +1,4 @@
llm:
extract_keywords_prompt: "You will extract structured data from the user input. Input text: {{.Message}}. Return ONLY valid minified JSON object with keys: translate (English translation of input), keyword (array of 3-5 concise English veterinary-related keywords derived strictly from the input), animal (animal mentioned or 'unknown'). Example: {\"translate\":\"dog has diarrhea\",\"keyword\":[\"diarrhea\",\"digestive\"],\"animal\":\"dog\"}. Do not add extra text, markdown, or quotes outside JSON."
disambiguate_prompt: "Given candidate visit entries (JSON array): {{.Entries}} and user message: {{.Message}} choose the best matching visit's ID. Return ONLY JSON: {\"visitReason\":\"<one of the candidate IDs or empty string if none>\"}. No other text."
translate_prompt: "Translate the following veterinary-related sentence to English. Input: '{{.Message}}'. Return ONLY the English translation, no extra text, no markdown, no quotes. If already English, return as is."

1
llm.go
View File

@ -15,6 +15,7 @@ type LLMClientAPI interface {
ExtractKeywords(ctx context.Context, message string) (map[string]interface{}, error)
DisambiguateBestMatch(ctx context.Context, message string, candidates []Visit) (string, error)
GetEmbeddings(ctx context.Context, input string) ([]float64, error)
TranslateToEnglish(ctx context.Context, message string) (string, error)
}
// --- Format Utilities ---

View File

@ -0,0 +1,16 @@
-- +goose Up
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE sentence_embeddings (
id SERIAL PRIMARY KEY,
visit_id INTEGER NOT NULL,
sentence TEXT NOT NULL,
translated TEXT,
embeddings VECTOR(1536) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- +goose Down
DROP TABLE IF EXISTS sentence_embeddings;
DROP EXTENSION IF EXISTS vector;

View File

@ -166,3 +166,19 @@ func (llm *OllamaClient) GetEmbeddings(ctx context.Context, input string) ([]flo
}
return nil, fmt.Errorf("unrecognized embedding response: %.200s", string(raw))
}
func (llm *OllamaClient) TranslateToEnglish(ctx context.Context, message string) (string, error) {
prompt, err := renderPrompt(appConfig.LLM.TranslatePrompt, map[string]string{"Message": message})
if err != nil {
logrus.WithError(err).Error("[CONFIG] Failed to render Translate prompt")
return "", err
}
logrus.WithField("prompt", prompt).Info("[LLM] TranslateToEnglish prompt")
resp, err := llm.ollamaCompletion(ctx, prompt, nil)
logrus.WithFields(logrus.Fields{"response": resp, "err": err}).Info("[LLM] TranslateToEnglish response")
if err != nil {
return resp, err
}
return strings.TrimSpace(resp), nil
}

View File

@ -198,3 +198,19 @@ func (llm *OpenAIClient) GetEmbeddings(ctx context.Context, input string) ([]flo
}
return nil, fmt.Errorf("unrecognized embedding response: %.200s", string(raw))
}
func (llm *OpenAIClient) TranslateToEnglish(ctx context.Context, message string) (string, error) {
prompt, err := renderPrompt(appConfig.LLM.TranslatePrompt, map[string]string{"Message": message})
if err != nil {
logrus.WithError(err).Error("[CONFIG] Failed to render Translate prompt")
return "", err
}
logrus.WithField("prompt", prompt).Info("[LLM] TranslateToEnglish prompt")
resp, err := llm.openAICompletion(ctx, prompt, nil)
logrus.WithFields(logrus.Fields{"response": resp, "err": err}).Info("[LLM] TranslateToEnglish response")
if err != nil {
return resp, err
}
return strings.TrimSpace(resp), nil
}