Skip to content

feat: Add simplified pricing display for search-actors with user tier#695

Merged
jirispilka merged 15 commits intomasterfrom
claude/simplify-pricing-output-oQmUw
Apr 18, 2026
Merged

feat: Add simplified pricing display for search-actors with user tier#695
jirispilka merged 15 commits intomasterfrom
claude/simplify-pricing-output-oQmUw

Conversation

@jirispilka
Copy link
Copy Markdown
Collaborator

@jirispilka jirispilka commented Apr 16, 2026

Summary

search-actors used to dump every tier of every event for every actor. For multi-event multi-tier actors this is ~60 price rows that an LLM mostly can't use.

This PR filters search-actors pricing to the user's resolved tier (with a note), keeps fetch-actor-details structurally lossless (full tier matrix preserved), reformats the complete-mode text for consistency with simplified mode, and folds in a handful of related output-shape changes driven by a formal contract.

Why this diff is bigger than "just filter tiers"

Apologies for the size.

Change Why
Added userTier to output, removed isFree LLM needs to know which tier applies; isFree is derivable from model
pricingNote names the resolved tier "Use fetch-actor-details for more" is only actionable if it says which tier
Widget (formatActorForWidget) now takes userTier Otherwise widget price disagreed with LLM text price in ChatGPT mode (review-feedback.md P2)
fetch-actor-details also fetches user tier So its userTier field reflects reality
PAY_PER_EVENT: per-event resolution collected; note fires only when all events agree Avoids mislabelling an actor when events resolve to different tiers
Simplified mode omits event descriptions when events > 5 tiktok-scraper alone is 10 × 6 = 60 rows; LLM doesn't need every description
Complete-mode text reformatted (see contract) Master's boilerplate ("You are not charged for the Apify platform usage...", "in this case named X") adds tokens without adding information — structured data is still lossless

Contract

Single source of truth: res/pricing_output_contract.md. Two modes (complete / simplified), both carry userTier, simplified adds pricingNote. Examples E1–E8 are pinned as unit-test fixtures.

Structured data in complete mode is lossless vs master (full tier matrix preserved). Text output in complete mode is reformatted — see the contract's Intentional text divergence from master section for the specific changes.

Before / after (vs master)

codingfrontend/google-maps-places-scraper via search-actors, anonymous caller (FREE tier):

master: full 6-tier dump — FREE \$0.00999, BRONZE \$0.00199, SILVER \$0.00149, GOLD \$0.00099, PLATINUM \$0.00099, DIAMOND \$0.00099. No userTier. No note.

this PR: one entry — { tier: "FREE", priceUsd: 0.00999 } + userTier: "FREE" + pricingNote naming FREE.

A GOLD user would see \$0.00099 (10× cheaper) without extra prompting. fetch-actor-details still returns the full tier matrix (structurally identical to master); the surrounding text is reformatted.

clockworks/tiktok-scraper: master returns 10 events × 6 tiers × descriptions = ~60 price rows + 10 long descriptions. This PR returns 10 titles × 1 tier + 2 notes.

Testing

  • 552 unit tests; contract examples E1–E8 as exact-object/exact-string assertions.
  • Live matrix on apify-dev (this branch) vs apify-prod (master):
    • fetch-actor-details apify/instagram-scraper — tier matrix identical to prod ✅
    • search-actors "google places" — simplified filtering correct across multi-tier, single-tier, all-flat cases ✅
    • search-actors "tiktok" — >5 events triggers description trim + single-tier note ✅

close: #578

@github-actions github-actions Bot added t-ai Issues owned by the AI team. tested Temporary label used only programatically for some analytics. labels Apr 16, 2026
@jirispilka jirispilka changed the title Add simplified pricing display for search-actors with user tier refactor: Add simplified pricing display for search-actors with user tier Apr 16, 2026
@jirispilka jirispilka changed the title refactor: Add simplified pricing display for search-actors with user tier feat: Add simplified pricing display for search-actors with user tier Apr 16, 2026
@jirispilka jirispilka added the high priority Do this ASAP! This is for mission-critical work or work that blocks other teams in their work. label Apr 16, 2026
Search results dumped all 6 pricing tiers (FREE through DIAMOND) for every
event of every actor, bloating output with no value (e.g. Google Maps Scraper
returned 9 events x 6 tiers = 54 price entries). Only the user's tier matters
in a search listing.

Now search-actors shows only the user's tier price (FREE fallback) plus a
short hint about other tiers. fetch-actor-details is untouched and still
returns full tiered pricing.

- Extend user cache to also return userPlanTier from the same API call
- Add pricingInfoToSimplifiedString and pricingInfoToSimplifiedStructured
- Add userTier to ActorCardOptions, branch in card formatters
- Add pricingNote field to StructuredPricingInfo for the hint
@jirispilka jirispilka marked this pull request as ready for review April 17, 2026 22:41
Comment thread tests/unit/tools.search_actors.widget.response.test.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a tier-aware “simplified pricing” mode for search-actors so results show only the price relevant to the current user’s plan tier (plus a note), while keeping fetch-actor-details pricing “complete” (full tier matrices). It also adds cached user tier resolution (from /users/me) and updates widget/structured output to match the new pricing contract.

Changes:

  • Add getUserInfoCached() (user id + resolved plan tier) and wire it into search + details flows.
  • Implement simplified pricing formatters that resolve a single tier (and optionally omit event descriptions when many events).
  • Update structured output schemas / actor card formatting / web types & mocks to remove isFree and support the new pricing shape.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/unit/utils.userid_cache.test.ts Adds unit coverage for cached user id + plan tier derivation behavior.
tests/unit/utils.pricing_info.test.ts Adds contract-style fixtures/assertions for complete vs simplified pricing formatting.
tests/unit/utils.actor_card.test.ts Updates assertions to reflect removal of isFree from structured pricing.
tests/unit/tools.search_actors.widget.response.test.ts Updates widget-mode search-actors test to pass userTier and simplified pricing options.
src/web/src/utils/mock-actor-details.ts Removes isFree from web mock actor details payloads.
src/web/src/types.ts Updates web pricing types for optional event descriptions + new note fields (but currently missing userTier).
src/utils/userid_cache.ts Replaces cached user-id-only helper with getUserInfoCached() including plan tier normalization.
src/utils/pricing_info.ts Adds tier resolution + simplified/complete pricing string + structured formatters and shared contract comment.
src/utils/actor_details.ts Threads userTier into widget actor-details payload formatting.
src/utils/actor_card.ts Adds tier-aware simplified pricing option and updates widget pricing to use simplified structured pricing.
src/types.ts Extends ActorCardOptions with userTier + simplifyPricingForUserTier.
src/tools/structured_output_schemas.ts Updates pricing schema: removes isFree, adds userTier + pricing note/omission metadata fields.
src/tools/openai/search_actors.ts Fetches user tier in parallel with actor search and formats simplified pricing for text/structured/widget outputs.
src/tools/openai/fetch_actor_details.ts Fetches user tier and threads it into card options + widget details payload.
src/tools/default/search_actors.ts Same as OpenAI variant for simplified tier-aware pricing in default mode.
src/tools/core/search_actors_common.ts Builds search actor cards using default options + userTier + simplified pricing.
src/tools/core/fetch_actor_details_common.ts Fetches user tier only when pricing output is requested; threads it into card options.
src/mcp/server.ts Switches telemetry user-id fetch to use getUserInfoCached().

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils/userid_cache.ts
Comment thread src/utils/userid_cache.ts
Comment thread src/utils/pricing_info.ts Outdated
Comment thread src/tools/structured_output_schemas.ts Outdated
Comment thread src/web/src/types.ts
Comment thread src/web/src/utils/mock-actor-details.ts
jirispilka and others added 4 commits April 18, 2026 07:52
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@jirispilka
Copy link
Copy Markdown
Collaborator Author

image image

@jirispilka jirispilka merged commit d7288ba into master Apr 18, 2026
12 checks passed
@jirispilka jirispilka deleted the claude/simplify-pricing-output-oQmUw branch April 18, 2026 19:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

high priority Do this ASAP! This is for mission-critical work or work that blocks other teams in their work. t-ai Issues owned by the AI team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: simplify search-actors pricing to show resolved price with minimal tier hint

4 participants