Repository navigation
GRANITE-71500: Content AI Semantic Search - #512
Conversation
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ontentSource=wknd)
…dd missing overlay comment to contentaisearch.less Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ase image) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
com.adobe.cq.wcm.core.components.services.contentai (and the ContentAIClient service it exposes) is scoped to AEM Cloud Service's com.adobe.aem.internal API region in the real product feature model (confirmed against CQ/quickstart's release-candidate/foundation-2026.07 branch) - not global - so no customer/application-tier bundle can call it directly, regardless of how the import is declared or which SDK version is pinned. This is a platform-level access restriction, not a publish-timing gap, and it applies to this bundle the same as any other. Removes the servlet, its response DTO, and its test (Task 8 of the implementation plan), and the now-unused org.jetbrains:annotations dependency it required. The resultsSize/totalResults-sum fix from aem-core-wcm-components PR #3068 remains unaddressed by this branch as a result - deferred until a numbered release includes it, same as the rest of that PR's server-side changes. The client-side JS/CSS overlays (Tasks 5-6) and the i18n label override (Task 7) are unaffected and still valid, since they don't call this service directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…as a temporary workaround Env 809713's own Content AI bucket isn't yet Release-Program-enabled for the experimental content-sources API (403 'A valid experimental scope is required'), confirmed despite a correctly-scoped Developer Console product profile. As a temporary unblock, points baseUrlOverride at publish-p149667-e1527800.adobeaemcloud.com's already-working 'wknd' content source instead of this environment's own bucket. Both values now come entirely from Cloud Manager environment variables (CONTENT_AI_BASE_URL_OVERRIDE as a plain string, CONTENT_AI_API_KEY as a secretString) rather than being hardcoded - set via a direct PATCH to the Cloud Manager Variables API (the web UI's own PATCH to this endpoint is currently blocked by a CORS gateway misconfiguration on Adobe's side). defaultContentSource dropped per request - falls back to the component's own default resolution. Revert baseUrlOverride once env 809713 gets its own Release Program grant - see docs/superpowers/specs/2026-08-05-wknd-contentai-semantic-search-demo-design.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
wknd/components/search reverted to core/wcm/components/search/v1/search (was bumped in-place to v3 in an earlier commit) so any other page/XF authoring a v1 search instance keeps rendering v1 unaffected. Added a new, separate wknd/components/searchv3 proxy (jcr:title 'Quick Search (V3)', sling:resourceSuperType core/wcm/components/search/v3/search) instead, and pointed the site header experience fragment's search instance at that new resourceType so the header specifically gets the v3 AI/Semantic Search toggle, without touching v1's own resourceType identity anywhere else. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…blish The prior config only lived under config.publish.dev, so it never reached the Author tier - confirmed via env 809713's aemerror log: ContentAIClientException 'Content AI API key (X-Api-Key) is not configured' from ContentSourcesDataSourceServlet, on an aem-author pod. Content-source browsing while authoring (the Content Scope tab's content source dropdown) runs on Author; the live search/gensearch calls run on Publish - both tiers need the same baseUrlOverride/apiKey config. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ND's brand Both overlay CSS files used generic ported colors (purple/blue accents) and rounded corners that didn't match WKND's actual site theme. Re-themed using WKND's own CSS custom properties (ui.frontend/src/main/webpack/base/sass/_variables.scss): --brandPrimary (#FFEA00 yellow) for solid-fill accents (AI summary icon background, active layout toggle, both AI-toggle switches' checked state), --brandSecondary (#202020 near-black) for accent text/focus outlines (never yellow text/borders directly - poor contrast), --linkColor (#0045FF) for inline text links, and border-radius flattened to 0 site-wide per WKND's own --buttonBorderRadius:0px convention (cards, chips, buttons, load-more) - functional circles (spinners, toggle knobs) left circular. Added explicit font-family (--fontFamilySansSerif) so form controls/buttons don't fall back to the browser's default UI font instead of WKND's Source Sans Pro stack. This is a WKND-specific customization on top of the ported PR #3068/#3069 fixes - see the updated overlay comments in both files for what to preserve when these overlays are eventually removed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…patcher Confirmed root cause of a 404 on .../contentaisearch.gensearch.json?q=... via dev.wknd.site (publish/Dispatcher- fronted): the response was a full rendered 404 HTML page, meaning Dispatcher itself rejected the request before it ever reached AEM - not an AEM-side error. Dispatcher's default filter policy is deny-first, and this project's existing filters.any only allowlists the old Quick Search's 'searchresults' selector (/0110), nothing for ContentAISearchResultsServlet/ContentAIGenSearchServlet's 'search'/'gensearch' selectors. Added /0115 and /0116 for those. This explains why the same request worked against Author (no Dispatcher in front of it) but not against dev.wknd.site (publish, Dispatcher-fronted) - not a missing environment variable, which was the other hypothesis in play. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Consolidates the per-environment ContentAIClientImpl.cfg.json (dev-only, author + publish) into the runmode-agnostic config.author/config.publish folders, now that the client ID (6e6eca478215492da5f53eb383ce2dfc) has proper product-profile access and aem.experimental scope across all three environments (809713 dev, 887927 stage, 887971 prod), each with its own working bucket. Drops baseUrlOverride entirely - no longer needed now that every environment's own bucket works directly, and the same api key value resolves per-environment via Cloud Manager's own CONTENT_AI_API_KEY variable scoping, so one shared config pair covers dev/stage/prod without per-runmode duplication. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…entaisearch Code review flagged contentSources="[wknd]" as pointing at a content source name that doesn't correspond to any real acquisition-based Content AI source (the actual sources are named after their acquisition, e.g. dev-wknd-site/stage-wknd-site/wknd-site). Rather than hardcode a guessed/environment-specific name into content, drop the default entirely so an author must explicitly pick the correct content source per environment via the dialog.
… check AbstractContentAISearchServlet currently collapses every ContentAIClientException into a generic 502 Bad Gateway, whether the real cause is "not configured" or a genuine backend failure - there's no way for the frontend to tell them apart. For anyone installing this package without a Content AI API key configured yet (the common case for a fresh aem-guides-wknd install), that means a broken-looking 502 instead of a clear message. Add a WKND-owned ContentAIAvailability Sling Model that reads whether ContentAIClientImpl's apiKey is configured directly via ConfigurationAdmin (a standard, publicly-accessible OSGi service - unlike ContentAIClient itself, which is scoped com.adobe.aem.internal and unreachable from application-tier code, per the constraint already documented in 90928bf/d74441e). Wire it into a WKND-owned contentaisearch.html overlay: render the real core component when configured, otherwise a plain "Content AI search is not configured for this environment yet" message. Also author a new /content/wknd/us/en/ai-powered-search page with the contentaisearch component on it, so the feature is visible out of the box on install - matching WKND's existing convention of shipping sample content that assumes further setup elsewhere (e.g. the Commerce/CIF sample content). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rationale
Code review correctly flagged that the getConfiguration(pid) side-effect
comment cited deploy ordering ("any real deployment already ships a
.cfg.json") as why the phantom-config side effect is safe - but that's
exactly the assumption the review called fragile (it doesn't hold during
a first deploy or a misconfigured environment). The actual reason it's
safe is unrelated to ordering: per OSGi/Felix semantics, an unpersisted
getConfiguration() result is inert until update() is called, so it can't
interfere with a later real config deployment regardless of when this runs.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Remove the Title and Text components above the contentaisearch component so the page matches the bare search-box layout used on https://dev.wknd.site/us/en/contentai-search.html. - Simplify the search placeholder from "Search WKND adventures" to "Search" to match the reference. - Order the ai-powered-search page after about-us in the parent page's sibling list so "AI-Powered Search" renders as the last item in the primary/footer navigation, matching the reference site. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ayout The contentaisearch page's content container was missing the site's standard 'Fixed Width' style (cq:styleId 1554340406437), which is what constrains/centers content to the page's normal reading width and renders the container as a semantic <main cmp-layout-container--fixed> element - every other WKND content page picks this up the same way. Without it, the search input rendered flush against the browser edges and full raw viewport width instead of matching the standard WKND content margins used on https://dev.wknd.site/us/en/contentai-search.html. Also widen the inner responsive grid column to 12 (full width of the now-fixed container) to match that reference layout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ontentAIClientImpl PID binding resolveConfigured() called ConfigurationAdmin.getConfiguration(pid) on almost every page render. Per OSGi/Felix semantics, that single-argument form binds a PID to whichever bundle calls it when no ManagedService is currently registered for it at that moment - whether because none exists yet, or because the real one is mid-restart during a bundle refresh. Since this model runs far more often than the real ContentAIClientImpl service activates, it was reliably winning that race and binding the shared PID to this (WKND core) bundle instead of the vendor bundle that actually implements the service - after which Felix silently stops delivering configuration updates to the real service, breaking Content AI regardless of what apiKey/baseUrlOverride is configured. Confirmed live, twice: a real apiKey + baseUrlOverride set via the console still failed with 'Content AI API key (X-Api-Key) is not configured' from the vendor's own ContentAIClientImpl, and the ContentSourcesDataSourceServlet dialog dropdown stayed empty, until the config's bundle binding was cleared. First fix attempt kept getConfiguration(pid) (the only lookup method Sling Mocks' MockConfigurationAdmin implements) and called configuration.setBundleLocation(null) immediately after, guarded to only fire when getProperties() == null so an already-correctly-bound, populated configuration is never touched - code review caught that an earlier, unconditional version of this would have repeatedly unbound an already-working configuration on every render. That guarded version still wasn't enough: verified live that simply calling getConfiguration(pid) at all - even when never followed by setBundleLocation - can itself dynamically bind the PID to the caller if the real ManagedService happens to not be registered at that exact instant (e.g. mid bundle-restart from a redeploy), independent of whatever this class does afterward. Final fix: try the two-argument getConfiguration(pid, null) first. Passing an explicit location (even null) means that call never dynamically binds the PID to the caller, closing the race structurally instead of narrowing it. Only fall back to the single-argument form (with the same guarded setBundleLocation(null) as before) when the two-argument form throws UnsupportedOperationException, which is all MockConfigurationAdmin knows how to do - so the production code path never touches bundle-location state at all, and the fallback exists purely for this class's own unit test. Verified against a real Content AI environment: after this fix, the contentaisearch dialog's Content Sources dropdown populates with real content sources, and bundleLocation stayed unbound across 8 consecutive page renders (previously it would flip to the WKND bundle within the first render or two). Added two Mockito-based tests (spying on the context's own ConfigurationAdmin rather than replacing it outright, since a full replacement breaks unrelated internal PID lookups the mock doesn't know how to answer) asserting setBundleLocation(null) fires only for a fresh phantom configuration and never for one that's already populated - MockConfigurationAdmin can't observe bundle-location calls at all, so the existing tests gave zero coverage of this fix's actual behavior. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sn't set Add an explicit ';default=' clause to the Cloud Manager secret placeholder syntax so, on an environment where the CONTENT_AI_API_KEY secret is genuinely never configured, apiKey resolves to an empty string rather than the literal, unresolved '$[secret:CONTENT_AI_API_KEY]' placeholder text - which is non-blank and so silently defeats ContentAIAvailabilityImpl's isConfigured() blank-check, permanently hiding the 'not configured' fallback message this PR is built around. UNVERIFIED: the $[env:...]/$[secret:...] token substitution this depends on runs as part of an actual Cloud Manager deployment pipeline, not something a local AEM SDK instance ever executes (confirmed empirically - this exact instance never resolves the token regardless of this change, since nothing here implements the substitution at all). This needs confirmation against a real Cloud Manager pipeline run before anyone relies on it - flagging that plainly rather than presenting it as tested. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Pushed 4 follow-up commits addressing UI parity with the reference implementation and a real correctness bug found during manual verification: UI/layout — matched Bug fix — Note: this was verified against a single AEM instance, not a multi-pod publish rolling deploy — flagging that as an open assumption rather than a fully closed guarantee. Also included: a small, explicitly-unverified config change ( 🤖 Generated with Claude Code |
…tentAIAvailability API bnd-baseline-maven-plugin (configured in core/pom.xml, and part of this project's build since 2019 - see git blame on that plugin block) fails the core module's build because this PR adds a new public interface, ContentAIAvailability, to a newly-exported package (com.adobe.aem.guides.wknd.core.models.contentai, versioned via its own package-info.java). Per the OSGi Alliance's Semantic Versioning whitepaper (https://docs.osgi.org/whitepaper/semantic-versioning/), a backward-compatible API addition with nothing removed requires a MINOR bundle-version bump - exactly what the plugin reports: aem-guides-wknd.core BUNDLE MAJOR 4.0.5.SNAPSHOT 4.0.4 Suggest: 4.1.0 This repo's own tag history confirms MINOR bumps (0.1.0, 0.2.0, 0.3.0, 1.1.0, 2.1.0, 3.1.0, 3.2.0) are an established, recurring part of its release history - not a first-of-its-kind departure - even though the most recent stretch since 4.0.0 happened to stay patch-only because nothing in that window added new exported API. Applied via [INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for com.adobe.aem.guides:aem-guides-wknd.all:content-package:4.1.0-SNAPSHOT [WARNING] The expression ${version} is deprecated. Please use ${project.version} instead. [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] WKND Sites Project - Reactor Project [pom] [INFO] WKND Sites Project - Core [jar] [INFO] WKND Sites Project - UI Frontend [pom] [INFO] WKND Sites Project - UI apps structure [content-package] [INFO] WKND Sites Project - UI apps [content-package] [INFO] WKND Sites Project - UI content [content-package] [INFO] WKND Sites Project - UI config [content-package] [INFO] WKND Sites Project - UI sample content [content-package] [INFO] WKND Sites Project - All [content-package] [INFO] WKND Sites Project - Integration Tests [jar] [INFO] WKND Sites Project - Dispatcher [pom] [INFO] WKND Sites Project - UI Tests [pom] [WARNING] The POM for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 is missing, no dependency information available [WARNING] Failed to retrieve plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0: Failed to parse plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0 (/Users/apoorvr/.m2/repository/org/eclipse/m2e/lifecycle-mapping/1.0.0/lifecycle-mapping-1.0.0.jar): zip END header not found [INFO] [INFO] ----------------< com.adobe.aem.guides:aem-guides-wknd >---------------- [INFO] Building WKND Sites Project - Reactor Project 4.1.0-SNAPSHOT [1/12] [INFO] from pom.xml [INFO] --------------------------------[ pom ]--------------------------------- [WARNING] The POM for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 is missing, no dependency information available [WARNING] Failed to retrieve plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0: Failed to parse plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0 (/Users/apoorvr/.m2/repository/org/eclipse/m2e/lifecycle-mapping/1.0.0/lifecycle-mapping-1.0.0.jar): zip END header not found [INFO] [INFO] --- versions:2.21.0:set (default-cli) @ aem-guides-wknd --- [INFO] Searching for local aggregator root... [INFO] Local aggregation root: /private/tmp/claude-503/-Users-apoorvr/d588db18-8a84-41a4-98ba-d76fddb38246/scratchpad/wknd-pr512 [INFO] Processing change of com.adobe.aem.guides:aem-guides-wknd:4.1.0-SNAPSHOT -> 4.1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for WKND Sites Project - Reactor Project 4.1.0-SNAPSHOT: [INFO] [INFO] WKND Sites Project - Reactor Project ............... SUCCESS [ 0.275 s] [INFO] WKND Sites Project - Core .......................... SKIPPED [INFO] WKND Sites Project - UI Frontend ................... SKIPPED [INFO] WKND Sites Project - UI apps structure ............. SKIPPED [INFO] WKND Sites Project - UI apps ....................... SKIPPED [INFO] WKND Sites Project - UI content .................... SKIPPED [INFO] WKND Sites Project - UI config ..................... SKIPPED [INFO] WKND Sites Project - UI sample content ............. SKIPPED [INFO] WKND Sites Project - All ........................... SKIPPED [INFO] WKND Sites Project - Integration Tests ............. SKIPPED [INFO] WKND Sites Project - Dispatcher .................... SKIPPED [INFO] WKND Sites Project - UI Tests ...................... SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.159 s [INFO] Finished at: 2026-09-03T17:44:47+05:30 [INFO] ------------------------------------------------------------------------, which is the project's own reactor-wide version property and affects only pom.xml version strings - no code changes. Verified: [INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for com.adobe.aem.guides:aem-guides-wknd.all:content-package:4.1.0-SNAPSHOT [WARNING] The expression ${version} is deprecated. Please use ${project.version} instead. [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] WKND Sites Project - Reactor Project [pom] [INFO] WKND Sites Project - Core [jar] [INFO] WKND Sites Project - UI Frontend [pom] [INFO] WKND Sites Project - UI apps structure [content-package] [INFO] WKND Sites Project - UI apps [content-package] [INFO] WKND Sites Project - UI content [content-package] [INFO] WKND Sites Project - UI config [content-package] [INFO] WKND Sites Project - UI sample content [content-package] [INFO] WKND Sites Project - All [content-package] [INFO] WKND Sites Project - Integration Tests [jar] [INFO] WKND Sites Project - Dispatcher [pom] [INFO] WKND Sites Project - UI Tests [pom] [INFO] [INFO] ----------------< com.adobe.aem.guides:aem-guides-wknd >---------------- [INFO] Building WKND Sites Project - Reactor Project 4.1.0-SNAPSHOT [1/12] [INFO] from pom.xml [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- clean:3.0.0:clean (default-clean) @ aem-guides-wknd --- [INFO] [INFO] --- enforcer:3.0.0:enforce (enforce-maven) @ aem-guides-wknd --- [WARNING] Rule 1: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message: Maven must be executed with Java 21. [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for WKND Sites Project - Reactor Project 4.1.0-SNAPSHOT: [INFO] [INFO] WKND Sites Project - Reactor Project ............... FAILURE [ 0.097 s] [INFO] WKND Sites Project - Core .......................... SKIPPED [INFO] WKND Sites Project - UI Frontend ................... SKIPPED [INFO] WKND Sites Project - UI apps structure ............. SKIPPED [INFO] WKND Sites Project - UI apps ....................... SKIPPED [INFO] WKND Sites Project - UI content .................... SKIPPED [INFO] WKND Sites Project - UI config ..................... SKIPPED [INFO] WKND Sites Project - UI sample content ............. SKIPPED [INFO] WKND Sites Project - All ........................... SKIPPED [INFO] WKND Sites Project - Integration Tests ............. SKIPPED [INFO] WKND Sites Project - Dispatcher .................... SKIPPED [INFO] WKND Sites Project - UI Tests ...................... SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.706 s [INFO] Finished at: 2026-09-03T17:44:49+05:30 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0:enforce (enforce-maven) on project aem-guides-wknd: Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed. -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException (full reactor, no baseline-skip flag) passes cleanly at this version, both for just the core module and the whole reactor. This only changes the current in-progress development version; it does not perform an actual release (no SCM tag, no Nexus deploy) - that remains a separate, maintainer-triggered mvn release:prepare/perform step whenever this project's release manager next cuts a release. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…mage) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
Integrates AEM Core WCM Components' Content AI semantic search (search v3's AI toggle + the
contentaisearchcomponent) into the WKND reference site, with WKND branding and a graceful "not configured" fallback for anyone installing this without a Content AI API key set up yet.What's included
ContentAIClientImplOSGi config (author + publish) - reads its API key from a Cloud Manager secret ($[secret:CONTENT_AI_API_KEY]); no hardcoded credentials, nobaseUrlOverride(relies on AEM's own program/env-derived base URL)..search.json/.gensearch.jsonselectors through.resourceSuperType, never touching the vendor package's own content) porting two upstreamaem-core-wcm-componentsfixes (PR #3068, merged; PR #3069, open) ahead of a numbered release that includes them - explicitly temporary, removable once that release ships.wknd/components/contentaisearchproxy component, authored on a new/content/wknd/us/en/ai-powered-searchpage so the feature is visible out of the box.ContentAIAvailabilitySling Model readsContentAIClientImpl's configured API key viaConfigurationAdminand renders a clear "Content AI search is not configured for this environment yet" message instead of the search UI when it's blank - so a fresh install without Content AI set up shows a helpful message instead of a broken 502.MockConfigurationAdmin).Prerequisites to actually use it live
Content AI is still an experimental AEM feature. To see real search results (not just the "not configured" message), an environment needs:
CONTENT_AI_API_KEYCloud Manager secret.POST .../content-sources/acquisition+ an explicitPOST .../content-sources/acquisition/{name}/runstrigger (schedule alone doesn't reliably trigger crawling).contentaisearchcomponent'scontentSourcesexplicitly set to that acquisition's name in the author dialog (deliberately left unset by default - see below).Notable design choices
contentSourcesis not defaulted on the authored component - an earlier iteration hardcoded a guessed source name, which review caught as pointing at a source that wouldn't exist in most environments. An author must explicitly pick the correct per-environment content source./content/wknd/us/en/ai-powered-search- not duplicated intolanguage-masters/enor other locales, unlike most existing WKND pages which are full MSM live copies. Kept simple deliberately for this demo page.Before
After
🤖 Generated with Claude Code