-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5104282
commit 93162fd
Showing
3 changed files
with
119 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,114 @@ | ||
package ldai | ||
|
||
import ( | ||
"fmt" | ||
"github.com/launchdarkly/go-sdk-common/v3/ldcontext" | ||
"github.com/launchdarkly/go-sdk-common/v3/ldvalue" | ||
"github.com/launchdarkly/go-server-sdk/v7/interfaces" | ||
) | ||
|
||
const ( | ||
duration = "$ld:ai:duration:total" | ||
feedbackPositive = "$ld:ai:feedback:user:positive" | ||
feedbackNegative = "$ld:ai:feedback:user:negative" | ||
generation = "$ld:ai:generation" | ||
tokenTotal = "$ld:ai:tokens:total" | ||
tokenInput = "$ld:ai:tokens:input" | ||
tokenOutput = "$ld:ai:tokens:output" | ||
) | ||
|
||
type TokenUsage struct { | ||
Total int | ||
Input int | ||
Output int | ||
} | ||
|
||
type Feedback string | ||
|
||
const ( | ||
Positive Feedback = "positive" | ||
Negative Feedback = "negative" | ||
) | ||
|
||
type Tracker struct { | ||
config *Config | ||
config *Config | ||
context ldcontext.Context | ||
events EventTracker | ||
trackData ldvalue.Value | ||
logger interfaces.LDLoggers | ||
} | ||
|
||
func NewTracker(config *Config) *Tracker { | ||
return &Tracker{config: config} | ||
type EventTracker interface { | ||
TrackMetric( | ||
eventName string, | ||
context ldcontext.Context, | ||
metricValue float64, | ||
data ldvalue.Value, | ||
) error | ||
} | ||
|
||
func NewTracker(key string, events EventTracker, config *Config, ctx ldcontext.Context, loggers interfaces.LDLoggers) *Tracker { | ||
if config == nil { | ||
panic("LaunchDarkly SDK programmer error: config must never be nil") | ||
} | ||
|
||
trackData := ldvalue.ObjectBuild(). | ||
Set("versionKey", ldvalue.String(config.VersionKey())). | ||
Set("configKey", ldvalue.String(key)).Build() | ||
|
||
return &Tracker{ | ||
config: config, | ||
trackData: trackData, | ||
events: events, | ||
context: ctx, | ||
logger: loggers, | ||
} | ||
} | ||
|
||
func (t *Tracker) TrackDuration(durationMs float64) error { | ||
return t.events.TrackMetric(duration, t.context, durationMs, t.trackData) | ||
} | ||
|
||
func (t *Tracker) TrackFeedback(feedback Feedback) error { | ||
switch feedback { | ||
case Positive: | ||
return t.events.TrackMetric(feedbackPositive, t.context, 1, t.trackData) | ||
case Negative: | ||
return t.events.TrackMetric(feedbackNegative, t.context, 1, t.trackData) | ||
default: | ||
return fmt.Errorf("unexpected feedback value: %v", feedback) | ||
} | ||
} | ||
|
||
func (t *Tracker) TrackSuccess() error { | ||
return t.events.TrackMetric(generation, t.context, 1, t.trackData) | ||
} | ||
|
||
func (t *Tracker) TrackUsage(usage TokenUsage) error { | ||
var failed bool | ||
|
||
if usage.Total > 0 { | ||
if err1 := t.events.TrackMetric(tokenTotal, t.context, float64(usage.Total), t.trackData); err1 != nil { | ||
t.logger.Warn("Error tracking total token usage: %s", err1.Error()) | ||
failed = true | ||
} | ||
} | ||
if usage.Input > 0 { | ||
if err2 := t.events.TrackMetric(tokenInput, t.context, float64(usage.Input), t.trackData); err2 != nil { | ||
t.logger.Warn("Error tracking input token usage: %s", err2.Error()) | ||
failed = true | ||
} | ||
} | ||
if usage.Output > 0 { | ||
if err3 := t.events.TrackMetric(tokenOutput, t.context, float64(usage.Output), t.trackData); err3 != nil { | ||
t.logger.Warn("Error tracking output token usage: %s", err3.Error()) | ||
failed = true | ||
} | ||
} | ||
|
||
if failed { | ||
return fmt.Errorf("error tracking token usage, logs contain more information") | ||
} | ||
|
||
return nil | ||
} |