tlsintent

package
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

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

View Source
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.

View Source
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

func ParseSemantics(direction string, body []byte) Semantics

ParseSemantics extracts structured intent from a request or response body.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL