specstream/pkg/types/types.go
agent-engineering ecf100b917 Initial commit: SpecStream structured extraction gateway
Go MCP server (port 3991) for agent content safety.
Deterministic parsers, typed output, no raw text fields.

- HTML (goquery), Markdown (goldmark), Text parsers
- Injection pattern detection and redaction
- SHA256 content fingerprinting
2026-05-25 21:18:57 -07:00

134 lines
5.3 KiB
Go

// Package types defines the SpecStream extraction data model.
//
// The central security invariant: every output type is structured and bounded.
// There is NO "RawText" or "Body" field. Every piece of content is categorized
// into typed, enumerated fields. The agent never receives free-form text
// from untrusted sources — only structured data extracted by deterministic
// (non-LLM) parsers.
package types
import "time"
// ExtractedContent is the top-level output of a SpecStream extraction.
// Every field is typed and bounded. No raw text bucket.
type ExtractedContent struct {
// Source metadata
Source Source `json:"source"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Author string `json:"author,omitempty"`
PublishedAt string `json:"published_at,omitempty"`
Language string `json:"language,omitempty"`
SiteName string `json:"site_name,omitempty"`
// Structured content — the safe output
Sections []Section `json:"sections,omitempty"`
CodeBlocks []CodeBlock `json:"code_blocks,omitempty"`
Links []Link `json:"links,omitempty"`
Images []Image `json:"images,omitempty"`
Lists []List `json:"lists,omitempty"`
Tables []Table `json:"tables,omitempty"`
Metadata Metadata `json:"metadata"`
// Extraction diagnostics
ExtractedAt time.Time `json:"extracted_at"`
ContentType string `json:"content_type"` // "html", "markdown", "text", "json"
CharCount int `json:"char_count"`
SectionCnt int `json:"section_count"`
}
type Source struct {
URL string `json:"url,omitempty"`
Filename string `json:"filename,omitempty"`
MIMEType string `json:"mime_type,omitempty"`
ByteSize int64 `json:"byte_size,omitempty"`
IsTrusted bool `json:"is_trusted"` // false for all external content by default
}
// Section is a content section with a heading and bounded paragraphs.
type Section struct {
Heading string `json:"heading,omitempty"`
Level int `json:"level"` // h1-h6
Paragraphs []string `json:"paragraphs"` // one string per <p> — never the full body
IsCode bool `json:"is_code,omitempty"` // false = prose
}
// CodeBlock is an isolated code segment with known language.
type CodeBlock struct {
Language string `json:"language,omitempty"` // "go", "python", "javascript", etc.
Code string `json:"code"` // the code text — tagged, not inline
Caption string `json:"caption,omitempty"`
}
// Link is an extracted hyperlink.
type Link struct {
Text string `json:"text"`
Href string `json:"href"`
Rel string `json:"rel,omitempty"`
}
// Image is an extracted image reference.
type Image struct {
Alt string `json:"alt,omitempty"`
Src string `json:"src"`
Width int `json:"width,omitempty"`
}
// List is an ordered or unordered list.
type List struct {
Ordered bool `json:"ordered"`
Items []string `json:"items"`
}
// Table is a structured data table.
type Table struct {
Headers []string `json:"headers,omitempty"`
Rows [][]string `json:"rows"`
}
// Metadata holds extraction diagnostics and content hashes.
type Metadata struct {
ExtractorVersion string `json:"extractor_version"`
ExtractionTimeMs int64 `json:"extraction_time_ms"`
TagCounts map[string]int `json:"tag_counts,omitempty"`
Warnings []string `json:"warnings,omitempty"`
SHA256 string `json:"sha256,omitempty"`
StrippedPatterns map[string]int `json:"stripped_patterns,omitempty"` // count of filtered patterns
}
// ── Extraction Request ─────────────────────
// ExtractRequest is sent to SpecStream's MCP endpoint.
type ExtractRequest struct {
URL string `json:"url,omitempty"`
Content string `json:"content,omitempty"` // raw text content (for testing/offline)
Filename string `json:"filename,omitempty"` // hint for content type detection
MaxSize int `json:"max_size,omitempty"` // max bytes to process (default 1MB)
// Schema hints — what structured fields we want
ExtractSections bool `json:"extract_sections,omitempty"`
ExtractCode bool `json:"extract_code,omitempty"`
ExtractLinks bool `json:"extract_links,omitempty"`
ExtractImages bool `json:"extract_images,omitempty"`
ExtractTables bool `json:"extract_tables,omitempty"`
ExtractLists bool `json:"extract_lists,omitempty"`
}
// ── Safety Policy ──────────────────────────
// SafetyConfig controls what patterns to strip from extracted content.
// These run AFTER extraction — they remove instruction-like patterns
// that slipped through the structured extraction.
type SafetyConfig struct {
// StripMarkdownImages removes ![alt](url) from extracted text
StripMarkdownImages bool `json:"strip_md_images,omitempty"`
// StripInlineCode removes `code` from extracted paragraphs
StripInlineCode bool `json:"strip_inline_code,omitempty"`
// StripURLs removes http:// and https:// from extracted paragraph text
StripURLs bool `json:"strip_urls,omitempty"`
// MaxParagraphLength truncates paragraphs over this length
MaxParagraphLength int `json:"max_paragraph_length,omitempty"`
// BlocklistPatterns removes paragraphs matching these regexes
BlocklistPatterns []string `json:"blocklist_patterns,omitempty"`
}