<ExtractPrompt> is not an importable runtime export of smthrs.
It ships as an example/pack composition pattern: scaffold it into your own
.smithers/components/extract-prompt/ (via init), import it relative to your
workflow as shown below, and adapt it.
Three modes
- Passthrough:
prompt ≥ 32 chars emits a static-output task (score: 1.0,
resolved: true); no agent invoked.
- Cache hit: caller resolved a
cached entry by key, same as passthrough but
carrying over the cached score and prefixing scoreReason with cached: .
- Extraction: wraps
<LoopUntilScored> around the drafter task, which uses the
R-C-T-F backbone, picks one Socratic principle per turn, asks the user via
bun .smithers/scripts/ask-user.ts, self-scores, and sets resolved: true when ready.
Cache I/O is the caller’s responsibility
The component is pure (no side effects in JSX); the caller runs cache getSync/setSync
inside the smithers (ctx) => function (see example above).
Drivers shipped:
MarkdownPromptCache (default): .smithers/cache/prompts/{slug}.md with YAML frontmatter
SqlitePromptCache: opt-in single-table store via bun:sqlite
MemoryPromptCache: for tests
Stakes
high → threshold 1.0 (every R-C-T-F slot must be strongly filled)
low → threshold 0.7
Override via threshold; stakes just saves callers from remembering exact numbers.
Override semantics
The human can override: if the score is below threshold and they type “ship it”
via the ask-user CLI, the agent sets:
resolved: true
overridden: true
overrideReason: "<verbatim>"
The cache records overridden: true for audit; the verbatim overrideReason is
available only on the live output, not in the cache.