Context & Manager
This chapter drills into context construction, caching, and lifecycle management.
Context Responsibilities
context.go defines Context which bundles:
- Templates (prompt, data, title, terse, author)
- In-memory
Databases(map: database name -> slice of CSV row strings) Seriesmetadata (filters & suffix)DalleCache(address -> *DalleDress)
The context owns pure prompt state; it does not perform network calls (image generation and enhancement are separate functions using the context’s outputs).
Building a Context
NewContext():
- Loads cache manager (
storage.GetCacheManager().LoadOrBuild()) - Initializes template pointers from
promptpackage variables - Creates empty maps
- Calls
ReloadDatabases("empty")to seed initial series
Database Loading
ReloadDatabases(filter string):
- Loads
SeriesvialoadSeries(filter) - For each name in
prompt.DatabaseNamestries cached binary index → falls back to CSV - Applies optional per-field filtering from
Series.GetFilter(fieldName) - Ensures at least one row ("none") to avoid zero-length selection panics
Constructing a DalleDress
MakeDalleDress(address string):
- Normalizes key (filename-safe) and returns cached instance if present
- Builds a
seed= original + reverse(original); enforces length >= 66; strips0x - Iteratively slices 6 hex chars every 8 chars; maps them into attributes until databases exhausted
- Builds prompt layers by executing templates; conditionally loads an
enhancedprompt from disk if present - Stores under both original and normalized cache keys for future hits
Thread Safety
CacheMutex protects DalleCache. Additional saveMutex guards concurrent file writes in reportOn.
Manager Layer
manager.go adds an LRU+TTL around contexts so each series has at most one resident context. Key pieces:
managedContextstruct holds context + lastUsed timestamp- Global
contextManagermap + order slice ManagerOptions(MaxContexts, ContextTTL) adjustable viaConfigureManager- Eviction: contexts older than TTL are dropped; if still above capacity, least-recently-used removed
Generation Entry Point
GenerateAnnotatedImage(series, address, skipImage, lockTTL):
- Early return if annotated image already exists (synthetic cache hit progress run created)
- Acquire per-(series,address) lock with TTL to avoid duplicate concurrent generations
- Build / fetch context and
DalleDress - Start and transition progress phases (base prompts → enhance → image...) unless
skipImage - Delegate to
Context.GenerateImageWithBaseURLfor image pipeline - Mark completion, update metrics
skipImage=true still produces prompt artifacts but bypasses network phases.
Locks
A map of requestLocks with TTL prevents burst duplicate work. Expired locks are cleaned opportunistically.
Cache Hit Shortcut
If annotated/<address>.png exists the system:
- Builds
DalleDress(ensures consistent metadata) - Starts a progress run (if one doesn’t already exist)
- Marks cacheHit + completed without regenerating
Cleaning Artifacts
Clean(series, address) removes the generated set: annotated png, raw image, selector JSON, audio, and prompt text files across all prompt subdirectories.
When to Add a New Context Field
Add new fields only if they reflect deterministic state or necessary caches. Side-effectful network concerns belong outside.
Extension Strategies
- Alternate Persistence: wrap
reportOnor post-process afterGenerateAnnotatedImage. - Custom Prompt Layers: execute additional templates with
DalleDress.FromTemplate. - Series Variants: manage multiple series suffixes and rely on manager eviction for memory control.