Repository navigation
Conversation
Extend dev.ucp.shopping.catalog.search (search_request) to support relational and intent-specific catalog discovery alongside free-text and filter-based search: - Add purpose (open string vocabulary with well-known values search, recommendation, and swap) to search_request in source/schemas/shopping/catalog_search.json. - Add reference_ids (non-empty array of unique, non-empty product or variant identifiers) to search_request with dependentRequired on purpose. - Document normative processing rules in docs/specification/shopping/catalog/search.md covering pairing constraints, supported identifiers (aligned with catalog.lookup), product and variant self-exclusion semantics, combination with query and filters, and handling of unsupported purpose values. - Add schema-validated request examples for product swap and product recommendation.
Address review feedback on #902: - Qualify standalone purpose in ## Search Inputs as a non-search purpose (such as contextual recommendation) so {"purpose": "search"} alone is not treated as a valid standalone input. - Explicitly state in Rule 1 (Pairing) and purpose.description that when purpose is search (or omitted), the request MUST include at least one of query, filters, or an extension-defined input.
This branch has not been deployed
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
Extends
dev.ucp.shopping.catalog.search(search_request) with two optional fields,purposeandreference_ids, to support relational and intent-specific catalog discovery (recommendationandswap) alongside standard free-text and filter-based search.Motivation
Platforms and agents need to retrieve complementary recommendations and functional substitutes (e.g., swapping an out-of-stock cart item) where
querymay be omitted and one or more anchor product or variant IDs are supplied. Previously,catalog.searchlacked a structured way to pass anchor item identifiers or distinguish whether the Business should return complementary items (recommendation) versus functional substitutes (swap).Schema Shapes and Examples
1.
search_requestSchema Addition (catalog_search.json){ "search_request": { "type": "object", "properties": { "query": { "type": "string" }, "purpose": { "type": "string", "examples": ["search", "recommendation", "swap"] }, "reference_ids": { "type": "array", "items": { "type": "string", "minLength": 1 }, "minItems": 1, "uniqueItems": true }, "context": { "$ref": "../common/types/context.json" }, "signals": { "$ref": "../common/types/signals.json" }, "attribution": { "$ref": "types/attribution.json" }, "filters": { "$ref": "types/search_filters.json" }, "pagination": { "$ref": "../common/types/pagination.json#/$defs/request" } }, "dependentRequired": { "reference_ids": ["purpose"] } } }2. Retrieval Modes at a Glance
purposereference_idssearch(or omitted)query,filters, or extension inputrecommendationreference_idsand/orcontext; optionalquery/filtersswapSHOULDpass 1 ID per request)query(e.g., guided swap) andfilters3. Example Payloads
Use Case A: Product Swap (Substituting an Unavailable Variant)
Passing a variant ID (
prod_abc123_size10) lets the Business match variant-level attributes (Size 10, price,quantity_unit), optionally guided byqueryand constrained byfilters:{ "purpose": "swap", "reference_ids": ["prod_abc123_size10"], "query": "waterproof", "context": { "location": "loc_downtown", "currency": "USD" }, "filters": { "price": { "max": 15000 } }, "pagination": { "limit": 5 } }Use Case B: Product Recommendation
Accepts product IDs, variant IDs, or a mix of both (or omits
reference_idsfor contextual/session recommendations):{ "purpose": "recommendation", "reference_ids": ["prod_abc123", "var_xyz789"], "context": { "address_country": "US", "currency": "USD" }, "pagination": { "limit": 10 } }Changes
source/schemas/shopping/catalog_search.json):purpose(string, open vocabulary with well-known valuessearch,recommendation,swap) andreference_ids(non-empty array of unique, non-empty strings) tosearch_request."dependentRequired": { "reference_ids": ["purpose"] }and a schema description onsearch_request.docs/specification/shopping/catalog/search.md):## Search Inputsand added### Purpose and Reference Identifiersdefining 5 normative rules: Pairing, Supported Identifiers, Self-Exclusion, Combination with Query and Filters, and Unsupported Purpose.Design Decisions & Alternatives Considered
search_requestvs.contextorfilters:context(common/types/context.json) is reserved for provisional, ignorable buyer signals shared across all UCP capabilities, andcontext.intentis already a free-text buyer background string. A Business must not silently ignorepurposeorreference_idsand return a generic catalog browse.filters(shopping/types/search_filters.json) is shared withcatalog.lookupand applies conjunctive (AND) predicates to narrow candidate items, whereaspurposeandreference_idsdefine the retrieval relation and ranking objective.search_requestvs. separaterecommend/swapoperations:queryfor guided swaps,filters,context,pagination,products[]) anddev.ucp.shopping.fulfillmentextension composition ascatalog.search. Modeling them viapurposeandreference_idsavoids duplicating endpoints, MCP tools, and fulfillment composition schemas across the specification.dependentRequired):reference_idsrequirespurpose(dependentRequired, andpurposeMUST NOT besearch) so the Business never has to guess whether anchor IDs represent a complement or a substitute. Conversely,purpose: "recommendation"is permitted withoutreference_idsto support contextual recommendations anchored tocontext, whilepurpose: "swap"requiresreference_ids, andpurpose: "search"(or omitted) requiresquery,filters, or an extension input.reference_idsresolution withcatalog.lookup(MUSTsupport product ID and variant ID;MAYsupport secondary IDs like SKU or handle) so Platforms can pass a specific variant ID when swapping an unavailable cart item (allowing the Business to match variant-level options, price, andquantity_unit).MUSTexclude its parent product forrecommendation, andSHOULDexclude its parent product forswapunless returning a distinct substitute variant of that product.Validation
ucp-schema lint source/(144 files checked, all passed)uv run python scripts/validate_examples.py --schema-base source/schemas/(378 passed, 0 failed)pre-commit run --files source/schemas/shopping/catalog_search.json docs/specification/shopping/catalog/search.md(all hooks passed)DOCS_MODE=spec uv run mkdocs build --strict && DOCS_MODE=spec uv run python scripts/check_links.py site(strict build and link validation passed)