|
1 |
| -tokens_log <- function(provider, tokens) { |
2 |
| - # TODO: probably should make this store in a data frame, but will tackle |
3 |
| - # when implementing token costs. |
| 1 | +on_load( |
| 2 | + the$tokens <- tokens_row(character(), character(), numeric(), numeric()) |
| 3 | +) |
4 | 4 |
|
5 |
| - name <- paste0(provider@name, "/", provider@model) |
| 5 | +tokens_log <- function(provider, input = NULL, output = NULL) { |
| 6 | + input <- input %||% 0 |
| 7 | + output <- output %||% 0 |
6 | 8 |
|
7 |
| - if (is.null(the$tokens)) { |
8 |
| - the$tokens <- list() |
9 |
| - } |
10 |
| - if (is.null(the$tokens[[name]])) { |
11 |
| - the$tokens[[name]] <- c(0, 0) |
| 9 | + model <- standardise_model(provider, provider@model) |
| 10 | + |
| 11 | + name <- function(provider, model) paste0(provider, "/", model) |
| 12 | + i <- tokens_match(provider@name, model, the$tokens$provider, the$tokens$model) |
| 13 | + |
| 14 | + if (is.na(i)) { |
| 15 | + new_row <- tokens_row(provider@name, model, input, output) |
| 16 | + the$tokens <- rbind(the$tokens, new_row) |
| 17 | + } else { |
| 18 | + the$tokens$input[i] <- the$tokens$input[i] + input |
| 19 | + the$tokens$output[i] <- the$tokens$output[i] + output |
12 | 20 | }
|
13 | 21 |
|
14 |
| - tokens[is.na(tokens)] <- 0 |
15 |
| - the$tokens[[name]] <- the$tokens[[name]] + tokens |
16 |
| - invisible() |
| 22 | + # Returns value to be passed to Turn |
| 23 | + c(input, output) |
| 24 | +} |
| 25 | + |
| 26 | +tokens_row <- function(provider, model, input, output) { |
| 27 | + data.frame(provider = provider, model = model, input = input, output = output) |
17 | 28 | }
|
18 | 29 |
|
| 30 | +tokens_match <- function( |
| 31 | + provider_needle, |
| 32 | + model_needle, |
| 33 | + provider_haystack, |
| 34 | + model_haystack |
| 35 | +) { |
| 36 | + match( |
| 37 | + paste0(provider_needle, "/", model_needle), |
| 38 | + paste0(provider_haystack, "/", model_haystack) |
| 39 | + ) |
| 40 | +} |
| 41 | + |
| 42 | + |
19 | 43 | local_tokens <- function(frame = parent.frame()) {
|
20 | 44 | old <- the$tokens
|
21 |
| - the$tokens <- NULL |
| 45 | + the$tokens <- tokens_row(character(), character(), numeric(), numeric()) |
22 | 46 |
|
23 | 47 | defer(the$tokens <- old, env = frame)
|
24 | 48 | }
|
25 | 49 |
|
26 |
| -tokens_set <- function() { |
27 |
| - the$tokens <- NULL |
28 |
| - invisible() |
29 |
| -} |
30 |
| - |
31 | 50 | #' Report on token usage in the current session
|
32 | 51 | #'
|
33 | 52 | #' Call this function to find out the cumulative number of tokens that you
|
34 |
| -#' have sent and recieved in the current session. |
| 53 | +#' have sent and recieved in the current session. The price will be shown |
| 54 | +#' if known. |
35 | 55 | #'
|
36 | 56 | #' @export
|
37 | 57 | #' @return A data frame
|
38 | 58 | #' @examples
|
39 | 59 | #' token_usage()
|
40 | 60 | token_usage <- function() {
|
41 |
| - if (is.null(the$tokens)) { |
| 61 | + if (nrow(the$tokens) == 0) { |
42 | 62 | cli::cli_inform(c(x = "No recorded usage in this session"))
|
43 |
| - return(invisible( |
44 |
| - data.frame(name = character(), input = numeric(), output = numeric()) |
45 |
| - )) |
| 63 | + return(invisible(the$tokens)) |
46 | 64 | }
|
47 | 65 |
|
48 |
| - rows <- map2(names(the$tokens), the$tokens, function(name, tokens) { |
49 |
| - data.frame(name = name, input = tokens[[1]], output = tokens[[2]]) |
50 |
| - }) |
51 |
| - do.call("rbind", rows) |
| 66 | + out <- the$tokens |
| 67 | + out$price <- find_price(out$provider, out$model, out$input, out$output) |
| 68 | + out |
| 69 | +} |
| 70 | + |
| 71 | +# Pricing ---------------------------------------------------------------------- |
| 72 | + |
| 73 | +find_price <- function(provider, model, input, output) { |
| 74 | + idx <- tokens_match(provider, model, prices$provider, prices$model) |
| 75 | + |
| 76 | + input_price <- input * prices$input[idx] / 1e6 |
| 77 | + output_price <- output * prices$output[idx] / 1e6 |
| 78 | + ellmer_price(input_price + output_price) |
| 79 | +} |
| 80 | + |
| 81 | +ellmer_price <- function(x) { |
| 82 | + structure(x, class = c("ellmer_price", "numeric")) |
| 83 | +} |
| 84 | +#' @export |
| 85 | +format.ellmer_price <- function(x, ...) { |
| 86 | + paste0("$", format(unclass(x), nsmall = 2)) |
| 87 | +} |
| 88 | +#' @export |
| 89 | +print.ellmer_price <- function(x, ...) { |
| 90 | + print(format(x), quote = FALSE) |
| 91 | + invisible(x) |
52 | 92 | }
|
0 commit comments