The loop, unbundled
run_discovery is essentially this, and each line is yours to swap:
mw.discovery.filter(...)
and mw.discovery.generate(...).
Bring your own pieces
- Your own filter.
filter_postis a convenience over acomplete_structuredcall. Replace it with your own classifier, a keyword rule, or an embedding score —generate_replydoesn’t care how a post was selected. - Your own voice.
DiscoveryContext+Personacarry voice guidelines, winning examples, pinned notes, an avoid-list, and per-account-type personas. This is the seam a memory system renders into. - Your own compliance.
heuristic_checkis deterministic and offline. Wrap it, extend it, or replace it with your own rules — then escalate tollm_judgeonly when you want a model’s second opinion. - Your own storage. Persist
Opportunityobjects wherever you like via theOpportunityRepoprotocol (see Bring your own store). - Your own action. metalworks never posts unless you call
RedditOAuth.post_comment(ormw.reddit.post). Queue drafts for human review, post to Slack, write to a DB — the gate hands you a vetted draft and stops.
Adaptive loops
run_discovery also exposes the seams an adaptive product needs without baking in
a memory system or a database:
query_performance: Callable[[str], float]— rank queries by your own metric.on_query_result: Callable[[str, int, int], None]— write back per-query metrics.OpportunityRepo.opportunity_exists(url)— dedup so a seen post never re-burns two LLM calls.