diff --git a/vendor/go.opentelemetry.io/otel/trace/auto.go b/vendor/go.opentelemetry.io/otel/trace/auto.go
new file mode 100644
index 0000000..f3aa398
--- /dev/null
+++ b/vendor/go.opentelemetry.io/otel/trace/auto.go
@@ -0,0 +1,662 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package trace // import "go.opentelemetry.io/otel/trace"
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"math"
+	"os"
+	"reflect"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"time"
+	"unicode/utf8"
+
+	"go.opentelemetry.io/otel/attribute"
+	"go.opentelemetry.io/otel/codes"
+	semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
+	"go.opentelemetry.io/otel/trace/embedded"
+	"go.opentelemetry.io/otel/trace/internal/telemetry"
+)
+
+// newAutoTracerProvider returns an auto-instrumentable [trace.TracerProvider].
+// If an [go.opentelemetry.io/auto.Instrumentation] is configured to instrument
+// the process using the returned TracerProvider, all of the telemetry it
+// produces will be processed and handled by that Instrumentation. By default,
+// if no Instrumentation instruments the TracerProvider it will not generate
+// any trace telemetry.
+func newAutoTracerProvider() TracerProvider { return tracerProviderInstance }
+
+var tracerProviderInstance = new(autoTracerProvider)
+
+type autoTracerProvider struct{ embedded.TracerProvider }
+
+var _ TracerProvider = autoTracerProvider{}
+
+func (p autoTracerProvider) Tracer(name string, opts ...TracerOption) Tracer {
+	cfg := NewTracerConfig(opts...)
+	return autoTracer{
+		name:      name,
+		version:   cfg.InstrumentationVersion(),
+		schemaURL: cfg.SchemaURL(),
+	}
+}
+
+type autoTracer struct {
+	embedded.Tracer
+
+	name, schemaURL, version string
+}
+
+var _ Tracer = autoTracer{}
+
+func (t autoTracer) Start(ctx context.Context, name string, opts ...SpanStartOption) (context.Context, Span) {
+	var psc, sc SpanContext
+	sampled := true
+	span := new(autoSpan)
+
+	// Ask eBPF for sampling decision and span context info.
+	t.start(ctx, span, &psc, &sampled, &sc)
+
+	span.sampled.Store(sampled)
+	span.spanContext = sc
+
+	ctx = ContextWithSpan(ctx, span)
+
+	if sampled {
+		// Only build traces if sampled.
+		cfg := NewSpanStartConfig(opts...)
+		span.traces, span.span = t.traces(name, cfg, span.spanContext, psc)
+	}
+
+	return ctx, span
+}
+
+// Expected to be implemented in eBPF.
+//
+//go:noinline
+func (t *autoTracer) start(
+	ctx context.Context,
+	spanPtr *autoSpan,
+	psc *SpanContext,
+	sampled *bool,
+	sc *SpanContext,
+) {
+	start(ctx, spanPtr, psc, sampled, sc)
+}
+
+// start is used for testing.
+var start = func(context.Context, *autoSpan, *SpanContext, *bool, *SpanContext) {}
+
+func (t autoTracer) traces(name string, cfg SpanConfig, sc, psc SpanContext) (*telemetry.Traces, *telemetry.Span) {
+	span := &telemetry.Span{
+		TraceID:      telemetry.TraceID(sc.TraceID()),
+		SpanID:       telemetry.SpanID(sc.SpanID()),
+		Flags:        uint32(sc.TraceFlags()),
+		TraceState:   sc.TraceState().String(),
+		ParentSpanID: telemetry.SpanID(psc.SpanID()),
+		Name:         name,
+		Kind:         spanKind(cfg.SpanKind()),
+	}
+
+	span.Attrs, span.DroppedAttrs = convCappedAttrs(maxSpan.Attrs, cfg.Attributes())
+
+	links := cfg.Links()
+	if limit := maxSpan.Links; limit == 0 {
+		n := int64(len(links))
+		if n > 0 {
+			span.DroppedLinks = uint32(min(n, math.MaxUint32)) // nolint: gosec  // Bounds checked.
+		}
+	} else {
+		if limit > 0 {
+			n := int64(max(len(links)-limit, 0))
+			span.DroppedLinks = uint32(min(n, math.MaxUint32)) // nolint: gosec  // Bounds checked.
+			links = links[n:]
+		}
+		span.Links = convLinks(links)
+	}
+
+	if t := cfg.Timestamp(); !t.IsZero() {
+		span.StartTime = cfg.Timestamp()
+	} else {
+		span.StartTime = time.Now()
+	}
+
+	return &telemetry.Traces{
+		ResourceSpans: []*telemetry.ResourceSpans{
+			{
+				ScopeSpans: []*telemetry.ScopeSpans{
+					{
+						Scope: &telemetry.Scope{
+							Name:    t.name,
+							Version: t.version,
+						},
+						Spans:     []*telemetry.Span{span},
+						SchemaURL: t.schemaURL,
+					},
+				},
+			},
+		},
+	}, span
+}
+
+func spanKind(kind SpanKind) telemetry.SpanKind {
+	switch kind {
+	case SpanKindInternal:
+		return telemetry.SpanKindInternal
+	case SpanKindServer:
+		return telemetry.SpanKindServer
+	case SpanKindClient:
+		return telemetry.SpanKindClient
+	case SpanKindProducer:
+		return telemetry.SpanKindProducer
+	case SpanKindConsumer:
+		return telemetry.SpanKindConsumer
+	}
+	return telemetry.SpanKind(0) // undefined.
+}
+
+type autoSpan struct {
+	embedded.Span
+
+	spanContext SpanContext
+	sampled     atomic.Bool
+
+	mu     sync.Mutex
+	traces *telemetry.Traces
+	span   *telemetry.Span
+}
+
+func (s *autoSpan) SpanContext() SpanContext {
+	if s == nil {
+		return SpanContext{}
+	}
+	// s.spanContext is immutable, do not acquire lock s.mu.
+	return s.spanContext
+}
+
+func (s *autoSpan) IsRecording() bool {
+	if s == nil {
+		return false
+	}
+
+	return s.sampled.Load()
+}
+
+func (s *autoSpan) SetStatus(c codes.Code, msg string) {
+	if s == nil || !s.sampled.Load() {
+		return
+	}
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	if s.span.Status == nil {
+		s.span.Status = new(telemetry.Status)
+	}
+
+	s.span.Status.Message = msg
+
+	switch c {
+	case codes.Unset:
+		s.span.Status.Code = telemetry.StatusCodeUnset
+	case codes.Error:
+		s.span.Status.Code = telemetry.StatusCodeError
+	case codes.Ok:
+		s.span.Status.Code = telemetry.StatusCodeOK
+	}
+}
+
+func (s *autoSpan) SetAttributes(attrs ...attribute.KeyValue) {
+	if s == nil || !s.sampled.Load() {
+		return
+	}
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	limit := maxSpan.Attrs
+	if limit == 0 {
+		// No attributes allowed.
+		n := int64(len(attrs))
+		if n > 0 {
+			s.span.DroppedAttrs += uint32(min(n, math.MaxUint32)) // nolint: gosec  // Bounds checked.
+		}
+		return
+	}
+
+	m := make(map[string]int)
+	for i, a := range s.span.Attrs {
+		m[a.Key] = i
+	}
+
+	for _, a := range attrs {
+		val := convAttrValue(a.Value)
+		if val.Empty() {
+			s.span.DroppedAttrs++
+			continue
+		}
+
+		if idx, ok := m[string(a.Key)]; ok {
+			s.span.Attrs[idx] = telemetry.Attr{
+				Key:   string(a.Key),
+				Value: val,
+			}
+		} else if limit < 0 || len(s.span.Attrs) < limit {
+			s.span.Attrs = append(s.span.Attrs, telemetry.Attr{
+				Key:   string(a.Key),
+				Value: val,
+			})
+			m[string(a.Key)] = len(s.span.Attrs) - 1
+		} else {
+			s.span.DroppedAttrs++
+		}
+	}
+}
+
+// convCappedAttrs converts up to limit attrs into a []telemetry.Attr. The
+// number of dropped attributes is also returned.
+func convCappedAttrs(limit int, attrs []attribute.KeyValue) ([]telemetry.Attr, uint32) {
+	n := len(attrs)
+	if limit == 0 {
+		var out uint32
+		if n > 0 {
+			out = uint32(min(int64(n), math.MaxUint32)) // nolint: gosec  // Bounds checked.
+		}
+		return nil, out
+	}
+
+	if limit < 0 {
+		// Unlimited.
+		return convAttrs(attrs), 0
+	}
+
+	if n < 0 {
+		n = 0
+	}
+
+	limit = min(n, limit)
+	return convAttrs(attrs[:limit]), uint32(n - limit) // nolint: gosec  // Bounds checked.
+}
+
+func convAttrs(attrs []attribute.KeyValue) []telemetry.Attr {
+	if len(attrs) == 0 {
+		// Avoid allocations if not necessary.
+		return nil
+	}
+
+	out := make([]telemetry.Attr, 0, len(attrs))
+	for _, attr := range attrs {
+		key := string(attr.Key)
+		val := convAttrValue(attr.Value)
+		if val.Empty() {
+			continue
+		}
+		out = append(out, telemetry.Attr{Key: key, Value: val})
+	}
+	return out
+}
+
+func convAttrValue(value attribute.Value) telemetry.Value {
+	switch value.Type() {
+	case attribute.BOOL:
+		return telemetry.BoolValue(value.AsBool())
+	case attribute.INT64:
+		return telemetry.Int64Value(value.AsInt64())
+	case attribute.FLOAT64:
+		return telemetry.Float64Value(value.AsFloat64())
+	case attribute.STRING:
+		v := truncate(maxSpan.AttrValueLen, value.AsString())
+		return telemetry.StringValue(v)
+	case attribute.BOOLSLICE:
+		slice := value.AsBoolSlice()
+		out := make([]telemetry.Value, 0, len(slice))
+		for _, v := range slice {
+			out = append(out, telemetry.BoolValue(v))
+		}
+		return telemetry.SliceValue(out...)
+	case attribute.INT64SLICE:
+		slice := value.AsInt64Slice()
+		out := make([]telemetry.Value, 0, len(slice))
+		for _, v := range slice {
+			out = append(out, telemetry.Int64Value(v))
+		}
+		return telemetry.SliceValue(out...)
+	case attribute.FLOAT64SLICE:
+		slice := value.AsFloat64Slice()
+		out := make([]telemetry.Value, 0, len(slice))
+		for _, v := range slice {
+			out = append(out, telemetry.Float64Value(v))
+		}
+		return telemetry.SliceValue(out...)
+	case attribute.STRINGSLICE:
+		slice := value.AsStringSlice()
+		out := make([]telemetry.Value, 0, len(slice))
+		for _, v := range slice {
+			v = truncate(maxSpan.AttrValueLen, v)
+			out = append(out, telemetry.StringValue(v))
+		}
+		return telemetry.SliceValue(out...)
+	}
+	return telemetry.Value{}
+}
+
+// truncate returns a truncated version of s such that it contains less than
+// the limit number of characters. Truncation is applied by returning the limit
+// number of valid characters contained in s.
+//
+// If limit is negative, it returns the original string.
+//
+// UTF-8 is supported. When truncating, all invalid characters are dropped
+// before applying truncation.
+//
+// If s already contains less than the limit number of bytes, it is returned
+// unchanged. No invalid characters are removed.
+func truncate(limit int, s string) string {
+	// This prioritize performance in the following order based on the most
+	// common expected use-cases.
+	//
+	//  - Short values less than the default limit (128).
+	//  - Strings with valid encodings that exceed the limit.
+	//  - No limit.
+	//  - Strings with invalid encodings that exceed the limit.
+	if limit < 0 || len(s) <= limit {
+		return s
+	}
+
+	// Optimistically, assume all valid UTF-8.
+	var b strings.Builder
+	count := 0
+	for i, c := range s {
+		if c != utf8.RuneError {
+			count++
+			if count > limit {
+				return s[:i]
+			}
+			continue
+		}
+
+		_, size := utf8.DecodeRuneInString(s[i:])
+		if size == 1 {
+			// Invalid encoding.
+			b.Grow(len(s) - 1)
+			_, _ = b.WriteString(s[:i])
+			s = s[i:]
+			break
+		}
+	}
+
+	// Fast-path, no invalid input.
+	if b.Cap() == 0 {
+		return s
+	}
+
+	// Truncate while validating UTF-8.
+	for i := 0; i < len(s) && count < limit; {
+		c := s[i]
+		if c < utf8.RuneSelf {
+			// Optimization for single byte runes (common case).
+			_ = b.WriteByte(c)
+			i++
+			count++
+			continue
+		}
+
+		_, size := utf8.DecodeRuneInString(s[i:])
+		if size == 1 {
+			// We checked for all 1-byte runes above, this is a RuneError.
+			i++
+			continue
+		}
+
+		_, _ = b.WriteString(s[i : i+size])
+		i += size
+		count++
+	}
+
+	return b.String()
+}
+
+func (s *autoSpan) End(opts ...SpanEndOption) {
+	if s == nil || !s.sampled.Swap(false) {
+		return
+	}
+
+	// s.end exists so the lock (s.mu) is not held while s.ended is called.
+	s.ended(s.end(opts))
+}
+
+func (s *autoSpan) end(opts []SpanEndOption) []byte {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	cfg := NewSpanEndConfig(opts...)
+	if t := cfg.Timestamp(); !t.IsZero() {
+		s.span.EndTime = cfg.Timestamp()
+	} else {
+		s.span.EndTime = time.Now()
+	}
+
+	b, _ := json.Marshal(s.traces) // TODO: do not ignore this error.
+	return b
+}
+
+// Expected to be implemented in eBPF.
+//
+//go:noinline
+func (*autoSpan) ended(buf []byte) { ended(buf) }
+
+// ended is used for testing.
+var ended = func([]byte) {}
+
+func (s *autoSpan) RecordError(err error, opts ...EventOption) {
+	if s == nil || err == nil || !s.sampled.Load() {
+		return
+	}
+
+	cfg := NewEventConfig(opts...)
+
+	attrs := cfg.Attributes()
+	attrs = append(attrs,
+		semconv.ExceptionType(typeStr(err)),
+		semconv.ExceptionMessage(err.Error()),
+	)
+	if cfg.StackTrace() {
+		buf := make([]byte, 2048)
+		n := runtime.Stack(buf, false)
+		attrs = append(attrs, semconv.ExceptionStacktrace(string(buf[0:n])))
+	}
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	s.addEvent(semconv.ExceptionEventName, cfg.Timestamp(), attrs)
+}
+
+func typeStr(i any) string {
+	t := reflect.TypeOf(i)
+	if t.PkgPath() == "" && t.Name() == "" {
+		// Likely a builtin type.
+		return t.String()
+	}
+	return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name())
+}
+
+func (s *autoSpan) AddEvent(name string, opts ...EventOption) {
+	if s == nil || !s.sampled.Load() {
+		return
+	}
+
+	cfg := NewEventConfig(opts...)
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	s.addEvent(name, cfg.Timestamp(), cfg.Attributes())
+}
+
+// addEvent adds an event with name and attrs at tStamp to the span. The span
+// lock (s.mu) needs to be held by the caller.
+func (s *autoSpan) addEvent(name string, tStamp time.Time, attrs []attribute.KeyValue) {
+	limit := maxSpan.Events
+
+	if limit == 0 {
+		s.span.DroppedEvents++
+		return
+	}
+
+	if limit > 0 && len(s.span.Events) == limit {
+		// Drop head while avoiding allocation of more capacity.
+		copy(s.span.Events[:limit-1], s.span.Events[1:])
+		s.span.Events = s.span.Events[:limit-1]
+		s.span.DroppedEvents++
+	}
+
+	e := &telemetry.SpanEvent{Time: tStamp, Name: name}
+	e.Attrs, e.DroppedAttrs = convCappedAttrs(maxSpan.EventAttrs, attrs)
+
+	s.span.Events = append(s.span.Events, e)
+}
+
+func (s *autoSpan) AddLink(link Link) {
+	if s == nil || !s.sampled.Load() {
+		return
+	}
+
+	l := maxSpan.Links
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	if l == 0 {
+		s.span.DroppedLinks++
+		return
+	}
+
+	if l > 0 && len(s.span.Links) == l {
+		// Drop head while avoiding allocation of more capacity.
+		copy(s.span.Links[:l-1], s.span.Links[1:])
+		s.span.Links = s.span.Links[:l-1]
+		s.span.DroppedLinks++
+	}
+
+	s.span.Links = append(s.span.Links, convLink(link))
+}
+
+func convLinks(links []Link) []*telemetry.SpanLink {
+	out := make([]*telemetry.SpanLink, 0, len(links))
+	for _, link := range links {
+		out = append(out, convLink(link))
+	}
+	return out
+}
+
+func convLink(link Link) *telemetry.SpanLink {
+	l := &telemetry.SpanLink{
+		TraceID:    telemetry.TraceID(link.SpanContext.TraceID()),
+		SpanID:     telemetry.SpanID(link.SpanContext.SpanID()),
+		TraceState: link.SpanContext.TraceState().String(),
+		Flags:      uint32(link.SpanContext.TraceFlags()),
+	}
+	l.Attrs, l.DroppedAttrs = convCappedAttrs(maxSpan.LinkAttrs, link.Attributes)
+
+	return l
+}
+
+func (s *autoSpan) SetName(name string) {
+	if s == nil || !s.sampled.Load() {
+		return
+	}
+
+	s.mu.Lock()
+	defer s.mu.Unlock()
+
+	s.span.Name = name
+}
+
+func (*autoSpan) TracerProvider() TracerProvider { return newAutoTracerProvider() }
+
+// maxSpan are the span limits resolved during startup.
+var maxSpan = newSpanLimits()
+
+type spanLimits struct {
+	// Attrs is the number of allowed attributes for a span.
+	//
+	// This is resolved from the environment variable value for the
+	// OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT key if it exists. Otherwise, the
+	// environment variable value for OTEL_ATTRIBUTE_COUNT_LIMIT, or 128 if
+	// that is not set, is used.
+	Attrs int
+	// AttrValueLen is the maximum attribute value length allowed for a span.
+	//
+	// This is resolved from the environment variable value for the
+	// OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT key if it exists. Otherwise, the
+	// environment variable value for OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, or -1
+	// if that is not set, is used.
+	AttrValueLen int
+	// Events is the number of allowed events for a span.
+	//
+	// This is resolved from the environment variable value for the
+	// OTEL_SPAN_EVENT_COUNT_LIMIT key, or 128 is used if that is not set.
+	Events int
+	// EventAttrs is the number of allowed attributes for a span event.
+	//
+	// The is resolved from the environment variable value for the
+	// OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT key, or 128 is used if that is not set.
+	EventAttrs int
+	// Links is the number of allowed Links for a span.
+	//
+	// This is resolved from the environment variable value for the
+	// OTEL_SPAN_LINK_COUNT_LIMIT, or 128 is used if that is not set.
+	Links int
+	// LinkAttrs is the number of allowed attributes for a span link.
+	//
+	// This is resolved from the environment variable value for the
+	// OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, or 128 is used if that is not set.
+	LinkAttrs int
+}
+
+func newSpanLimits() spanLimits {
+	return spanLimits{
+		Attrs: firstEnv(
+			128,
+			"OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT",
+			"OTEL_ATTRIBUTE_COUNT_LIMIT",
+		),
+		AttrValueLen: firstEnv(
+			-1, // Unlimited.
+			"OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT",
+			"OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT",
+		),
+		Events:     firstEnv(128, "OTEL_SPAN_EVENT_COUNT_LIMIT"),
+		EventAttrs: firstEnv(128, "OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT"),
+		Links:      firstEnv(128, "OTEL_SPAN_LINK_COUNT_LIMIT"),
+		LinkAttrs:  firstEnv(128, "OTEL_LINK_ATTRIBUTE_COUNT_LIMIT"),
+	}
+}
+
+// firstEnv returns the parsed integer value of the first matching environment
+// variable from keys. The defaultVal is returned if the value is not an
+// integer or no match is found.
+func firstEnv(defaultVal int, keys ...string) int {
+	for _, key := range keys {
+		strV := os.Getenv(key)
+		if strV == "" {
+			continue
+		}
+
+		v, err := strconv.Atoi(strV)
+		if err == nil {
+			return v
+		}
+		// Ignore invalid environment variable.
+	}
+
+	return defaultVal
+}
