Skip to content
anecticoDocsDashboard
Browse documentation
Reference

Go SDK API

Interfaces, functions, options, parameters, return values, and helpers for the Anectico Go SDK.

On this page

This is the application-developer API for github.com/anectico/anectico/sdks/go. The SDK is safe for concurrent use and follows Go/OpenTelemetry context conventions.

Use ingest:write for traces, metrics, logs, and errors. Add analytics:write for identity, groups, events, and flag exposures; add flags:read for decisions.

Construct and run a client

client, err := anectico.New(
	 anectico.WithAPIKey(os.Getenv("ANECTICO_API_KEY")),
	 anectico.WithServiceName("orders-api"),
)
if err != nil {
	return err
}
if err := client.Start(ctx); err != nil {
	return err
}
defer client.Stop(shutdownCtx)
API Parameters Returns Behavior
New(opts ...Option) functional options (Client, error) Creates an unstarted client or returns a configuration or transport-initialization error.
Start(ctx) lifecycle context error Validates config and starts enabled transports.
Stop(ctx) deadline/cancellation context error Marks the client non-running, flushes, and releases client-owned providers. Final trace, metric, or log upload failures are returned. Concurrent calls share one terminal result.
IsRunning() — bool Whether the client accepts telemetry.
Health() — HealthStatus State, recent errors, uptime, and per-signal counters.
Stats() — ClientStats Processed/dropped/export-failure counters and timestamps.

The first Stop caller owns the transport shutdown, bounded by the earlier of its context deadline and ShutdownTimeout. Other callers wait for that operation and receive the identical completed error or nil. If a waiter's context ends first, only that wait returns ctx.Err(); the owner continues the shared shutdown. Calls made after completion return the cached terminal result. Start waits for an in-flight stop before beginning a fresh lifecycle, at which point the next Stop creates a new operation.

For signal-driven or fatal shutdown, catch SIGTERM or os.Interrupt, call Stop with a bounded context, and inspect its error before exiting. Deferred calls do not run after os.Exit. SIGKILL is not catchable and therefore has no final-flush guarantee; configure the process supervisor's termination grace period to cover the shutdown deadline.

Keep one client per service. Pass request contexts through all instrumentation so trace and person correlation remain intact.

Core Client methods

Method Parameters Returns Behavior
Tracer() — OTel trace.Tracer Underlying tracer for advanced instrumentation.
Meter() — OTel metric.Meter Underlying meter for advanced instrumentation.
Logger() — *slog.Logger Structured logger backed by the Anectico log provider. Use context-aware methods for request work.
StartSpan(ctx, name, opts...) context; name; OTel options (context.Context, trace.Span) Starts a span and returns the child context. Caller must end the span.
RecordMetric(name, value, labels) name; float; string map — Records one gauge value and caches the instrument by name. It has no context parameter.
LogEvent(level, message, attrs...) slog.Level; message; attributes — Convenience log using a background context. Use Logger().LogAttrs(ctx, ...) for correlation.
RecordLLMCall(ctx, opts) context; LLMCallOptions — Records one completed model call as a gen_ai span and directly attaches the resolved anectico.distinct_id, including with a caller-supplied tracer provider.
RecordToolCall(ctx, name, opts) context; tool name/options — Records one completed tool execution.
StartAgentRun(ctx, agent, opts) context; agent name/options (context.Context, AgentRun) Starts an agent span and returns its child context plus a safe handle. Call run.End(status, reasonCode); the first valid terminal outcome wins.
WrapHTTPClient(client) *http.Client *http.Client Returns a client that propagates trace and Anectico identity context. Its generated transport spans are Issue-suppressed; restrict its destinations.
WrapHTTPTransport(base) http.RoundTripper http.RoundTripper Wraps a transport for outbound propagation/instrumentation and Issue-suppresses its generated client spans.
GRPCDialOptions() — []grpc.DialOption Installs the client stats handler for gRPC tracing and propagation.

LLMCallOptions.Model is required. Other fields are ResponseModel, Provider, Operation, token counts, CostUSD, FinishReason, IsError, StartTime, and EndTime. Messages and Output are opt-in content. ToolCallOptions provides Type, CallID, ConversationID, AgentName, IsError, and opt-in Arguments/Result. AgentRunOptions provides AgentID, AgentVersion, and ConversationID. Set AgentVersion to the release label you deploy; it is optional and is emitted as the standard gen_ai.agent.version span attribute. Agent-run status is completed, failed, timed_out, cancelled, or max_steps. The optional reason is normalized to a lowercase code matching [a-z][a-z0-9_]{0,63}; free text is rejected. Calling run.Span().End() directly bypasses this contract and produces only the legacy inferred status, so use run.End(...) for normal completion.

Context assembly events

AgentRun exposes RecordContextAssembly(modelCtx, value), RecordContextCompaction(modelCtx, value), and RecordContextCache(modelCtx, value). Go requires the explicit model context because OpenTelemetry Go has no ambient current-span API. The context must contain a recording model span in the same trace with gen_ai.operation.name equal to chat, text_completion, generate_content, embeddings, or fetch_response; the SDK refuses the run span, a tool span, an ended span, and an absent span.

runCtx, run := client.StartAgentRun(ctx, "support-planner", anectico.AgentRunOptions{})
modelCtx, modelSpan := client.Tracer().Start(runCtx, "chat gpt-4o",
	trace.WithSpanKind(trace.SpanKindClient),
	trace.WithAttributes(attribute.String("gen_ai.operation.name", "chat")),
)
err := run.RecordContextAssembly(modelCtx, anectico.ContextAssembly{
	BudgetTokens: 8192, ReservedOutputTokens: 1024, AssembledTokens: 6144,
	Overflow: "none", AssemblySHA256: assemblySHA256,
	Sources: []anectico.ContextSource{{
		Kind: "memory", ID: "memory:item-7", Sensitivity: "confidential",
		Tokens: 512, Position: 3, Visibility: "included",
	}},
})
modelSpan.End()
_ = run.End(anectico.AgentRunCompleted, "completed")

All values are validated against the context event bounds before the event is attached, so an error records nothing. Compaction ratio is not a producer field; the server derives it from before/after tokens. Provider wrappers add cache hit/miss events automatically when OpenAI or Anthropic reports cache fields. An absent provider field produces no event; a reported zero produces a miss.

Package-level WrapHTTPClient, WrapHTTPTransport, GRPCDialOptions, and GRPCClientStatsHandler provide the same integration helpers when a Client reference is not available.

Errors, messages, users, and breadcrumbs

Breadcrumbs snapshot nested JSON data when added. If optional data cannot be serialized, the breadcrumb is retained without that data so error reporting can still include the trail.

Method Parameters Returns Behavior
CaptureError(ctx, err, opts...) context; error; ErrorOptions string Captures an error and returns its generated ID; returns empty when capture is unavailable/sampled out.
CaptureMessage(ctx, message, level, opts...) context; text; ErrorLevel; options string Captures a diagnostic message.
AddBreadcrumb(category, message, opts...) category/message; breadcrumb options — Buffers trail context for the next captured error.
SetUser(user) *User — Sets process-global error user context.
GetUser(ctx) request context *User Returns context-local user first, then global user.
ClearUser() — — Clears global error user context.

User contains ID, Email, Username, IPAddress, Segment, and Data. Use ContextWithUser(ctx, user) for concurrent request-local error context.

Error option Purpose
WithLevel Override debug, info, warning, error, or fatal.
WithTag Add one indexed tag.
WithTags Add multiple indexed tags.
WithExtra(key, value) Add one unindexed context value.
WithErrorExtra(map) Add several unindexed context values in one option.
WithUser Override user for one capture.
WithFingerprint(parts...) Override grouping; comma separates components and {{default}} includes automatic grouping.
WithStackTrace(pcs) Supply program counters rather than capture the current stack.
WithErrorTimestamp(time) Supply the event timestamp.

WithTag and WithTags keys are encoded as indexed anectico.tag.* telemetry attributes automatically. Capture severity is also indexed as error.level for Issue filtering and context.

WithBreadcrumbLevel(level) sets severity and WithBreadcrumbData(map) attaches structured breadcrumb context.

Identity and groups

API Parameters Returns Behavior
client.Identify(ctx, distinctID, props) context; stable ID; person properties error Sets shared identity and queues the identity event for background delivery with retries.
client.Group(ctx, groupType, groupKey, props) context; account type/key; properties error Records membership and $groupidentify.
client.Reset(ctx) context error Logout: rotates anonymous identity and clears groups, global error-user context, and uncaptured breadcrumbs. Already-captured telemetry remains queued with its original attribution.
ContextWithDistinctID(ctx, id) context; stable ID context.Context Sets request-local identity for concurrency-safe server work.
DistinctIDFromContext(ctx) context (string, bool) Reads request-local identity.
AdoptDistinctIDFromBaggage(ctx) context context Promotes trusted inbound baggage into request scope.
DiscardDistinctIDFromBaggage(ctx) context context Removes untrusted Anectico identity baggage while preserving other context.

Never adopt a public client's identity baggage until a trusted gateway has authenticated the request and recreated that baggage.

Diagnostic events: Analytics

Capture snapshots event properties when enqueueing. Later mutations do not change queued events. Properties must be JSON-serializable; capture returns an error for invalid events before they enter the queue. The built-in analytics and feature-flag HTTP clients do not follow redirects: configure the final API endpoint directly so project credentials stay at that endpoint.

events, err := anectico.NewAnalytics(anectico.AnalyticsConfig{
	Endpoint: "https://api.anectico.com",
	APIKey:   os.Getenv("ANECTICO_API_KEY"),
})
if err != nil {
	return err
}
defer func() { _ = events.Stop(ctx) }()

AnalyticsConfig fields are Endpoint, APIKey, FlushAt (default 20), Interval (zero means 5 seconds; negative disables the timer), and optional HTTPClient (default timeout 10 seconds).

Release and AppVersion are stamped as the reserved $release/$app_version string properties on every Capture'd event when set; the SDK never auto-detects a server deployment's version, so set them yourself from your own deploy pipeline (for example, reading your own ANECTICO_RELEASE environment variable in application code — this package never reads the environment itself). Leave them unset and the properties are omitted entirely, never sent as "". See Reserved event properties.

API Parameters Returns Behavior
NewAnalytics(config) AnalyticsConfig (*Analytics, error) Validates the absolute endpoint and API key, then starts a background flusher using a background lifecycle context. AnalyticsConfig also takes an optional Logger and an OnDeliveryError handler.
NewAnalyticsWithContext(ctx, config) lifecycle context/config (*Analytics, error) Validates configuration and stops the background flusher when context is canceled; still call Stop to flush.
Capture(ctx, event, props, opts...) context; name; properties; capture options error Queues an event using the call override, request context/baggage, then shared identity.
Identify(ctx, distinctID, props, opts...) context; ID; properties; options error Queues an identity merge without changing process-global identity; safe for multi-person server batches.
Group(ctx, type, key, props, opts...) context; group; properties; options error Queues membership for the resolved person; changes shared groups only for the shared person.
Flush(ctx) deadline context error Sends queued events in chunks. Returns nil only when every batch it sent was accepted; an empty queue is nil. Returns ErrAnalyticsDropped for explicit refusals and ErrAnalyticsRetryPending for uncertain/retryable items; a mixed ledger or separate chunks in one flush can match both.
Stats() — AnalyticsStats Recorded, Delivered, Dropped, Queued. Delivered counts queue-acknowledged attempts; Dropped counts explicit refusals/local discards; Queued includes uncertain items retained for retry.
Reset(ctx) context error Attempts to flush, then rotates shared anonymous identity even on delivery failure; retained events keep their original attribution.
Stop(ctx) deadline context error Stops the flusher and sends the remaining queue, returning what that final flush returned. Capture after stop returns ErrAnalyticsClosed.
Disable() — — Immediately closes analytics collection and discards pending work without a final flush; active delivery settles separately.

Flush validates the complete version 1 capture acknowledgement. Use both errors.Is(err, ErrAnalyticsDropped) and errors.Is(err, ErrAnalyticsRetryPending): a mixed ledger can contain refused items and uncertain siblings, and a later chunk can fail after an earlier chunk was refused. Both cases preserve the two error classifications. Check Stats() for their counts. Queued items are never resent. Uncertain items retain their original message ID, timestamp, identity and payload and wait at least one second (or the bounded server Retry-After) before retry. Malformed/unrecognized responses remain uncertain, including HTTP 2xx and unrecognized 4xx bodies.

Stop(ctx) performs a final flush. For collection withdrawal, call Disable() instead: collection closes immediately and pending events are discarded with collection_disabled. Further Capture/Identify/Group calls return ErrAnalyticsClosed. Disable is nonblocking and safe in a delivery callback; call Flush(ctx) outside callbacks to wait for an active request to settle, then inspect Stats. A chunk already admitted to delivery may still reach the server; its validated acceptance/refusal counts remain, but uncertain positions and later chunks are never retried. A flush that discards work matches ErrAnalyticsDropped, without a pending-retry classification for those positions. After settlement, Queued is zero. Repeated Disable is safe; new consent requires a new Analytics instance. This does not erase stored events or disable separate telemetry clients. Gate collection before initialization where your application requires it.

Explicit refusals are reported through OnDeliveryError, Stats().Dropped and a WARN log. The callback runs once for a chunk's refused portion and excludes its uncertain siblings. DeliveryError.Reason includes invalid_event, quota_exceeded, mixed_rejection, request-failure reasons such as unauthorized and bad_request, and local queue_overflow, not_serializable or collection_disabled. Fix the input, credentials or quota condition before resubmitting a refused event. A callback panic is recovered. Delivered proves a queue acknowledgement, not storage visibility, a unique stored occurrence or a completed identity mutation.

events, err := anectico.NewAnalytics(anectico.AnalyticsConfig{
    Endpoint: "https://api.anectico.com",
    APIKey:   os.Getenv("ANECTICO_API_KEY"),
    OnDeliveryError: func(e anectico.DeliveryError) {
        myAlerting.Warnf("anectico dropped %d events: %d %s", e.Dropped, e.Status, e.Reason)
    },
})

Capture inherits shared $groups only when its resolved person matches the shared identity. Explicit $groups in event properties take precedence. For concurrent requests, pass request-local identity and event-local groups. Identify sends no anonymous alias unless WithAnonDistinctID is supplied, so independent server-side imports do not merge through a shared anonymous ID.

A partial ledger updates Delivered only for queued items and Dropped only for explicit refusals. Unknown items remain in Queued. An HTTP 200 can contain all three outcomes.

Analytics and flag endpoints must be absolute HTTP(S) base URLs without credentials, query strings, or fragments. Remote flags validate before sending; local flags validate during construction.

Per-call options are WithDistinctID, WithAnonDistinctID, and WithSessionID. Use WithAnonDistinctID when each server-side merge has its own anonymous alias. For a stateful single-user/client application that should switch the shared identity used by later signals, call client.Identify instead.

Feature flags: Flags

Bootstrap data and returned payload containers are copied. Exposure deduplication distinguishes identity, flag name, and the response's type and value. Remote decision responses must contain one JSON document of at most 16 MiB, with boolean or string flag values. Invalid responses preserve the last valid cache; overlapping reloads allow only the latest invocation to replace it.

FlagsConfig fields are Endpoint, APIKey, optional HTTPClient, optional Bootstrap, and an optional Capture(ctx, event, props, distinctID) callback for exposures. The key needs flags:read; the exposure callback usually calls Analytics.Capture and therefore needs analytics:write.

Method Parameters Returns Behavior
NewFlags(config) FlagsConfig *Flags Builds a concurrency-safe in-memory decision client.
Reload(ctx, distinctID, personProperties, groups) targeting context error Calls /api/v1/decide; nil groups use shared memberships.
GetFeatureFlag(ctx, key, distinctID) context; key; ID any Returns bool/variant/nil and emits one deduplicated exposure.
IsFeatureEnabled(ctx, key, distinctID) context; key; ID bool True for true or a non-empty string variant.
GetFeatureFlagPayload(key) key json.RawMessage Returns a copy of the payload or nil.
GetAllFlags() — map[string]any Returns a copy of cached decisions.
HadEvaluationErrors() — bool Whether the last decision used a fallback.
Reset() — — Clears exposure dedup after identity changes.
NewLocalFlagsClient(config) LocalFlagsConfig{Endpoint, APIKey, ProjectID, HTTPClient?, Capture?, Now?} (*LocalFlagsClient, error) Creates one exact-project cache; snapshot reads require flags:read, and an Anectico-backed Capture requires analytics:write.
LocalFlagsClient.Refresh(ctx) context (LocalRefreshStatus, error) Fetches or conditionally revalidates a strict, bounded snapshot while retaining the last-known-good cache on failure.
LocalFlagsClient.Evaluate(ctx, key, distinctID, personProperties) context, flag key, exact identity, person properties LocalEvaluationResult Evaluates only a fresh snapshot and emits a successful exposure through optional Capture.
LocalFlagsClient.Reset() — — Clears local (identity,key,value) exposure deduplication; preserves the snapshot.

NewLocalFlagsClient(LocalFlagsConfig) creates the project-bound server-side evaluator; ProjectID must be one exact canonical UUID. Refresh(ctx) uses strong conditional validators and serializes concurrent refreshes. Evaluate(ctx, key, distinctID, personProperties) returns a LocalEvaluationResult and fails closed when the snapshot is missing/stale, the identity is empty, or the rule requires authoritative cohort/group data. LocalFlagsConfig.Capture mirrors FlagsConfig.Capture: successful matched/default decisions emit $feature_flag_called once per identity/key/value, and Reset() reopens the dedup set without dropping the snapshot. A callback wired to Analytics.Capture also requires analytics:write.

Configuration options

Explicit service name/version options take precedence over their environment defaults. An explicitly empty service name is invalid. Signal-specific and authentication headers override general headers case-insensitively. Integer millisecond environment values that overflow time.Duration fall back to the setting's default.

Options apply in order. WithConfig(config) is normally first; later options override its fields.

Option family Functions and effect
Identity WithServiceName, WithServiceVersion, WithEnvironment, WithProjectID.
Authentication WithAPIKey selects API-key auth; WithJWTToken selects JWT auth. Application integrations should use a project API key.
Endpoint/transport WithEndpoint, WithProtocol("http"|"grpc") (default "http"; "grpc" is opt-in for a self-hosted or tunneled deployment), WithInsecure, WithHeaders, WithHeader.
TLS WithTLS, WithTLSCerts(cert,key,ca), WithTLSCA, WithTLSServerName; WithInsecureTLS skips verification and is development-only.
Batching WithBatchTimeout, WithBatchSize, WithMaxQueueSize, WithExportTimeout, WithShutdownTimeout, WithRetryConfig.
Signals/sampling WithTraceSampleRate, WithTraces, WithMetrics, WithLogs, WithAllTelemetry.
Diagnostics WithDebug, WithLogLevel, WithLogOutput.
Resources WithResourceAttribute, WithResourceAttributes.
Errors WithErrorCapture, WithErrorSampleRate, WithMaxStackTraceFrames, WithAttachStackTrace, WithErrorEnvironment, WithErrorRelease.
Providers WithTracerProvider uses a caller-owned OTel provider and enables traces; the caller shuts it down after the Anectico client.
Presets WithProductionDefaults, WithDevelopmentDefaults, WithTestingDefaults, WithKubernetesDefaults, WithDockerDefaults. Apply a preset before options that should override it.

Defaults include the HTTP transport, a 10% trace sample rate, 100% captured errors, batch size 512, queue size 2048, 5-second batch/shutdown timeouts, 30-second exports, and three retry attempts. DefaultConfig() reads the equivalent ANECTICO_* and OTEL_* environment variables (including OTEL_EXPORTER_OTLP_PROTOCOL, which also accepts the OTel-standard http/protobuf spelling as an alias for http); Config.Validate() checks required values and bounds.

The selected authentication mode must have its matching credential: API-key mode requires an API key and JWT mode requires a JWT. Sampling rates reject NaN and infinity as well as values outside 0–1.

Managed Go providers attach the standard OpenTelemetry SDK resource identity to every trace, metric, and log: telemetry.sdk.language=go, telemetry.sdk.name=opentelemetry, and the active OpenTelemetry Go SDK version in telemetry.sdk.version. These reserved attributes describe the emitting SDK and cannot be overridden with WithResourceAttribute(s). Anectico does not implicitly enable host or process resource detectors; add any reviewed infrastructure attributes explicitly.

The managed tracer provider uses parent-based sampling: local and remote child spans preserve the parent's sampled or unsampled W3C decision, while WithTraceSampleRate applies only to new root traces. error.capture and message.capture spans are always retained so explicit error/message capture is not lost when ordinary traces are sampled out. WithTracerProvider remains fully caller-owned; Anectico neither replaces its sampler nor applies these managed-provider rules.

Authentication and error helpers

ValidateAPIKey, IsAPIKeyFormat, and MaskAPIKey support configuration UIs. IsAuthError, IsNetworkError, IsRetryableError, GetErrorSuggestion, and WrapGRPCError support custom transports. Prefer returning these errors rather than matching their strings.

Advanced configuration and utility API

API Parameters Returns/behavior
DefaultConfig() — *Config populated from supported ANECTICO_*/OTEL_* variables and safe defaults.
config.Validate() — error for missing credentials/identity or inconsistent protocol, sampling, queues, timeouts, and TLS.
config.GetEndpointForSignal(signal) traces, metrics, or logs Signal-specific OTLP endpoint.
config.GetHeadersForSignal(signal) signal name Copy of headers including active authentication.
config.Logger() — SDK diagnostic *slog.Logger.
NewTransport(config) validated *Config (Transport, error) for custom lifecycle ownership; most applications should use Client.
TLSConfig.Validate() — Rejects incomplete certificate pairs and unsafe/inconsistent TLS bounds.
TLSConfig.GetStandardTLSConfig() — (*tls.Config, error) for HTTP transports.
TLSConfig.GetTLSCredentials() — (credentials.TransportCredentials, error) for gRPC.
ContextWithUser(ctx, user) context; *User Request-local error user.
UserFromContext(ctx) context Request-local *User or nil.
user.ToOTelAttributes() — OpenTelemetry enduser.* and user.data.* attributes.
CaptureStackTrace(skip) number of caller frames to skip Structured []StackFrame for a custom error integration.
GetPoolStats() / ResetPoolStats() — SDK allocation-pool counters, and a test/debug reset.

Config exposes the same fields represented by the functional options: service identity, credentials, endpoint/protocol/headers/TLS, batch and retry values, signal switches, sampling, logging, resources, and error settings. TLSConfig additionally accepts Enabled, InsecureSkipVerify, certificate/key/CA files, ServerName, TLS version bounds, and cipher suites. The package's typed sentinel errors (ErrUnauthorized, ErrForbidden, ErrInvalidAPIKey, ErrExpiredToken, ErrRateLimited, ErrInvalidCredentials, ErrConnectionFailed, ErrTimeout, and ErrServiceUnavailable) are compatible with errors.Is.

Framework and model-provider packages

Package/API Parameters Returns Behavior
instrumentation/openai.WrapClient(anecticoClient, client, opts...) Anectico client; official OpenAI client; options instrumented client Wraps Chat.Completions.New and NewStreaming calls while preserving provider responses, chunks, errors, and stream iteration.
instrumentation/openai.WithCaptureContent() — wrapper option Opts into prompt/completion content; off by default.
instrumentation/anthropic.WrapClient(anecticoClient, client, opts...) Anectico client; official Anthropic client; options instrumented client Wraps Messages.New and NewStreaming calls while preserving provider results, events, errors, and stream iteration.
instrumentation/anthropic.WithCaptureContent() — wrapper option Opts into prompt/completion content; off by default.
instrumentation/gin.Middleware(client) / MiddlewareWithOptions(client, opts) Anectico client; optional Options Gin handler Creates inbound request spans and request-scoped propagation, captures c.Errors, and captures handler panics recovered by Gin as one canonical Issue occurrence.
instrumentation/echo.Middleware(client) / MiddlewareWithOptions(client, opts) Anectico client; optional Options Echo middleware Creates inbound request spans and request-scoped propagation. DefaultSkipper is the exported standard skip predicate.
instrumentation/fiber.Middleware(client) / MiddlewareWithOptions(client, opts) Anectico client; optional Options Fiber handler Creates inbound request spans and request-scoped propagation. DefaultNext skips standard health paths; GetSpan(ctx) reads the active request span.
instrumentation/grpc.UnaryServerInterceptor(client) / UnaryServerInterceptorWithOptions(client, opts) client; optional ServerOptions unary server interceptor Extracts trace context, creates the server span, and optionally adopts trusted identity.
instrumentation/grpc.StreamServerInterceptor(client) / StreamServerInterceptorWithOptions(client, opts) client; optional ServerOptions stream server interceptor Instruments stream lifetime and propagation.
instrumentation/grpc.UnaryClientInterceptor(client) / StreamClientInterceptor(client) client client interceptor Copies existing metadata, injects W3C trace/identity context, and traces RPCs. Stream completion is idempotent; transport errors remain spans rather than duplicate Issues.
instrumentation/grpc.CombinedServerInterceptors(client) client []grpc.ServerOption Installs both server interceptors.
instrumentation/grpc.CombinedClientInterceptors(client) client []grpc.DialOption Installs both client interceptors.

Both NewStreaming wrappers keep the official Next/Current/Err/Close flow and record one model call when the stream is exhausted, fails, or is abandoned. Always close the stream, normally with defer stream.Close().

Closing before the stream finished, or cancelling its context, is not an error: the call happened and was billed, so the span keeps its normal status and carries anectico.gen_ai.stream.abandoned = true instead. That keeps deliberate early exits out of your error rate while remaining distinguishable; the token counts on such a span are the provider's last reported values and are partial by construction. Provider stream failures, a Close error, and an expiring deadline record one error-status model call.

Neither wrapper changes your request. stream_options.include_usage is never set for you — doing so appends a terminal empty-Choices chunk that panics the usual chunk.Choices[0] loop, and is rejected outright by some OpenAI-compatible gateways — so set StreamOptions.IncludeUsage yourself when you want streaming token counts from OpenAI. Anthropic needs no such parameter: its usage arrives on message_start and message_delta. A count the provider never reported is recorded as absent, never as zero. Content capture can record sensitive text and remains off unless WithCaptureContent is supplied.

Gin Options supports TrustIncomingIdentity, SkipPaths, request/response body capture, MaxBodySize, custom attributes, span naming, filtering, captured-header allowlists, and sensitive header redaction. Gin Recovery can be registered before or after Anectico; the configured recovery still controls the response. Registering Recovery first (the gin.Default() order) retains the original panic value in Anectico. When Recovery is inside Anectico, Gin has already discarded that value, so Anectico records a generic panic message with the handler stack. In both orders, the failed server span stays visible and correlated in Traces while the stacked error.capture child is the only Issue occurrence. Echo provides the same controls through Skipper (rather than SkipPaths and a filter). Fiber supports Next, custom attributes, span naming, and header controls. Every HTTP package exports WithSkipHealthCheck() and WithCaptureAllHeaders() presets. Body or header capture can collect secrets; keep it disabled unless a reviewed debugging need requires it. gRPC ServerOptions contains TrustIncomingIdentity and an explicit CaptureMetadata allowlist.

Gin, Echo, and Fiber strip URL userinfo, query strings, and fragments from recorded HTTP URLs. Each HTTP attribute is bounded independently; a truncated value receives a .truncated=true sibling marker so one oversized request does not discard a batch.

Package-level and client-bound HTTP client/transport wrappers mark their generated outbound spans with anectico.issue.suppressed=true. Transport failures and cancellations keep their normal span status, trace/baggage propagation, and HTTP metrics, so they remain diagnosable in Traces without producing stackless Issues. To turn an actionable dependency failure into an Issue, translate it into an explicit typed application/domain error after retries are exhausted and call CaptureError once at that boundary.

The custom gRPC client interceptors inject the newly started client span as traceparent/tracestate and propagate request identity in W3C baggage. Generated client calls must receive the request context that carries the active span and anectico.ContextWithDistinctID value. A client stream span ends on EOF, the single response of a client-streaming RPC, a failed stream operation, or caller cancellation. Successful CloseSend does not end the response side. Concurrent or repeated terminal signals end the span once while returning the original gRPC status unchanged. Client transport statuses do not create Issues. The server interceptor captures one occurrence for unexpected server failures (Unknown, ResourceExhausted, Unimplemented, Internal, Unavailable, or DataLoss). Cancellation, deadlines, and expected caller/control statuses remain visible as error-status spans without becoming Issues. Non-canonical transport spans carry anectico.issue.suppressed=true; when server CaptureError succeeds, its transport parent also carries the returned error.id. This suppression remains exact if exporter batches separate or reorder the parent and canonical error.capture child. If server capture is disabled, sampled out, fails, or returns no ID, the actionable server transport span is left eligible as the fallback Issue. For an external dependency, explicitly capture one typed domain error after retries are exhausted when the failure should become an Issue.