angela

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Apr 1, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyDiff

func ApplyDiff(original string, hunks []DiffHunk, accepted []bool) string

ApplyDiff applies accepted hunks to the original text. Hunks are applied in reverse order to preserve line offsets.

func AverageScore

func AverageScore(scored []ScoredPersona) float64

AverageScore returns the average resolution score of the given scored personas.

func BuildCorpusSummary

func BuildCorpusSummary(corpus []domain.DocMeta) string

BuildCorpusSummary creates a compact summary of corpus metadata for the prompt. Limited to 20 entries to respect token limits.

func BuildPersonaPrompt

func BuildPersonaPrompt(personas []PersonaProfile) string

BuildPersonaPrompt constructs the persona section for the AI polish prompt.

func BuildPolishPrompt

func BuildPolishPrompt(doc string, meta domain.DocMeta, styleGuide string, corpusSummary string, personas []PersonaProfile) (string, string)

BuildPolishPrompt constructs the AI prompt for polishing a document. Returns (systemPrompt, userContent) where system is stable/cacheable and user varies per call. When personas is non-nil, persona directives are injected into the user content (AC-4).

func BuildReviewPrompt

func BuildReviewPrompt(docs []DocSummary, styleGuide string, signals *CorpusSignals) (string, string)

BuildReviewPrompt constructs the AI prompt for corpus-wide review. Returns (systemPrompt, userContent) where system is stable/cacheable and user varies per call. signals may be nil (no pre-analysis). Corpus is serialized in TOON format.

func ExtractAdaptiveSummary

func ExtractAdaptiveSummary(body string, maxRunes int) string

ExtractAdaptiveSummary extracts top 3 sections from a document body, scored by semantic relevance rather than length. Each section is truncated to maxRunes/N runes (N = number of selected sections). Budget is not redistributed from short sections to longer ones.

func FormatDiff

func FormatDiff(hunks []DiffHunk, streams domain.IOStreams)

FormatDiff displays hunks to the writer with colored output.

func FormatStyleGuideRules

func FormatStyleGuideRules(guide *StyleGuide) string

FormatStyleGuideRules returns a prompt-ready string describing the active rules. Returns empty string if no rules are active.

func InteractiveDiff

func InteractiveDiff(hunks []DiffHunk, streams domain.IOStreams, opts DiffOptions) ([]bool, error)

InteractiveDiff prompts the user for each hunk. Returns a slice of booleans indicating acceptance per hunk.

func Polish

func Polish(ctx context.Context, provider domain.AIProvider, doc string, meta domain.DocMeta, styleGuide string, corpusSummary string, personas []PersonaProfile) (string, error)

Polish sends a document to the AI provider for enhancement. Returns the improved document content. Exactly 1 API call.

func ResolveMaxTokens

func ResolveMaxTokens(mode string, docWordCount int) int

ResolveMaxTokens returns the max_tokens cap for a given Angela mode. For polish mode, the cap is dynamic based on document word count. Unknown modes default to 2000.

func SaveReviewCache

func SaveReviewCache(loreDir string, report *ReviewReport, totalDocs int) error

SaveReviewCache writes the review results to .lore/cache/review.json.

func SerializeTOON

func SerializeTOON(summaries []DocSummary, signals *CorpusSignals) string

SerializeTOON produces a pipe-separated corpus + signals block for review prompts. Headers are declared once per section. Each data row is pipe-separated.

Types

type CorpusSignals

type CorpusSignals struct {
	// PotentialPairs are docs of the same type with shared tags but distant dates.
	// These are the most likely contradiction candidates.
	PotentialPairs []DocPair

	// TagClusters groups docs by tag for thematic analysis.
	TagClusters map[string][]string // tag → filenames

	// IsolatedDocs are docs with no shared tags with any other doc.
	IsolatedDocs []string

	// TypeDistribution counts docs per type.
	TypeDistribution map[string]int
}

CorpusSignals holds locally computed analysis of the entire corpus. Zero API calls — all analysis is string matching and metadata comparison. Extends the CheckCoherence pattern (single-doc) to corpus-wide scope.

func AnalyzeCorpusSignals

func AnalyzeCorpusSignals(docs []DocSummary) *CorpusSignals

AnalyzeCorpusSignals performs local corpus-wide analysis. Uses only metadata (no doc content reads, no API calls).

type DiffHunk

type DiffHunk struct {
	OrigStart     int      // 0-based line index in original
	OrigCount     int      // number of original lines in this hunk
	ModStart      int      // 0-based line index in modified
	ModCount      int      // number of modified lines in this hunk
	ContextBefore []string // up to 3 lines before the change
	Original      []string // lines removed/changed from original
	Modified      []string // lines added/changed in modified
	ContextAfter  []string // up to 3 lines after the change
}

DiffHunk represents a contiguous group of changes with surrounding context.

func ComputeDiff

func ComputeDiff(original, modified string) []DiffHunk

ComputeDiff produces a list of diff hunks between original and modified text. Uses a simple LCS-based line diff. Returns nil if texts are identical. Falls back to a single whole-document hunk if either text exceeds maxDiffLines.

type DiffOptions

type DiffOptions struct {
	DryRun bool
	YesAll bool
}

DiffOptions controls the behavior of InteractiveDiff.

type DocPair

type DocPair struct {
	DocA     string // filename
	DocB     string // filename
	Type     string // shared type
	Tags     string // shared tags
	DaysDiff int    // approximate days between dates
}

DocPair represents two documents that may contradict each other.

type DocSummary

type DocSummary struct {
	Filename string
	Type     string
	Date     string
	Tags     []string
	Summary  string // adaptive: top sections by content length (max 450 runes total)
}

DocSummary holds extracted metadata and content snippets for a single document.

func PrepareDocSummaries

func PrepareDocSummaries(reader domain.CorpusReader) ([]DocSummary, int, error)

PrepareDocSummaries reads documents from the corpus and builds summaries. Returns error if fewer than 5 documents exist (AC-2). Limits to 50 docs: 25 most recent + 25 oldest when corpus exceeds 50.

type DraftCheck

type DraftCheck struct {
	Label string
	Check func(body string, sections map[string]string) *Suggestion
}

DraftCheck is a persona-specific structural check run during draft analysis. Check returns a raw Suggestion (without persona prefix); the caller decorates.

type PersonaProfile

type PersonaProfile struct {
	Name            string
	DisplayName     string
	Icon            string
	Expertise       string
	Principles      []string
	DraftChecks     []DraftCheck
	PromptDirective string
	DocTypes        []string // explicit type activation
	ContentSignals  []string // keyword content activation (EN + FR)
}

PersonaProfile represents an expert lens that Angela can activate for document review. Personas are Go values — no external files.

func GetRegistry

func GetRegistry() []PersonaProfile

GetRegistry returns a deep copy of the persona registry. Slices (Principles, DraftChecks, DocTypes, ContentSignals) are independently copied.

func Profiles

func Profiles(scored []ScoredPersona) []PersonaProfile

Profiles extracts PersonaProfile slice from scored results.

type ReviewCache

type ReviewCache struct {
	Version    int             `json:"version"`
	LastReview time.Time       `json:"last_review"`
	DocCount   int             `json:"doc_count"`
	TotalDocs  int             `json:"total_docs"`
	Findings   []ReviewFinding `json:"findings"`
}

ReviewCache holds persisted review results for incremental tracking. Version field enables forward-compatible schema evolution (ADR-013).

func LoadReviewCache

func LoadReviewCache(loreDir string) (*ReviewCache, error)

LoadReviewCache reads the cached review results. Returns nil if no cache exists.

type ReviewFinding

type ReviewFinding struct {
	Severity    string   `json:"severity"` // "contradiction", "gap", "style", "obsolete"
	Title       string   `json:"title"`
	Description string   `json:"description"`
	Documents   []string `json:"documents"` // filenames concerned
}

ReviewFinding represents a single issue found during corpus review.

type ReviewReport

type ReviewReport struct {
	Findings []ReviewFinding
	DocCount int
}

ReviewReport holds the complete result of a corpus review.

func Review

func Review(ctx context.Context, provider domain.AIProvider, docs []DocSummary, styleGuide string) (*ReviewReport, error)

Review performs a corpus-wide analysis using the AI provider. Exactly 1 API call. Returns the review report sorted by severity.

type ScoredPersona

type ScoredPersona struct {
	Profile PersonaProfile
	Score   int
}

ScoredPersona pairs a persona with its resolution score.

func ResolvePersonas

func ResolvePersonas(docType, body string) []ScoredPersona

ResolvePersonas selects up to 3 personas based on document type and content signals. Type match = +10 points, each content signal found = +2 points. Returns fallback [tech-writer] if no persona scores > 0 (AC-6).

type StyleGuide

type StyleGuide struct {
	RequireWhy          bool
	RequireAlternatives bool
	MaxBodyLength       int // in runes, 0 = no limit
	MinTags             int

	// Warnings collects any parse-time issues (e.g. unknown rules).
	Warnings []Suggestion
}

StyleGuide holds parsed style rules for Angela draft analysis.

func ParseStyleGuide

func ParseStyleGuide(rules map[string]interface{}) *StyleGuide

ParseStyleGuide parses style guide rules from config. Returns default rules if input is nil. Unknown keys produce warning suggestions (catches typos in .lorerc).

type Suggestion

type Suggestion struct {
	Category string // "structure", "completeness", "style", "coherence", "persona"
	Message  string
	Severity string // "info", "warning"
}

Suggestion represents a single review finding from Angela draft analysis.

func AnalyzeDraft

func AnalyzeDraft(doc string, meta domain.DocMeta, guide *StyleGuide, corpus []domain.DocMeta, personas []PersonaProfile) []Suggestion

AnalyzeDraft performs local structural analysis of a document. Zero API calls — fully deterministic. Returns nil if no suggestions. When personas is non-nil, persona-specific draft checks are included.

func CheckCoherence

func CheckCoherence(doc string, meta domain.DocMeta, corpus []domain.DocMeta) []Suggestion

CheckCoherence validates a document against the existing corpus. Works on metadata only (no file reads) for performance.

func RunPersonaDraftChecks

func RunPersonaDraftChecks(body string, personas []PersonaProfile) []Suggestion

RunPersonaDraftChecks runs all draft checks from the given personas against the body. Suggestion messages are decorated with the persona's icon and display name.

Jump to

Keyboard shortcuts

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