Skip to content

Commit 3b28bb7

Browse files
chore: collect and log token usage
1 parent 12e80c2 commit 3b28bb7

File tree

7 files changed

+42
-3
lines changed

7 files changed

+42
-3
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ require (
1414
github.com/fatih/color v1.16.0
1515
github.com/getkin/kin-openapi v0.123.0
1616
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
17-
github.com/gptscript-ai/chat-completion-client v0.0.0-20240502162133-7dabc28eab59
17+
github.com/gptscript-ai/chat-completion-client v0.0.0-20240515050533-bdef9f2226a9
1818
github.com/hexops/autogold/v2 v2.2.1
1919
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056
2020
github.com/mholt/archiver/v4 v4.0.0-alpha.8

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
123123
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
124124
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
125125
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
126-
github.com/gptscript-ai/chat-completion-client v0.0.0-20240502162133-7dabc28eab59 h1:Nda0GDkrmIDiAFHfaXu0eIp6SsBs0/4Zyo87ff3Qcqo=
127-
github.com/gptscript-ai/chat-completion-client v0.0.0-20240502162133-7dabc28eab59/go.mod h1:7P/o6/IWa1KqsntVf68hSnLKuu3+xuqm6lYhch1w4jo=
126+
github.com/gptscript-ai/chat-completion-client v0.0.0-20240515050533-bdef9f2226a9 h1:s6nL/aokB1sJTqVXEjN0zFI5CJa66ubw9g68VTMzEw0=
127+
github.com/gptscript-ai/chat-completion-client v0.0.0-20240515050533-bdef9f2226a9/go.mod h1:7P/o6/IWa1KqsntVf68hSnLKuu3+xuqm6lYhch1w4jo=
128128
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
129129
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
130130
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=

pkg/monitor/display.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ type display struct {
6262
dumpState string
6363
callIDMap map[string]string
6464
callLock sync.Mutex
65+
usage types.Usage
6566
}
6667

6768
type livePrinter struct {
@@ -226,6 +227,10 @@ func (d *display) Event(event runner.Event) {
226227
userSpecifiedToolName: event.CallContext.ToolName,
227228
}
228229

230+
d.usage.PromptTokens += event.Usage.PromptTokens
231+
d.usage.CompletionTokens += event.Usage.CompletionTokens
232+
d.usage.TotalTokens += event.Usage.TotalTokens
233+
229234
switch event.Type {
230235
case runner.EventTypeCallStart:
231236
d.livePrinter.progressStart(currentCall)
@@ -283,6 +288,7 @@ func (d *display) Stop(output string, err error) {
283288
defer d.callLock.Unlock()
284289

285290
log.Fields("runID", d.dump.ID, "output", output, "err", err).Debugf("Run stopped")
291+
log.Fields("runID", d.dump.ID, "total", d.usage.TotalTokens, "prompt", d.usage.PromptTokens, "completion", d.usage.CompletionTokens).Infof("usage ")
286292
d.dump.Output = output
287293
d.dump.Err = err
288294
if d.dumpState != "" {

pkg/mvl/log.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ func (f formatter) Format(entry *logrus.Entry) ([]byte, error) {
3838
if i, ok := entry.Data["response"]; ok && i != "" {
3939
msg += fmt.Sprintf(" [response=%s]", i)
4040
}
41+
if i, ok := entry.Data["total"]; ok && i != "" {
42+
msg += fmt.Sprintf(" [total=%v]", i)
43+
}
44+
if i, ok := entry.Data["prompt"]; ok && i != "" {
45+
msg += fmt.Sprintf(" [prompt=%v]", i)
46+
}
47+
if i, ok := entry.Data["completion"]; ok && i != "" {
48+
msg += fmt.Sprintf(" [completion=%v]", i)
49+
}
4150
return []byte(fmt.Sprintf("%s %s\n",
4251
entry.Time.Format(time.TimeOnly),
4352
msg)), nil

pkg/openai/client.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques
308308
Model: messageRequest.Model,
309309
Messages: msgs,
310310
MaxTokens: messageRequest.MaxTokens,
311+
StreamOptions: &openai.StreamOptions{
312+
IncludeUsage: true,
313+
},
311314
}
312315

313316
if messageRequest.Temperature == nil {
@@ -372,17 +375,27 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques
372375
}
373376
}
374377

378+
var usage types.Usage
379+
if !cacheResponse {
380+
usage = result.Usage
381+
}
382+
375383
status <- types.CompletionStatus{
376384
CompletionID: id,
377385
Chunks: response,
378386
Response: result,
387+
Usage: usage,
379388
Cached: cacheResponse,
380389
}
381390

382391
return &result, nil
383392
}
384393

385394
func appendMessage(msg types.CompletionMessage, response openai.ChatCompletionStreamResponse) types.CompletionMessage {
395+
msg.Usage.CompletionTokens = types.FirstSet(msg.Usage.CompletionTokens, response.Usage.CompletionTokens)
396+
msg.Usage.PromptTokens = types.FirstSet(msg.Usage.PromptTokens, response.Usage.PromptTokens)
397+
msg.Usage.TotalTokens = types.FirstSet(msg.Usage.TotalTokens, response.Usage.TotalTokens)
398+
386399
if len(response.Choices) == 0 {
387400
return msg
388401
}
@@ -470,6 +483,7 @@ func (c *Client) call(ctx context.Context, request openai.ChatCompletionRequest,
470483
Object: resp.Object,
471484
Created: resp.Created,
472485
Model: resp.Model,
486+
Usage: resp.Usage,
473487
Choices: []openai.ChatCompletionStreamChoice{
474488
{
475489
Index: resp.Choices[0].Index,

pkg/runner/runner.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ type Event struct {
196196
ChatCompletionID string `json:"chatCompletionId,omitempty"`
197197
ChatRequest any `json:"chatRequest,omitempty"`
198198
ChatResponse any `json:"chatResponse,omitempty"`
199+
Usage types.Usage `json:"usage,omitempty"`
199200
ChatResponseCached bool `json:"chatResponseCached,omitempty"`
200201
Content string `json:"content,omitempty"`
201202
}
@@ -622,6 +623,7 @@ func streamProgress(callCtx *engine.Context, monitor Monitor) (chan<- types.Comp
622623
ChatCompletionID: status.CompletionID,
623624
ChatRequest: status.Request,
624625
ChatResponse: status.Response,
626+
Usage: status.Usage,
625627
ChatResponseCached: status.Cached,
626628
})
627629
}

pkg/types/completion.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,20 @@ type CompletionMessage struct {
5454
// ToolCall should be set for only messages of type "tool" and Content[0].Text should be set as the
5555
// result of the call describe by this field
5656
ToolCall *CompletionToolCall `json:"toolCall,omitempty"`
57+
Usage Usage `json:"usage,omitempty"`
58+
}
59+
60+
type Usage struct {
61+
PromptTokens int `json:"promptTokens,omitempty"`
62+
CompletionTokens int `json:"completionTokens,omitempty"`
63+
TotalTokens int `json:"totalTokens,omitempty"`
5764
}
5865

5966
type CompletionStatus struct {
6067
CompletionID string
6168
Request any
6269
Response any
70+
Usage Usage
6371
Cached bool
6472
Chunks any
6573
PartialResponse *CompletionMessage

0 commit comments

Comments
 (0)