Documentation
¶
Overview ¶
Package tlsintent reassembles the fragmented TLS plaintext that the eBPF SSL_write/SSL_read probes capture into COMPLETE HTTP/1.1 request/response messages, and pulls minimal LLM semantics (model, endpoint) out of the body.
It is the userspace half of "capture the agent's actual LLM traffic without instrumenting the agent": the kernel probe can only read a bounded buffer per call, so it emits ordered Chunks keyed by the TLS connection; this package accumulates them and parses the message once whole. Clean-room implementation (technique only; our own code, Go stdlib HTTP framing).
Scope: HTTP/1.1 with Content-Length, chunked, and SSE (streaming) bodies, and HTTP/2 (h2 frames + HPACK, see http2.go) which dominates real LLM APIs. Platform-neutral (no eBPF/Linux deps) so it unit-tests anywhere.
Index ¶
Constants ¶
const ( Request = "request" // SSL_write: bytes the agent sent (the LLM request) Response = "response" // SSL_read: bytes the agent received (the LLM response) )
Direction of a captured segment relative to the agent.
const ( ProtoHTTP11 = "http/1.1" ProtoH2 = "h2" // parsed from h2 frames + HPACK (see http2.go) )
Protocol values on a reassembled Message.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Chunk ¶
type Chunk struct {
PID uint32
Conn uint64 // the SSL* pointer: identifies one TLS connection
Direction string // Request or Response
Data []byte
Truncated bool // the kernel dropped bytes past its capture cap for this call
}
Chunk is one ordered segment of TLS plaintext from the eBPF probe. A large request/response arrives as several Chunks with increasing arrival order on the same (PID, Conn) TLS connection. This is the eBPF<->userspace contract.
type Message ¶
type Message struct {
PID uint32
Conn uint64
Direction string // Request or Response
Protocol string // ProtoHTTP11 or ProtoH2
// HTTP surface.
Method string // request only
Path string // request only
Host string // request only
Status int // response only
Headers map[string]string
Body []byte // decoded body: dechunked and, for SSE, the joined data: payloads
Truncated bool // some bytes were dropped, so Body may be incomplete
// Minimal LLM semantics (best-effort; empty when not an LLM call).
Model string
Endpoint string // request: host+path
}
Message is a fully reassembled HTTP/1.1 message plus minimal LLM semantics.
type Reassembler ¶
type Reassembler struct {
MaxBytes int // per-stream buffer cap; 0 -> defaultMaxBytes
// contains filtered or unexported fields
}
Reassembler accumulates Chunks per connection+direction and returns any messages that became complete. It handles HTTP keep-alive (several messages on one connection) by keeping the pipelined remainder after each complete message.
func NewReassembler ¶
func NewReassembler() *Reassembler
NewReassembler returns an empty Reassembler.
func (*Reassembler) Add ¶
func (r *Reassembler) Add(c Chunk) []Message
Add feeds one Chunk and returns every message that completed as a result (usually zero or one).
func (*Reassembler) Flush ¶
func (r *Reassembler) Flush(pid uint32, conn uint64) []Message
Flush emits whatever is buffered for a connection as a best-effort (possibly truncated) message and forgets its streams. Call it when a connection closes (e.g. on process_exit) so a close-framed response with no Content-Length isn't lost.
type Semantics ¶
type Semantics struct {
Model string `json:"model,omitempty"`
MessageCount int `json:"message_count,omitempty"` // request: number of messages
HasSystem bool `json:"has_system,omitempty"` // request: a system prompt is present
ToolsOffered []string `json:"tools_offered,omitempty"` // request: tool names offered to the model
ToolCalls []string `json:"tool_calls,omitempty"` // response: tool names the model decided to call
ToolCommands []string `json:"tool_commands,omitempty"` // response: the shell command(s) the model decided to run
StopReason string `json:"stop_reason,omitempty"` // response: why generation stopped
}
Semantics is the minimal structured intent pulled from an LLM request/response body, tolerant across the common provider shapes (Anthropic Messages, OpenAI Chat Completions). Empty fields mean "not present / not an LLM call".
func ParseSemantics ¶
ParseSemantics extracts structured intent from a request or response body.