extract

package
v0.7.8 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: AGPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package extract distils conversation prose into durable, classified facts without an LLM — a port of mempalace's heuristic extractor. It pulls the decisions, preferences, and problems worth keeping out of a short-term intake capture, as durable memories that earn trust on recall. Marker-driven and deliberately conservative: a miss just means no extra memory, never a wrong one. Both the backfill importer and write-time extraction share this logic.

Index

Constants

View Source
const ClassifyMaxChars = 400

ClassifyMaxChars bounds a classifiable write, in runes: one durable fact is terse; longer content is session history even when it contains decision markers. Runes, not bytes — a byte bound would put non-ASCII prose over the ceiling at a third of the nominal length, silently denying it a durable tier.

View Source
const MaxEntities = 12

MaxEntities caps the entities extracted from one memory, keeping the first (reading-order) mentions so one long transcript can't flood the entity index.

View Source
const MaxPerExchange = 5

MaxPerExchange caps extractions from a single exchange so one rambling turn can't flood the store.

View Source
const MinConfidence = 0.3

MinConfidence gates an extraction: confidence is min(1, score/5) where score is the count of distinct markers that match plus a length bonus, so a lone marker on a short segment (0.2) is dropped while two distinct markers, or one in a longer segment, pass.

View Source
const MinFactChars = 20

MinFactChars floors an extractable segment and a classifiable write, in runes: below this there is too little text to be a fact. Runes for the same reason as ClassifyMaxChars — on bytes, non-ASCII prose clears a floor that the same amount of ASCII prose does not.

Exported because it bounds the useful range of a classify ceiling: a ceiling under MinFactChars can admit nothing, so config rejects that range rather than letting it read as a tight bound and act as an off switch.

Variables

This section is empty.

Functions

func Entities added in v0.5.5

func Entities(text string) []string

Entities extracts salient named-entity keys from a memory's content without an LLM: maximal runs of capitalized tokens ("Charlotte's Web", "Black Friday", "Postgres"), normalized to lowercase with possessives stripped. Deliberately precision-first — noisy entities poison every consumer — so it only trusts capitalization evidence:

  • a sentence-initial span counts only when it has ≥2 tokens, its lead word is also seen capitalized mid-sentence in the same text, or the word carries its own casing signal (internal uppercase or digits, "iPhone", "Qwen3");
  • stopwords (function words, greetings, months/weekdays) never join a span; they split it instead;
  • purely numeric or single-letter tokens never start an entity.

Lowercase concept nouns ("pottery", "the retry policy") are out of scope by design: without a POS tagger they cannot be told from ordinary prose.

func Stopword added in v0.5.6

func Stopword(w string) bool

Stopword reports whether a lowercased word is a function/discourse word that carries no content on its own. Exported for the contradict package, which shares the entity extractor's vocabulary judgment when diffing two memories.

Types

type Kind

type Kind string

Kind labels an extracted memory; it doubles as the memory's first tag.

const (
	KindDecision   Kind = "decision"
	KindPreference Kind = "preference"
	KindProblem    Kind = "problem"
	KindFact       Kind = "fact"  // architecture/config/factual statement
	KindHowTo      Kind = "howto" // setup/instruction steps
)

func Classify added in v0.5.4

func Classify(text string) (Kind, bool)

Classify labels an entire write whose caller picked no tier, bounded by the built-in ClassifyMaxChars. See ClassifyWith.

func ClassifyWith added in v0.7.3

func ClassifyWith(text string, maxChars int) (Kind, bool)

ClassifyWith labels an entire write whose caller picked no tier, bounding it at maxChars runes. It is stricter than Typed because the verdict covers the full text rather than an extracted segment: the content must be short, prose-shaped, unhedged, not a transcript, and clear the same marker-confidence gate. ok=false means no confident call — callers fall back to the working-intake default. maxChars <= 0 declines every write, since a zero-length ceiling admits nothing.

func (Kind) Tier

func (k Kind) Tier() memory.Tier

Tier maps an extracted kind to its memory tier: a preference is a how-to rule, so it's procedural; decisions and problems are durable facts, so semantic.

type Result

type Result struct {
	Kind    Kind
	Content string
}

Result is one classified segment ready to become a durable memory.

func Typed

func Typed(text string) []Result

Typed scans a block of conversation text and returns the decision/preference/problem segments that clear the confidence gate, capped at MaxPerExchange. Empty when nothing qualifies.

Jump to

Keyboard shortcuts

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