Packages
caffeine_lang
6.3.1
6.3.1
6.3.0
6.2.2
6.2.1
6.2.0
6.1.2
6.1.1
6.1.0
6.0.0
5.6.0
5.5.0
5.4.4
5.4.3
5.4.2
5.4.1
5.4.0
5.3.0
5.2.0
5.1.1
5.1.0
5.0.12
5.0.11
5.0.10
5.0.8
5.0.7
5.0.6
5.0.5
5.0.4
5.0.1
5.0.0
4.10.0
4.9.0
4.8.3
4.8.2
4.8.1
4.8.0
4.7.9
4.7.8
4.7.7
4.7.6
4.7.5
4.6.7
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.7
4.3.6
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.0.2
1.0.1
0.1.0
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.2
0.0.1
A compiler for generating reliability artifacts from service expectation definitions.
Current section
Files
Jump to
Current section
Files
src/caffeine_lang@codegen@relay.erl
-module(caffeine_lang@codegen@relay).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/codegen/relay.gleam").
-export([generate_langfuse_to_datadog/1]).
-export_type([relay_file/0, scorer_data_type/0, scorer/0, langfuse_datadog_relay/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(
" Codegen for the Relay artifact.\n"
"\n"
" A relay is a GitHub Action that pulls metrics from a source vendor and\n"
" pushes them to a destination vendor. The compiler emits a self-contained\n"
" set of files that a target repository drops in to start relaying.\n"
"\n"
" Today the only supported pairing is Langfuse → Datadog, producing four\n"
" files:\n"
" - `.github/workflows/<name>.yml` — workflow that runs the runner on a\n"
" schedule, manages a cursor in a repo Variable, and dispatches manually.\n"
" - `relay/gleam.toml` — runner project manifest.\n"
" - `relay/src/relay.gleam` — runner that queries Langfuse v2 metrics\n"
" for `[from, to)` and submits one Datadog metric per scorer.\n"
" - `relay/src/manifest.gleam` — static declaration of which metrics the\n"
" relay emits. The runner imports it for its scorer allowlist; later\n"
" language tooling will import it to type-check measurement references.\n"
"\n"
" File contents come from templates under `priv/templates/relay/<pairing>/`.\n"
" Each template is a real `.yml` / `.toml` / `.gleam` file with\n"
" `{{PLACEHOLDER}}` tokens — so editors and reviewers get the right syntax\n"
" highlighting and the diffs read naturally.\n"
).
-type relay_file() :: {relay_file, binary(), binary()}.
-type scorer_data_type() :: numeric | boolean | categorical.
-type scorer() :: {scorer, binary(), scorer_data_type()}.
-type langfuse_datadog_relay() :: {langfuse_datadog_relay,
binary(),
binary(),
binary(),
list(scorer())}.
-file("src/caffeine_lang/codegen/relay.gleam", 146).
-spec data_type_string(scorer_data_type()) -> binary().
data_type_string(Dt) ->
case Dt of
numeric ->
<<"numeric"/utf8>>;
boolean ->
<<"boolean"/utf8>>;
categorical ->
<<"categorical"/utf8>>
end.
-file("src/caffeine_lang/codegen/relay.gleam", 131).
-spec render_scorer_entry(scorer(), binary()) -> binary().
render_scorer_entry(Scorer, Metric_prefix) ->
Data_type_str = data_type_string(erlang:element(3, Scorer)),
Value_metric = case erlang:element(3, Scorer) of
categorical ->
<<"option.None"/utf8>>;
numeric ->
<<<<"option.Some(\""/utf8, Metric_prefix/binary>>/binary,
".value\")"/utf8>>;
boolean ->
<<<<"option.Some(\""/utf8, Metric_prefix/binary>>/binary,
".value\")"/utf8>>
end,
<<<<<<<<<<<<<<<<<<<<<<<<<<" ScorerInfo(\n"/utf8, " name: \""/utf8>>/binary,
(erlang:element(2, Scorer))/binary>>/binary,
"\",\n"/utf8>>/binary,
" data_type: \""/utf8>>/binary,
Data_type_str/binary>>/binary,
"\",\n"/utf8>>/binary,
" count_metric: \""/utf8>>/binary,
Metric_prefix/binary>>/binary,
".count\",\n"/utf8>>/binary,
" value_metric: "/utf8>>/binary,
Value_metric/binary>>/binary,
",\n"/utf8>>/binary,
" ),\n"/utf8>>.
-file("src/caffeine_lang/codegen/relay.gleam", 125).
-spec scorer_entries(langfuse_datadog_relay()) -> binary().
scorer_entries(Relay) ->
_pipe = erlang:element(5, Relay),
_pipe@1 = gleam@list:map(
_pipe,
fun(_capture) ->
render_scorer_entry(_capture, erlang:element(3, Relay))
end
),
erlang:list_to_binary(_pipe@1).
-file("src/caffeine_lang/codegen/relay.gleam", 119).
-spec cursor_var_name(langfuse_datadog_relay()) -> binary().
cursor_var_name(Relay) ->
<<"RELAY_CURSOR_"/utf8,
(string:uppercase(erlang:element(2, Relay)))/binary>>.
-file("src/caffeine_lang/codegen/relay.gleam", 109).
-spec substitutions(langfuse_datadog_relay()) -> list({binary(), binary()}).
substitutions(Relay) ->
[{<<"{{RELAY_NAME}}"/utf8>>, erlang:element(2, Relay)},
{<<"{{METRIC_PREFIX}}"/utf8>>, erlang:element(3, Relay)},
{<<"{{SCHEDULE_CRON}}"/utf8>>, erlang:element(4, Relay)},
{<<"{{CURSOR_VAR}}"/utf8>>, cursor_var_name(Relay)},
{<<"{{SCORER_ENTRIES}}"/utf8>>, scorer_entries(Relay)}].
-file("src/caffeine_lang/codegen/relay.gleam", 101).
?DOC(
" Read a template from `priv/templates/relay/langfuse_to_datadog/` and\n"
" substitute the relay's fields into the `{{PLACEHOLDER}}` tokens. A\n"
" missing template file means the package was shipped broken — assert so\n"
" it fails loudly.\n"
).
-spec render(langfuse_datadog_relay(), binary()) -> binary().
render(Relay, Template_name) ->
Template@1 = case simplifile:read(
<<"priv/templates/relay/langfuse_to_datadog/"/utf8,
Template_name/binary>>
) of
{ok, Template} -> Template;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"caffeine_lang/codegen/relay"/utf8>>,
function => <<"render"/utf8>>,
line => 102,
value => _assert_fail,
start => 4166,
'end' => 4238,
pattern_start => 4177,
pattern_end => 4189})
end,
gleam@list:fold(
substitutions(Relay),
Template@1,
fun(Acc, Sub) ->
{Placeholder, Value} = Sub,
gleam@string:replace(Acc, Placeholder, Value)
end
).
-file("src/caffeine_lang/codegen/relay.gleam", 75).
?DOC(" Generate the file set for a Langfuse → Datadog relay.\n").
-spec generate_langfuse_to_datadog(langfuse_datadog_relay()) -> list(relay_file()).
generate_langfuse_to_datadog(Relay) ->
[{relay_file,
<<<<".github/workflows/"/utf8, (erlang:element(2, Relay))/binary>>/binary,
".yml"/utf8>>,
render(Relay, <<"workflow.yml"/utf8>>)},
{relay_file,
<<"relay/gleam.toml"/utf8>>,
render(Relay, <<"gleam.toml"/utf8>>)},
{relay_file,
<<"relay/src/relay.gleam"/utf8>>,
render(Relay, <<"runner.gleam"/utf8>>)},
{relay_file,
<<"relay/src/manifest.gleam"/utf8>>,
render(Relay, <<"manifest.gleam"/utf8>>)}].