Skip to content

Commit 2c7810f

Browse files
authored
Merge pull request #7 from tyzbit/ollama
Ollama filter support
2 parents 9667390 + 488a72d commit 2c7810f

File tree

6 files changed

+151
-39
lines changed

6 files changed

+151
-39
lines changed

README.md

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,44 +35,48 @@ variables for them.
3535

3636
### Annotators
3737

38-
| Environment Variable | Value |
39-
| ---------------------------------- | ----------------------------------------------------------------- |
40-
| ANNOTATE_ACARS | Include the original ACARS message, "true" or "false" |
41-
| ANNOTATE_VDLM2 | Include the original VDLM2 message, "true" or "false" |
42-
| ADBSEXCHANGE_APIKEY | Your API Key to adb-s exchange (lite tier is fine) |
43-
| ADBSEXCHANGE_REFERENCE_GEOLOCATION | A geolocation to calulate distance from (ex: "0.1,-0.1") \* |
44-
| TAR1090_URL | URL to a tar1090 instance |
45-
| TAR1090_REFERENCE_GEOLOCATION | Geolocation to allow the annotator to provide distance metrics \* |
38+
| Environment Variable | Value |
39+
| ---------------------------------- | ---------------------------------------------------------------------- |
40+
| ANNOTATE_ACARS | Include the original ACARS message, "true" or "false" |
41+
| ANNOTATE_VDLM2 | Include the original VDLM2 message, "true" or "false" |
42+
| ADBSEXCHANGE_APIKEY | **REQUIRED TO USE** Your API Key to adb-s exchange (lite tier is fine) |
43+
| ADBSEXCHANGE_REFERENCE_GEOLOCATION | A geolocation to calulate distance from (ex: "0.1,-0.1") \* |
44+
| TAR1090_URL | **REQUIRED TO USE** URL to a tar1090 instance |
45+
| TAR1090_REFERENCE_GEOLOCATION | Geolocation to allow the annotator to provide distance metrics \* |
4646

4747
### Filters
4848

49-
| Environment Variable | Value |
50-
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
51-
| ACARS_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable from ACARS annotator \*\* |
52-
| VDLM2_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable from VDLM2 annotator \*\* |
53-
| ADSB_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable from TAR1090 annotator \*\* |
54-
| TAR1090_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable \*\* |
55-
| FILTER_CRITERIA_HAS_TEXT | Message must have text |
56-
| FILTER_CRITERIA_MATCH_TAIL_CODE | Message must match tail code |
57-
| FILTER_CRITERIA_MATCH_FLIGHT_NUMBER | Message must match flight number |
58-
| FILTER_CRITERIA_MATCH_FREQUENCY | Message must have been received on this frequency |
59-
| FILTER_CRITERIA_ABOVE_SIGNAL_DBM | Message must have signal above this |
60-
| FILTER_CRITERIA_MATCH_STATION_ID | Message must have come from this station |
61-
| FILTER_CRITERIA_DICTIONARY_PHRASE_LENGTH_MINIMUM | Message must have at least this amount of consecutive words (English only at the moment) |
62-
| FILTER_OPENAI_PROMPT | Criteria to evaluate the message, sent to OpenAI (`gpt-4o` by default) \*\*\*\* |
63-
| FILTER_OPENAI_APIKEY | API key for OpenAI, required for functionality |
64-
| FILTER_OPENAI_MODEL | Override the default model, see [here](https://pkg.go.dev/github.com/openai/openai-go@v0.1.0-alpha.62#ChatModel) for your options |
65-
| FILTER_OPENAI_PREAMBLE | By default, `acars-annotator` includes a preamble that describes what the response should look like. This overrides that. |
49+
| Environment Variable | Value |
50+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
51+
| ACARS_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable from ACARS annotator \*\* |
52+
| VDLM2_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable from VDLM2 annotator \*\* |
53+
| ADSB_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable from TAR1090 annotator \*\* |
54+
| TAR1090_ANNOTATOR_SELECTED_FIELDS | If this is set, receivers will only receive fields present in this variable \*\* |
55+
| FILTER_CRITERIA_HAS_TEXT | Message must have text |
56+
| FILTER_CRITERIA_MATCH_TAIL_CODE | Message must match tail code |
57+
| FILTER_CRITERIA_MATCH_FLIGHT_NUMBER | Message must match flight number |
58+
| FILTER_CRITERIA_MATCH_FREQUENCY | Message must have been received on this frequency |
59+
| FILTER_CRITERIA_ABOVE_SIGNAL_DBM | Message must have signal above this |
60+
| FILTER_CRITERIA_MATCH_STATION_ID | Message must have come from this station |
61+
| FILTER_CRITERIA_DICTIONARY_PHRASE_LENGTH_MINIMUM | Message must have at least this amount of consecutive words (English only at the moment) |
62+
| FILTER_OLLAMA_URL | **REQUIRED TO USE** Full URL to your ollama instance (<scheme>://<host>:<port>) |
63+
| FILTER_OLLAMA_MODEL | **REQUIRED TO USE** The model to use; ex: "llama3.2" |
64+
| FILTER_OLLAMA_PROMPT | **REQUIRED TO USE** Criteria for the model to evaluate the message against \*\*\*\* |
65+
| FILTER_OLLAMA_SYSTEM_PROMPT | By default, `acars-annotator` includes a system prompt that describes what the response should look like. This overrides that. |
66+
| FILTER_OPENAI_PROMPT | **REQUIRED TO USE** Criteria to evaluate the message, sent to OpenAI \*\*\*\* |
67+
| FILTER_OPENAI_APIKEY | **REQUIRED TO USE** API key for OpenAI, required for functionality |
68+
| FILTER_OPENAI_MODEL | Override the default model (`gpt-4o` by default), see [here](https://pkg.go.dev/github.com/openai/openai-go@v0.1.0-alpha.62#ChatModel) for your options |
69+
| FILTER_OPENAI_PREAMBLE | By default, `acars-annotator` includes a preamble that describes what the response should look like. This overrides that. |
6670

6771
### Receivers
6872

69-
| Environment Variable | Value |
70-
| --------------------- | ------------------------------------------------------ |
71-
| DISCORD_WEBHOOK_URL | URL to a Discord webhook to post messages in a channel |
72-
| NEW_RELIC_LICENSE_KEY | Your New Relic Infra license key (ex: 123456NRAL) |
73-
| WEBHOOK_URL | URL to your custom webhook |
74-
| WEBHOOK_METHOD | GET, POST, etc |
75-
| WEBHOOK_HEADERS | Headers to send along with the webhook request\*\*\* |
73+
| Environment Variable | Value |
74+
| --------------------- | -------------------------------------------------------------------------- |
75+
| DISCORD_WEBHOOK_URL | **REQUIRED TO USE** URL to a Discord webhook to post messages in a channel |
76+
| NEW_RELIC_LICENSE_KEY | **REQUIRED TO USE** Your New Relic Infra license key (ex: 123456NRAL) |
77+
| WEBHOOK_URL | **REQUIRED TO USE** URL to your custom webhook |
78+
| WEBHOOK_METHOD | **REQUIRED TO USE** GET, POST, etc |
79+
| WEBHOOK_HEADERS | Headers to send along with the webhook request \*\*\* |
7680

7781
\* If none provided, "0,0" is used.
7882

config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ type Config struct {
1717
OpenAIPrompt string `env:"FILTER_OPENAI_PROMPT"`
1818
OpenAIModel string `env:"FILTER_OPENAI_MODEL"`
1919
OpenAICustomPreamble string `env:"FILTER_OPENAI_PREAMBLE"`
20+
OllamaURL string `env:"FILTER_OLLAMA_URL"`
21+
OllamaPrompt string `env:"FILTER_OLLAMA_PROMPT"`
22+
OllamaSystemPrompt string `env:"FILTER_OLLAMA_SYSTEM_PROMPT"`
23+
OllamaSystemAssistant string `env:"FILTER_OLLAMA_SYSTEM_ASSISTANT"`
24+
OllamaModel string `env:"FILTER_OLLAMA_MODEL"`
2025
ADSBAnnotatorSelectedFields string `env:"ADSB_ANNOTATOR_SELECTED_FIELDS"`
2126
VDLM2AnnotatorSelectedFields string `env:"VDLM2_ANNOTATOR_SELECTED_FIELDS"`
2227
TAR1090AnnotatorSelectedFields string `env:"TAR1090_ANNOTATOR_SELECTED_FIELDS"`

filter_ollama.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"net/http"
8+
"net/url"
9+
"regexp"
10+
11+
api "github.com/ollama/ollama/api"
12+
log "github.com/sirupsen/logrus"
13+
)
14+
15+
var OllamaSystemPrompt string = `You will evaluate a message to decide if it
16+
matches the provided criteria.
17+
You MUST respond in valid JSON with the format:
18+
19+
{"decision": boolean, "reasoning": string}
20+
21+
with the unquoted data in that object being results from your evaluation.
22+
23+
"decision" should ONLY be true or false.
24+
"reasoning" should ONLY be a string, and it should be a terse explanation of
25+
why, based on the criteria, you made the decision you made.
26+
Do not use backticks.
27+
28+
Here is the criteria:
29+
%s
30+
31+
Here is the message I want you to evaluate:
32+
%s
33+
`
34+
35+
type OllamaResponse struct {
36+
Decision bool `json:"decision"`
37+
Reasoning string `json:"reasoning"`
38+
}
39+
40+
// Return true if a message passes a filter, false otherwise
41+
func OllamaFilter(m string) bool {
42+
if config.OllamaModel == "" {
43+
log.Warn("Ollama model not specified, this is required to use the ollama filter")
44+
return true
45+
}
46+
if match, err := regexp.Match(`\S*`, []byte(m)); !match || err != nil {
47+
log.Info("message was blank, filtering without calling Ollama")
48+
return true
49+
}
50+
url, err := url.Parse(config.OllamaURL)
51+
if err != nil {
52+
log.Fatalf("Ollama url could not be parsed: %s", err)
53+
return true
54+
}
55+
client := api.NewClient(url, &http.Client{})
56+
if err != nil {
57+
log.Fatalf("error initializing Ollama: %s", err)
58+
}
59+
60+
if config.OllamaSystemPrompt != "" {
61+
OllamaSystemPrompt = config.OllamaSystemPrompt
62+
}
63+
messages := []api.Message{
64+
{
65+
Role: "system",
66+
Content: OllamaSystemPrompt,
67+
},
68+
{
69+
Role: "user",
70+
Content: fmt.Sprintf(OllamaSystemPrompt, config.OllamaPrompt, m),
71+
},
72+
}
73+
74+
ctx := context.Background()
75+
req := &api.ChatRequest{
76+
Model: config.OllamaModel,
77+
Messages: messages,
78+
}
79+
80+
var r OllamaResponse
81+
respFunc := func(resp api.ChatResponse) error {
82+
err = json.Unmarshal([]byte(resp.Message.Content), &r)
83+
if err != nil {
84+
return err
85+
}
86+
return nil
87+
}
88+
89+
err = client.Chat(ctx, req, respFunc)
90+
if err != nil {
91+
log.Errorf("error using Ollama: %s", err)
92+
return true
93+
}
94+
log.Debugf("Ollama response: %+v", r)
95+
return r.Decision
96+
}

filter_openai.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@ import (
1111
log "github.com/sirupsen/logrus"
1212
)
1313

14-
var OpenAIPromptTemplate string = `I have a message I want you to evaluate.
14+
var OpenAIPromptTemplate string = `You will evaluate a message to decide if it
15+
matches the provided criteria.
1516
You MUST respond in valid JSON with the format:
16-
{"decision": boolean, "reasoning": string} with the unquoted data in that object
17-
being results from your evaluation.
17+
18+
{"decision": boolean, "reasoning": string}
19+
20+
with the unquoted data in that object being results from your evaluation.
1821
1922
"decision" should ONLY be true or false.
2023
"reasoning" should ONLY be a string, and it should be a terse explanation of

go.mod

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
module github.com/tyzbit/acars-annotator
22

3-
go 1.23
4-
5-
toolchain go1.23.6
3+
go 1.24.0
64

75
require (
86
github.com/golobby/config/v3 v3.4.2
97
github.com/jftuga/geodist v1.0.0
108
github.com/newrelic/newrelic-telemetry-sdk-go v0.8.1
9+
github.com/ollama/ollama v0.6.1
1110
github.com/openai/openai-go v0.1.0-alpha.62
1211
github.com/sirupsen/logrus v1.9.3
1312
github.com/tidwall/words v0.0.0-20181116223016-6463671b7759

go.sum

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ github.com/golobby/dotenv v1.3.2 h1:9vA8XqXXIB3cX/5xQ1CTbOCPegioHtHXIxeFng+uOqQ=
1212
github.com/golobby/dotenv v1.3.2/go.mod h1:9MMVXqzLNluhVxCv3X/DLYBNUb289f05tr+df1+7278=
1313
github.com/golobby/env/v2 v2.2.4 h1:sjdTe+bScPRWUIA1AQH95RHv52jM5Mns2XHwLyEbkzk=
1414
github.com/golobby/env/v2 v2.2.4/go.mod h1:HDJW+dHHwLxkb8FZMjBTBiZUFl1iAA4F9YX15kBC84c=
15+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
16+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1517
github.com/jftuga/geodist v1.0.0 h1:PFPQlZtj10u8ETAYTyxE0DWMl1bwA+Xzrqb4+oLkkC0=
1618
github.com/jftuga/geodist v1.0.0/go.mod h1:BohEDxpZ8S5ADAxW/9EKPSKWOVl0+3wHENIT40m4UO4=
1719
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -23,6 +25,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
2325
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
2426
github.com/newrelic/newrelic-telemetry-sdk-go v0.8.1 h1:6OX5VXMuj2salqNBc41eXKz6K+nV6OB/hhlGnAKCbwU=
2527
github.com/newrelic/newrelic-telemetry-sdk-go v0.8.1/go.mod h1:2kY6OeOxrJ+RIQlVjWDc/pZlT3MIf30prs6drzMfJ6E=
28+
github.com/ollama/ollama v0.6.1 h1:M+wxOCuC1hKhHd6a8zNuJl6jYiRPsi/JFd4QoU0P5BQ=
29+
github.com/ollama/ollama v0.6.1/go.mod h1:pGgtoNyc9DdM6oZI6yMfI6jTk2Eh4c36c2GpfQCH7PY=
2630
github.com/openai/openai-go v0.1.0-alpha.62 h1:wf1Z+ZZAlqaUBlxhE5rhXxc9hQylcDRgMU2fg+jME+E=
2731
github.com/openai/openai-go v0.1.0-alpha.62/go.mod h1:3SdE6BffOX9HPEQv8IL/fi3LYZ5TUpRYaqGQZbyk11A=
2832
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@@ -38,8 +42,9 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
3842
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
3943
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
4044
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
41-
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
4245
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
46+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
47+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
4348
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
4449
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
4550
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=

0 commit comments

Comments
 (0)