Documentation
¶
Overview ¶
Package chat instruments Core chat capabilities with OpenTelemetry.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidConfig = errors.New("otel/chat: invalid config") ErrNilStream = errors.New("otel/chat: nil stream sequence") )
Functions ¶
This section is empty.
Types ¶
type Middleware ¶
type Middleware struct {
// contains filtered or unexported fields
}
Middleware adds GenAI spans, metrics, and exception events to synchronous and streaming chat capabilities. It is immutable after construction and safe for concurrent use.
func NewMiddleware ¶
func NewMiddleware(config MiddlewareConfig) (Middleware, error)
NewMiddleware fixes instrument identity and provider binding once so every model request contributes to the same telemetry series.
func (Middleware) Call ¶
func (m Middleware) Call(next corechat.Model) corechat.Model
Call is a corechat.CallMiddleware. It preserves the wrapped model's response and error exactly; observation is a read-only side effect.
Example ¶
package main
import (
"context"
"fmt"
corechat "github.com/Tangerg/scope/core/chat"
otelchat "github.com/Tangerg/scope/otel/chat"
)
func main() {
middleware, err := otelchat.NewMiddleware(otelchat.MiddlewareConfig{Provider: "example"})
if err != nil {
panic(err)
}
model := middleware.Call(corechat.ModelFunc(func(context.Context, *corechat.Request) (*corechat.Response, error) {
message := corechat.NewAssistantMessage(corechat.NewTextPart("instrumented"))
output, outputErr := corechat.NewOutput(&message, corechat.FinishReasonStop, nil)
if outputErr != nil {
return nil, outputErr
}
return corechat.NewResponse(output, nil)
}))
request, err := corechat.NewRequest(corechat.NewUserMessage(corechat.NewTextPart("hello")))
if err != nil {
panic(err)
}
response, err := model.Call(context.Background(), request)
if err != nil {
panic(err)
}
fmt.Println(response.Text())
}
Output: instrumented
func (Middleware) Stream ¶
func (m Middleware) Stream(next corechat.Streamer) corechat.Streamer
Stream is a corechat.StreamMiddleware. Instrumentation starts lazily when the caller iterates and ends synchronously on completion, provider failure, or early consumer stop. Deltas are forwarded unchanged. Only identity, cumulative usage, finish reason, and arrival times are observed; content is never buffered or assembled into a second response. Each non-nil delta is a received chunk, including metadata-only increments. Known usage survives an incomplete stream.
type MiddlewareConfig ¶
type MiddlewareConfig struct {
Provider string
TracerProvider trace.TracerProvider
MeterProvider metric.MeterProvider
// LoggerProvider receives GenAI exception events. Nil uses the global provider.
LoggerProvider log.LoggerProvider
}
MiddlewareConfig identifies the remote GenAI provider and optionally supplies providers scoped to this middleware. Provider is normalized to lowercase so span and metric dimensions remain stable. The global OpenTelemetry providers are used when a signal provider is nil.
func (MiddlewareConfig) Validate ¶
func (m MiddlewareConfig) Validate() error