-module(langfuse_client@score).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/langfuse_client/score.gleam").
-export(['query'/0, with_page/2, with_limit/2, with_name/2, with_trace_id/2, with_session_id/2, with_dataset_run_id/2, with_user_id/2, with_data_type/2, with_from_timestamp/2, with_to_timestamp/2, decode/1, list/2]).
-export_type([score/0, page/0, scores/0, 'query'/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" `GET /api/public/v2/scores` — paginated fetch of eval scores from a\n"
" Langfuse project. Build a `Query` with `query()` and the `with_*` helpers,\n"
" then pass it to `list(client, query)`.\n"
).
-type score() :: {score,
binary(),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
binary(),
binary(),
binary(),
gleam@option:option(float()),
gleam@option:option(binary()),
gleam@option:option(binary()),
binary(),
gleam@option:option(binary())}.
-type page() :: {page, integer(), integer(), integer(), integer()}.
-type scores() :: {scores, list(score()), page()}.
-type 'query'() :: {'query',
gleam@option:option(integer()),
gleam@option:option(integer()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary())}.
-file("src/langfuse_client/score.gleam", 67).
?DOC(
" Empty query — pass to `list` to retrieve the first page with the server\n"
" defaults (page 1, limit 50).\n"
).
-spec 'query'() -> 'query'().
'query'() ->
{'query', none, none, none, none, none, none, none, none, none, none, none}.
-file("src/langfuse_client/score.gleam", 84).
?DOC(" Set the page number (1-indexed).\n").
-spec with_page('query'(), integer()) -> 'query'().
with_page(Q, Page) ->
{'query',
{some, Page},
erlang:element(3, Q),
erlang:element(4, Q),
erlang:element(5, Q),
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 89).
?DOC(" Set the page size (Langfuse defaults to 50).\n").
-spec with_limit('query'(), integer()) -> 'query'().
with_limit(Q, Limit) ->
{'query',
erlang:element(2, Q),
{some, Limit},
erlang:element(4, Q),
erlang:element(5, Q),
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 94).
?DOC(" Filter to scores with this exact name.\n").
-spec with_name('query'(), binary()) -> 'query'().
with_name(Q, Name) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
erlang:element(4, Q),
{some, Name},
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 99).
?DOC(" Filter to scores attached to this trace.\n").
-spec with_trace_id('query'(), binary()) -> 'query'().
with_trace_id(Q, Trace_id) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
erlang:element(4, Q),
erlang:element(5, Q),
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
{some, Trace_id},
erlang:element(10, Q),
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 104).
?DOC(" Filter to scores attached to this session.\n").
-spec with_session_id('query'(), binary()) -> 'query'().
with_session_id(Q, Session_id) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
erlang:element(4, Q),
erlang:element(5, Q),
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
{some, Session_id},
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 109).
?DOC(" Filter to scores tied to this dataset run.\n").
-spec with_dataset_run_id('query'(), binary()) -> 'query'().
with_dataset_run_id(Q, Dataset_run_id) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
erlang:element(4, Q),
erlang:element(5, Q),
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
{some, Dataset_run_id},
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 114).
?DOC(" Filter to scores whose trace has this user id.\n").
-spec with_user_id('query'(), binary()) -> 'query'().
with_user_id(Q, User_id) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
{some, User_id},
erlang:element(5, Q),
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 119).
?DOC(" Filter to scores of a given data type (`NUMERIC`, `BOOLEAN`, `CATEGORICAL`).\n").
-spec with_data_type('query'(), binary()) -> 'query'().
with_data_type(Q, Data_type) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
erlang:element(4, Q),
erlang:element(5, Q),
erlang:element(6, Q),
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
erlang:element(11, Q),
{some, Data_type}}.
-file("src/langfuse_client/score.gleam", 124).
?DOC(" Lower bound on `timestamp` (ISO 8601, inclusive).\n").
-spec with_from_timestamp('query'(), binary()) -> 'query'().
with_from_timestamp(Q, From) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
erlang:element(4, Q),
erlang:element(5, Q),
{some, From},
erlang:element(7, Q),
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 129).
?DOC(" Upper bound on `timestamp` (ISO 8601, exclusive).\n").
-spec with_to_timestamp('query'(), binary()) -> 'query'().
with_to_timestamp(Q, To) ->
{'query',
erlang:element(2, Q),
erlang:element(3, Q),
erlang:element(4, Q),
erlang:element(5, Q),
erlang:element(6, Q),
{some, To},
erlang:element(8, Q),
erlang:element(9, Q),
erlang:element(10, Q),
erlang:element(11, Q),
erlang:element(12, Q)}.
-file("src/langfuse_client/score.gleam", 142).
?DOC(
" Parse a `GET /api/public/v2/scores` response body. Useful if you already\n"
" have the raw body in hand (e.g. from a cached/recorded response).\n"
).
-spec decode(binary()) -> {ok, scores()} | {error, gleam@json:decode_error()}.
decode(Body) ->
gleam@json:parse(Body, scores_decoder()).
-file("src/langfuse_client/score.gleam", 182).
-spec meta_decoder() -> gleam@dynamic@decode:decoder(page()).
meta_decoder() ->
gleam@dynamic@decode:field(
<<"page"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Page) ->
gleam@dynamic@decode:field(
<<"limit"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Limit) ->
gleam@dynamic@decode:field(
<<"totalItems"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Total_items) ->
gleam@dynamic@decode:field(
<<"totalPages"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Total_pages) ->
gleam@dynamic@decode:success(
{page,
Page,
Limit,
Total_items,
Total_pages}
)
end
)
end
)
end
)
end
).
-file("src/langfuse_client/score.gleam", 178).
-spec lenient_float() -> gleam@dynamic@decode:decoder(float()).
lenient_float() ->
gleam@dynamic@decode:one_of(
{decoder, fun gleam@dynamic@decode:decode_float/1},
[begin
_pipe = {decoder, fun gleam@dynamic@decode:decode_int/1},
gleam@dynamic@decode:map(_pipe, fun erlang:float/1)
end]
).
-file("src/langfuse_client/score.gleam", 190).
-spec score_decoder() -> gleam@dynamic@decode:decoder(score()).
score_decoder() ->
gleam@dynamic@decode:field(
<<"id"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Id) ->
gleam@dynamic@decode:optional_field(
<<"traceId"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Trace_id) ->
gleam@dynamic@decode:optional_field(
<<"sessionId"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
fun(Session_id) ->
gleam@dynamic@decode:optional_field(
<<"observationId"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(Observation_id) ->
gleam@dynamic@decode:field(
<<"name"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Name) ->
gleam@dynamic@decode:field(
<<"dataType"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Data_type) ->
gleam@dynamic@decode:field(
<<"source"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Source) ->
gleam@dynamic@decode:optional_field(
<<"value"/utf8>>,
none,
gleam@dynamic@decode:optional(
lenient_float(
)
),
fun(Value) ->
gleam@dynamic@decode:optional_field(
<<"stringValue"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(
String_value
) ->
gleam@dynamic@decode:optional_field(
<<"comment"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(
Comment
) ->
gleam@dynamic@decode:field(
<<"timestamp"/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(
Timestamp
) ->
gleam@dynamic@decode:optional_field(
<<"environment"/utf8>>,
none,
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
fun(
Environment
) ->
gleam@dynamic@decode:success(
{score,
Id,
Trace_id,
Session_id,
Observation_id,
Name,
Data_type,
Source,
Value,
String_value,
Comment,
Timestamp,
Environment}
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/langfuse_client/score.gleam", 170).
-spec scores_decoder() -> gleam@dynamic@decode:decoder(scores()).
scores_decoder() ->
gleam@dynamic@decode:field(
<<"data"/utf8>>,
gleam@dynamic@decode:list(score_decoder()),
fun(Data) ->
gleam@dynamic@decode:field(
<<"meta"/utf8>>,
meta_decoder(),
fun(Meta) ->
gleam@dynamic@decode:success({scores, Data, Meta})
end
)
end
).
-file("src/langfuse_client/score.gleam", 147).
-spec query_pairs('query'()) -> list({binary(), binary()}).
query_pairs(Q) ->
_pipe = [{<<"page"/utf8>>,
gleam@option:map(
erlang:element(2, Q),
fun erlang:integer_to_binary/1
)},
{<<"limit"/utf8>>,
gleam@option:map(
erlang:element(3, Q),
fun erlang:integer_to_binary/1
)},
{<<"userId"/utf8>>, erlang:element(4, Q)},
{<<"name"/utf8>>, erlang:element(5, Q)},
{<<"fromTimestamp"/utf8>>, erlang:element(6, Q)},
{<<"toTimestamp"/utf8>>, erlang:element(7, Q)},
{<<"source"/utf8>>, erlang:element(8, Q)},
{<<"traceId"/utf8>>, erlang:element(9, Q)},
{<<"sessionId"/utf8>>, erlang:element(10, Q)},
{<<"datasetRunId"/utf8>>, erlang:element(11, Q)},
{<<"dataType"/utf8>>, erlang:element(12, Q)}],
gleam@list:filter_map(
_pipe,
fun(Pair) ->
{K, V} = Pair,
case V of
{some, Value} ->
{ok, {K, Value}};
none ->
{error, nil}
end
end
).
-file("src/langfuse_client/score.gleam", 136).
?DOC(
" Fetch one page of scores from `GET /api/public/v2/scores`. Erlang-only —\n"
" the JavaScript target lacks an HTTP transport in this library.\n"
).
-spec list(langfuse_client@client:client(), 'query'()) -> {ok, scores()} |
{error, langfuse_client@client:error()}.
list(C, Q) ->
langfuse_client@client:send_get(
C,
<<"/api/public/v2/scores"/utf8>>,
query_pairs(Q),
scores_decoder()
).