MCPcopy Create free account
hub / github.com/NVIDIA-NeMo/Switchyard / run_observed

Method run_observed

crates/libsy/src/core/algorithm.rs:719–830  ·  view source on GitHub ↗

Process a request to completion while reporting each model call to `observer`.

(
        self: Arc<Self>,
        ctx: Context,
        request: Request,
        observer: Option<RunObserver>,
    )

Source from the content-addressed store, hash-verified

717
718 /// Process a request to completion while reporting each model call to `observer`.
719 async fn run_observed(
720 self: Arc<Self>,
721 ctx: Context,
722 request: Request,
723 observer: Option<RunObserver>,
724 ) -> Result<(Vec<Arc<dyn Decision>>, Response)> {
725 // Serve one offloaded call with its target's default client. A failed *model*
726 // call is forwarded to the algorithm via `respond`; this errors only on an
727 // infrastructure failure (no default client, or the promise was dropped).
728 // `serve` makes the one API call libsy itself performs, so it gets its
729 // own `libsy.client_call` span.
730 #[tracing::instrument(
731 target = "libsy",
732 name = "libsy.client_call",
733 skip_all,
734 fields(
735 algorithm = observability::algorithm_label(&call.get_routed().ctx),
736 switchyard.algorithm = observability::algorithm_label(&call.get_routed().ctx),
737 switchyard.routing.tier = tracing::field::Empty,
738 selected_model = call.get_decision().selected_model(),
739 otel.kind = "client",
740 otel.name = %format_args!("chat {}", call.get_decision().selected_model()),
741 openinference.span.kind = "LLM",
742 gen_ai.operation.name = "chat",
743 gen_ai.request.model = call.get_decision().selected_model(),
744 gen_ai.request.stream = tracing::field::Empty,
745 gen_ai.request.temperature = tracing::field::Empty,
746 gen_ai.request.top_p = tracing::field::Empty,
747 gen_ai.request.top_k = tracing::field::Empty,
748 gen_ai.request.max_tokens = tracing::field::Empty,
749 gen_ai.request.reasoning.level = tracing::field::Empty,
750 gen_ai.output.type = tracing::field::Empty,
751 gen_ai.conversation.id = tracing::field::Empty,
752 server.address = tracing::field::Empty,
753 server.port = tracing::field::Empty,
754 gen_ai.response.id = tracing::field::Empty,
755 gen_ai.response.model = tracing::field::Empty,
756 gen_ai.usage.input_tokens = tracing::field::Empty,
757 gen_ai.usage.output_tokens = tracing::field::Empty,
758 gen_ai.usage.cache_read.input_tokens = tracing::field::Empty,
759 gen_ai.usage.cache_creation.input_tokens = tracing::field::Empty,
760 gen_ai.usage.reasoning.output_tokens = tracing::field::Empty,
761 outcome = tracing::field::Empty,
762 otel.status_code = tracing::field::Empty,
763 error.type = tracing::field::Empty,
764 error = tracing::field::Empty,
765 )
766 )]
767 async fn serve(call: CallLlmRequest) -> Result<()> {
768 let span = tracing::Span::current();
769 observability::record_gen_ai_request(&span, &call.get_routed().request.llm_request);
770 if let Some(tier) = call.get_decision().routing_tier() {
771 span.record("switchyard.routing.tier", tier);
772 }
773 if let Some(session_id) = call
774 .get_routed()
775 .request
776 .metadata

Callers 3

handle_llm_requestFunction · 0.80
runMethod · 0.80

Implementers 13

algorithm.rscrates/libsy/src/core/algorithm.rs
dropping_the_stream_cancels_the_algorithm_taskcrates/libsy/src/core/algorithm.rs
create_run_task_panic_surfaces_as_a_stream_errorcrates/libsy/src/core/algorithm.rs
run_returns_an_error_when_the_algorithm_task_panicscrates/libsy/src/core/algorithm.rs
cancelling_run_cancels_the_algorithm_taskcrates/libsy/src/core/algorithm.rs
fall_through.rscrates/libsy/src/algorithms/fall_throu
llm_class.rscrates/libsy/src/algorithms/llm_class.
passthrough.rscrates/libsy/src/algorithms/passthroug
stage.rscrates/libsy/src/algorithms/stage.rs
noop.rscrates/libsy/src/algorithms/noop.rs
rand.rscrates/libsy/src/algorithms/rand.rs

Calls 2

run_streamMethod · 0.80
mapMethod · 0.45

Tested by

no test coverage detected