parseutil

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package parseutil holds small helpers shared by the harness adapters.

Index

Constants

View Source
const MaxLineBytes = 256 << 20

MaxLineBytes bounds a single transcript line across every adapter; line scanners grow their buffer on demand up to this cap. Tool results and file-history snapshots can be very large. Anything else reading transcript lines (drift scanning) must use the same cap, or a line an adapter accepts would fail elsewhere.

Variables

This section is empty.

Functions

func CloneRaw

func CloneRaw(b []byte) json.RawMessage

CloneRaw copies b into an independent RawMessage, safe to retain after a scanner reuses its buffer.

func Digest

func Digest(b []byte) string

Digest returns the SHA-256 hex digest of b.

func ParseBlocks

func ParseBlocks[T any](raw json.RawMessage, fromText func(string) T, setRaw func(*T, json.RawMessage)) ([]T, error)

ParseBlocks decodes API message content, which is either a bare string (one text block) or an array of typed blocks. fromText builds a block from a bare string; setRaw retains each array element verbatim on its decoded block.

func ParseTime

func ParseTime(s string) *time.Time

ParseTime parses an RFC3339 timestamp, returning nil on absence or malformation (timestamps are extension data; they never fail a parse).

func TrimBOM

func TrimBOM(b []byte) []byte

TrimBOM strips a leading UTF-8 byte-order mark.

func Truncate

func Truncate(tr *session.ToolResult, limit int64)

Truncate applies a max-payload limit to a tool result, replacing oversized payloads with size-and-digest placeholders per the schema's truncation contract. A limit of zero or less keeps payloads whole. Content blocks carry either Text or Raw by construction (see the adapters' toContentBlock mappings); if a block ever carried both oversized, Size and Digest would describe the Raw payload.

func UncoveredLines

func UncoveredLines(data []byte, events []session.Event, skipLines []int) []int

UncoveredLines checks the line-accounting invariant: every non-blank line of a transcript must be covered by an event's provenance range or by a skip callback. It returns the 1-based lines that are covered by neither, in order (nil when the invariant holds). skipLines are the lines reported via Options.OnSkip.

Types

type Emitter

type Emitter struct {
	Harness harness.ID
	Opts    harness.Options
	Yield   func(session.Event, error) bool

	// Line is the 1-based source line of the record being parsed.
	Line int

	// Version is the harness version, once discovered.
	Version string
}

Emitter owns the yield-side plumbing every adapter parser shares: emitting events, failing loudly as *harness.ParseError, preserving unclassifiable records in permissive mode, and the provenance and truncation conventions. Adapters embed it in their parser and keep Line (and Version, once the transcript reveals one) current while scanning.

func (*Emitter) Emit

func (e *Emitter) Emit(ev session.Event) bool

Emit yields a normal event.

func (*Emitter) Fail

func (e *Emitter) Fail(msg string, err error) bool

Fail yields a *harness.ParseError carrying the harness, version, and line context, and always returns false.

func (*Emitter) Prov

func (e *Emitter) Prov(data []byte) *session.Provenance

Prov is single-record provenance for the current line, retaining the verbatim record when KeepRaw is set.

func (*Emitter) Truncate

func (e *Emitter) Truncate(tr *session.ToolResult)

Truncate applies Opts.MaxPayloadBytes to a tool result.

func (*Emitter) Unknown

func (e *Emitter) Unknown(recordType string, data []byte, reason string) bool

Unknown preserves an unclassifiable record as a KindUnknown event.

func (*Emitter) UnknownOrFail

func (e *Emitter) UnknownOrFail(recordType string, data []byte, reason string) bool

UnknownOrFail handles an unclassifiable record: a loud parse error by default, or a preserved unknown event in permissive mode.

type LineScanner

type LineScanner struct {
	// contains filtered or unexported fields
}

LineScanner reads transcript lines with the conventions every adapter shares: buffer growth up to MaxLineBytes, a tolerated UTF-8 BOM on the first line, surrounding whitespace (including CRLF) trimmed, and blank lines skipped while still counting toward line numbers.

func NewLineScanner

func NewLineScanner(r io.Reader) *LineScanner

NewLineScanner returns a LineScanner reading from r.

func (*LineScanner) Bytes

func (s *LineScanner) Bytes() []byte

Bytes returns the current line, trimmed. Like bufio.Scanner, the slice is only valid until the next Scan; clone to retain.

func (*LineScanner) Err

func (s *LineScanner) Err() error

Err returns the first error the underlying scanner encountered, if any.

func (*LineScanner) Line

func (s *LineScanner) Line() int

Line returns the 1-based number of the current line (the last physical line read, once Scan has returned false).

func (*LineScanner) Scan

func (s *LineScanner) Scan() bool

Scan advances to the next non-blank line, reporting whether one exists.

Jump to

Keyboard shortcuts

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