Skip to main content

Documentation Index

Fetch the complete documentation index at: https://whyops.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

Use the Go trace builder when you want the graph to include application-side runtime work that the provider proxy cannot observe directly.

Quickstart

Start with client creation, agent initialization, and your first trace event.

Proxy Transport

Review the Go proxy flow before adding runtime events on top of proxied traffic.

Manual Events API

Compare the Go helpers with the raw REST ingest endpoint and event schema.

Minimal runtime tracing

spanID, _ := trace.ToolCallRequest(ctx, "search_orders",
	[]whyops.ToolCallPair{{Name: "search_orders", Arguments: map[string]any{"orderId": "123"}}},
	whyops.ToolCallRequestOptions{LatencyMs: 12},
)

_ = trace.ToolCallResponse(ctx, "search_orders", spanID,
	[]whyops.ToolCallPair{{Name: "search_orders", Arguments: map[string]any{"orderId": "123"}}},
	map[string]any{"status": "shipped"},
	whyops.ToolCallResponseOptions{LatencyMs: 91},
)

Prompt caching-aware usage

_ = trace.LLMResponse(ctx, "anthropic/claude-sonnet-4-5", "anthropic", "Done.", whyops.LLMResponseOptions{
	LatencyMs: 860,
	Usage: &whyops.TokenUsage{
		PromptTokens:        1200,
		CompletionTokens:    240,
		TotalTokens:         9940,
		CacheReadTokens:     8200,
		CacheCreationTokens: 300,
	},
})

Hybrid pattern

Use hybrid mode when the proxy already captures the model exchange, but you still want application-side tool timing and output.
spanID, _ := trace.ToolCallRequest(ctx, "charge_card",
	[]whyops.ToolCallPair{{Name: "charge_card", Arguments: map[string]any{"amount": 4999, "currency": "usd"}}},
	whyops.ToolCallRequestOptions{},
)

result := chargeCard()

_ = trace.ToolCallResponse(ctx, "charge_card", spanID,
	[]whyops.ToolCallPair{{Name: "charge_card", Arguments: map[string]any{"amount": 4999, "currency": "usd"}}},
	map[string]any{"result": result},
	whyops.ToolCallResponseOptions{},
)

Self-hosted overrides

sdk := whyops.New(whyops.Config{
	APIKey:         os.Getenv("WHYOPS_API_KEY"),
	AgentName:      "customer-support-agent",
	AgentMetadata:  whyops.AgentMetadata{SystemPrompt: "You are helpful."},
	ProxyBaseURL:   "https://proxy.internal.example.com",
	AnalyseBaseURL: "https://analyse.internal.example.com/api",
})

Method map

MethodPurposeNotes
InitAgent(ctx)Explicit agent registrationAlso runs automatically before first event
Trace(traceID)Create a trace builderUse one trace per session, request, or workflow
UserMessage()Log user or assembled prompt inputOptional SystemPrompt, Tools, Params, and ExternalUserID
LLMResponse()Log model outputSupports Usage, FinishReason, LatencyMs
LLMThinking()Log explicit thinking blocksUse when the runtime exposes reasoning
EmbeddingRequest()Log embedding inputsPairs with EmbeddingResponse()
EmbeddingResponse()Log embedding result summaryIncludes total tokens and latency
ToolCallRequest()Start a tool spanReturns spanID
ToolCallResponse()Close the tool spanReuse the spanID from the request
ToolResult()Record tool output returned to the modelUseful in hybrid setups
Error()Record runtime or provider failureSupports Status and Stack

Linking events to users

Use ExternalUserID to associate events with your application user IDs:
_ = trace.UserMessage(ctx, []whyops.MessageItem{{Role: "user", Content: "Reset my password."}},
	whyops.UserMessageOptions{EventOptions: whyops.EventOptions{ExternalUserID: "user_12345"}},
)
The ExternalUserID is stored on every event and trace, allowing you to filter and analyze traces by your own user identifiers.