Skip to content

feat(rewards): add opt-in AI search query generator with self-learning cache - #616

Open
phanex wants to merge 3 commits into
TheNetsky:v4from
phanex:feat/ai-query-resolver
Open

phanex wants to merge 3 commits into
TheNetsky:v4from
phanex:feat/ai-query-resolver

Conversation

@phanex

@phanex phanex commented Sep 23, 2026

Copy link
Copy Markdown

Summary

Adds an opt-in AI-powered search query generator (experimental.aiQueryGenerator) for SearchOnBing activities to intelligently handle localized/non-English cards (e.g., German, French, Spanish, etc.) that currently fail due to English-only heuristic parsing.

Problem

In SearchOnBingShared.ts, when a card has no pre-defined queries in bing-search-activity-queries.json, the fallback regex (extractSearchTerm) only strips English keywords (such as search on bing for, look up, find).

When non-English cards appear (for example, German: Title: "Cleverer Bankgeschäfte machen", Description: "Suchen Sie auf Bing, um Optionen für Giro- und Sparkonten zu vergleichen"), the fallback submits the entire verbose sentence into Bing search. Bing rejects verbose sentences and awards 0 points, whereas natural short queries like "Bestes Sparkonto" or "Girokonto Vergleich" immediately award points.

Solution

  1. Opt-in Configuration:
    Disabled by default (false). Users can enable it in config.json or via environment variables:
    "experimental": {
        "aiQueryGenerator": true
    }

… activities (fixes TheNetsky#603)

- Parse Explore on Bing activities dynamically from React Server Component (RSC) flight chunks via Fluent UI design tokens (findTextByClass), completely language-agnostic across all locales
- Strip zero-width Unicode characters (\u200B-\u200D, \uFEFF) from titles and descriptions
- Introduce offerAdapter to unify ParsedOffer to BasePromotion transformation with safe defaults
- Add fallback in DailySet and MorePromotions for RSC-only offers not returned by the legacy dashboard API
- Align UrlReward context with /earn (matching bootstrap and router state tree)
- Simplify quest completion regex to use universal slash-based task counts without language-specific keywords
@lasbt

lasbt commented Sep 29, 2026

Copy link
Copy Markdown

Personally, I don’t think implementing an AI model would be sustainable as the user base grows (even if each user gets their own API key), especially due to the limitations of free-tier plans and the increasing consumption of natural resources required to run these models.

That said, this is such a cool idea! It would be even better if users could opt to use a self-hosted AI model, so they have full control over how their model responds, and the service can’t suddenly be deactivated because of a company’s TOS or policy changes, like using ollama, instead.

@phanex

phanex commented Sep 29, 2026 •

Copy link
Copy Markdown
Author

Personally, I don’t think implementing an AI model would be sustainable as the user base grows (even if each user gets their own API key), especially due to the limitations of free-tier plans and the increasing consumption of natural resources required to run these models.

This is a public DuckDuckGo AI with no API requirement. I have also created a fallback: if the search fails, the failure is logged in failed.json. You can then copy and paste the failed part into your custom.json file and edit the answers as you wish.

upd. Ok, that is a fair concern, especially regarding cloud API limits and third-party dependencies.

To address this, I have updated the implementation so it is not tied to any single provider:

  1. Self-hosted models first: It now supports local LLMs (such as Ollama or LM Studio) via standard OpenAI-compatible endpoints. You can simply set CONFIG_EXPERIMENTAL_AI_BASE_URL="http://localhost:11434/v1" and CONFIG_EXPERIMENTAL_AI_MODEL="llama3" (or any model you have locally), so no external API or cloud resource is used.
  2. Zero-setup default: For users who don't want to run a local LLM, it defaults to a free, public endpoint that requires no API keys and no registration.
  3. Fully optional: The entire feature is off by default (aiQueryGenerator: false), so anyone who prefers not to use an LLM won't be affected.
  4. Local caching: Any successful query returned by the model is immediately saved to custom.json, meaning each activity is only queried once and subsequent runs are completely local.
  5. Manual fallback: If a card fails, it gets logged to failed.json, allowing users to manually map queries in custom.json without involving an LLM at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants