Repository navigation
steampowered.com: add get_app, get_search_results and search_store - #134
Merged
Merged
Conversation
…; get_app takes {}
…tools # Conflicts: # registry.json
… navigating The tools only read the page open in the tab, so answering anything took search_store (a navigation), listing the tools again and get_search_results, while an agent that knew the app's URL could just open it. get_app now takes app (an id or store URL) and get_search_results takes term; both read the store's server-rendered page markup with the tab's session, without leaving the page. Visibility for fetched markup comes from hidden attributes and inline display: none.
…rice Civilization VII's search row shows $49.99, the Deluxe Edition at half price, while the base game costs $69.99. get_search_results told callers a row answers a price question by itself; it now says to read the app's page with get_app for the base game's price.
Contributor
Author
Live, from the home page, the app and search reads each took under half a second and the tab stayed put. Tests pass (3,920). Bench (5 pairs each, paired medians):
For the comparison, "right" means all three base-game prices match the store ($29.99, $59.99, $69.99). The bench's own check only verifies the answer's format. |
…rices out of get_app's message, and mark search_store as not read-only
Contributor
Author
|
Pushed c86efbc:
QA (5 pairs, low thinking): |
yummybomb
marked this pull request as ready for review
October 22, 2026 15:55
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the first tools for steampowered.com, which had a bench intent (
steam-game-price, from #133) but no tools. All three arepagetools onstore.steampowered.com:get_appreads an app page: the one open in the tab ({}), or any app by id or store URL (app) from any store page, by fetching that app page's HTML with the tab's session. It doesn't navigate. It returns name, release date, developers, publishers, genres, the Buy-area options (package, bundle, free-to-play) with shown price, original price and discount, the store currency, and the header's review summaries (Recent / All or English Reviews, each with summary, percent positive and count). An age-gated app returnsage_check, an adult-only app that Steam sends signed-out visitors to its sign-in page for returnssign_in_required, an unknown id returnsnot_found, and a failed request returnsnot_ready.get_search_resultsreads search results: the rows rendered on the open search page ({}), or a term's results (term) fetched from Steam's server-rendered search page, from any store page. Rows come in page order (type, id, url, title, release, platforms, review summary, price), plus the sort, checked filters and Steam's result total.offset/limitonly bound the response. When more results follow the currently rendered range,more_resultsgives a visible next-page link from the open page. Hidden pagination links can repeat rows already loaded by infinite scrolling, so those links and unverified links from fetched markup are omitted.next_stepsexplains how to open the fetched search or scroll and read newly appended rows by offset. It accounts for prior pages and appended rows, and stops continuation once all results are loaded. For a signed-in account, Steam hides owned, ignored and wishlisted rows by the account's preferences only in the live page's script, so a term's fetched rows keep them; the message andnext_stepssay so and point at the open search. The description warns that a row's price can be an edition's sale price: Civilization VII's row shows the $49.99 Deluxe Edition, while the base game is $69.99.search_storetypes the term into the header's "Search the store" box and clicks submit 100 ms after returningnavigation_scheduled(cdp-tools.md §2.2). It'sreadOnlyHint: falsebecause it navigates the tab, like Google'ssearch_flights. The newbench/tasks/steampowered.com/domain.jsonlists it underpage_actions, so every Steam intent still gets it.Both reads return
registered_tools,available_actions(with a valid input for each action in the current state) andnext_steps, as the Google Flights tools in #131 do. On any store page, the reads count as available because they work there when given input. Shared page code is inlib/steam-store.js, inlined withscripts/compose.mjs. The URL patterns are narrowed tostore.steampowered.com;url_patterns_reasonexplains why.Testing
node scripts/validate-registry.mjs: 268 tools valid.node --test "tests/*.test.mjs": 3926 pass.tests/steampowered-store.test.mjsruns each tool from its source against fabricated store markup and checks the result against itsoutputSchema. It covers fetched pages, app URLs given withouthttps://, age checks, unknown ids, 403/429/500/503 failures versus 404/410 missing pages, final-page pagination with limited responses, appended infinite-scroll rows, next-page fallback without a total, hidden pagination links, fetched-page continuation guidance, sign-in age gates, the signed-in hide-preference note, markup-hidden rows, actions on non-app/non-search store pages, and a message that names no edition's price.get_appandget_search_resultswere also run on Steam's served HTML for Civilization V, VI and VII, Stardew Valley, Palworld, and a "civilization" search. Prices, discounts, bundle vs package, review summaries and counts, and rendered rows vs total came out right. The earlier next-page link check did not verify that following it advanced beyond the returned rows; that is covered by the follow-up below.get_appon Stardew Valley, Palworld (a 30% discount and three bundles), Hollow Knight (a bundle price behind "Your Price:"), Dota 2 (free to play), ELDEN RING (age_check) and the home page (wrong_page). Alsosearch_storefrom the home page, thenget_search_resultsin relevance order and Lowest Price order.age_check) and 1 (not_found), and the term "stardew valley" (50 of 83 rows). Each took under half a second and the tab stayed put.limit: 1, reports no further results. Scrolling the first page from 50 to all 83 rows also reports no further results despite stale pagination text. App success, missing-app and age-check behavior still pass./login/?redir=…/agecheck/app/1126320/and returnssign_in_required(before,not_found); 413150 (ok), 292030 (age_check) and 1 (not_found) unchanged. Twelve age-rated apps were checked: every age gate is a redirect to/agecheck/app/<id>/or to sign-in, none is shown inline on the app page. The header search box was found on the home, app and search pages, andsearch_storefrom the search page navigated to the results.draft; nobody other than the author has QA'd them. Unverified: non-USD stores, delisted and pre-purchase pages, any signed-in account, and fetched markup that Steam hides with CSS classes rather thanhiddenor inlinedisplay: none.Bench
QA run at c86efbc, with #136's intents and this branch's
domain.json(5 pairs, paired medians, low thinking). "Right" means all three base-game prices ($29.99, $59.99, $69.99) and English Reviews summaries (Overwhelmingly Positive, Very Positive, Mixed) match the store, checked by hand.steam-game-pricesteam-game-pricesteam-compare-seriessteam-compare-seriesControl's wrong answers were Civilization VII's $49.99 Deluxe sale price, Civilization VI at $10.24, and once Civilization V's Recent Reviews. Treatment called a tool in every trial, with no failed invocations.
Earlier trials, before the request-error and pagination fixes:
5 pairs per row, paired medians,
toolspointed at this branch locally (that edit isn't committed). Until this merges, a bench run of the Steam intents needstoolspointed at this branch, becausedomain.jsonnamessearch_store.steam-game-price(Stardew Valley)steam-game-price(Stardew Valley)steam-compare-series(Civilization V/VI/VII, #136)steam-compare-series(Civilization V/VI/VII, #136)"Right" means all three base-game prices match the store ($29.99, $59.99, $69.99). The bench's own check only verifies the answer's format, so the wrong answers (mostly Civilization VII's $49.99 Deluxe price) still scored as correct.
steam-game-priceis too easy for the tools to matter: control reads the app page in about 4 s. These runs used the tools beforeget_app's message stopped naming the first option's price.