feat(llmo): register recurring DRS prompt-suggestion schedules at onboarding#2824
Open
dzehnder wants to merge 3 commits into
Open
feat(llmo): register recurring DRS prompt-suggestion schedules at onboarding#2824dzehnder wants to merge 3 commits into
dzehnder wants to merge 3 commits into
Conversation
…oarding
Adds three onboarding triggers next to triggerBrandalfOnboardingJob that
register recurring DRS schedules (with an immediate first run) for the
prompt-suggestion pipelines, invoked from the V2 onboarding block after the
Brandalf trigger:
- triggerSemrushPromptJob -> prompt_generation_semrush (twice-monthly)
- triggerCitationAttemptJob -> prompt_generation_agentic_traffic (twice-monthly)
- triggerSyntheticPersonasJob -> prompt_generation_synthetic_personas (quarterly)
Each is guarded by drsClient.isConfigured() and uses a single
createSchedule({ ..., triggerImmediately: true }) call. Split error semantics:
the immediate first run is best-effort (self-heals on the next scheduled run),
but a createSchedule (schedule-registration) failure is logged at ERROR with
site_id + provider_id + status and surfaced to ops -- never silently swallowed,
since a swallowed failure means the site never gets a recurring schedule.
Onboarding still succeeds when a schedule registration fails.
Depends on a new additive createSchedule(...) method in
@adobe/spacecat-shared-drs-client (bumped to 1.14.0); must merge/release after
that shared PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dule signature Match the shared drs-client createSchedule contract (confirmed): - providerIds is an ARRAY (job_config.provider_ids envelope) — pass a one-element array per single-provider pipeline. - cadence enum values use underscores: 'twice_monthly' / 'quarterly' (SCHEDULE_CADENCES); the client derives the cron server-side. - drop orgId/imsOrgId entirely: DRS derives the tenant-isolation key from site_id server-side and rejects any caller-supplied imsOrgId, so it must not be threaded through createSchedule. - add a length-capped description; priority defaults HIGH in the client. Also harden the new Phase 3 before-hook with an explicit timeout for cold esmock module loads. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
This PR will trigger a minor release when merged. |
Address PR review on the prompt-suggestion schedule registration: - Replace the three near-identical exported trigger helpers and the inline per-provider array with a single PROMPT_SUGGESTION_PIPELINES table, iterated by registerPromptSuggestionSchedules. Each providerId+cadence is now declared once; adding a pipeline is a one-line change. Rename reflects the durable effect (register a recurring schedule, not trigger a one-shot job). - Single-layer error ownership: iterate the pipelines under Promise.all with a per-pipeline try/catch that owns the failure (ERROR log + operator Slack signal) and never rethrows, replacing the redundant allSettled + inner catch. - Correct the overstated sequencing comment: the immediate first run fires right after SUBMITTING the async Brandalf job, so it races Brandalf and typically no-ops for brand-new sites, self-healing on the next scheduled run. Note the worst-case quarterly (synthetic_personas) cold-start latency, and add a TODO for the cross-repo follow-up (DRS chaining off base-prompt-gen completion). - Hoist the DRS client to a single DrsClient.createFrom(context) in the V2 block. - Tests: iterate PROMPT_SUGGESTION_PIPELINES (with a drift guard), assert the schedules register after the Brandalf submit, cover the status=unknown and alreadyExisted:true branches, and assert the failure-path Slack warning fires. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
Phase 3 of the DRS prompt-suggestion schedules + onboarding-triggers effort (
local/drs-prompt-suggestions-schedules-onboarding-plan.md). Wires three new onboarding triggers into the V2 onboarding path so newly onboarded LLMO sites get a recurring DRS schedule (plus an immediate first run) for each prompt-suggestion pipeline.New helpers next to
triggerBrandalfOnboardingJobinsrc/controllers/llmo/llmo-onboarding.js, each guarded bydrsClient.isConfigured():provider_idtriggerSemrushPromptJobprompt_generation_semrushtwice_monthlytriggerCitationAttemptJobprompt_generation_agentic_traffictwice_monthlytriggerSyntheticPersonasJobprompt_generation_synthetic_personasquarterlyprompt_generation_agentic_trafficis the provider behind "Citation Attempts" (no standalone citation-attempt provider — the name won't grep, so there's a code comment).drsClient.createSchedule({ ..., triggerImmediately: true })(no separatesubmitJob+createSchedule).enableBrandPresencedefaults false (plan Phase 0.4).Error handling — split semantics
createSchedule(schedule registration): NOT best-effort. A failure means the site never gets a recurring schedule and nothing self-heals, so it is logged at ERROR withsite_id+provider_id+statusand surfaced viasay/ops — never silently swallowed. Onboarding still succeeds (mirrors the brand-activation side-effect handling inbrands.jsactivateBrand, which logs full context before we mirrored it).Cross-repo dependency (deploy ordering)
Depends on a new additive
createSchedule(...)method in@adobe/spacecat-shared-drs-client(separate spacecat-shared PR, not yet released). This PR bumps the dependency to1.14.0.This PR must merge/release after the shared drs-client
createSchedulePR is published as 1.14.0. Until then, a freshnpm ci/ bundle build cannot resolve1.14.0and CI install will be red — this is the intended cross-repo sequencing, not a defect. Unit tests do not hard-depend on the real method: they mock the DRS client (as existing onboarding tests do).Confirmed
createSchedulesignature (from the shared PR author)Key contract points this PR honors:
providerIdsis an array (thejob_config.provider_idsenvelope), so each helper passes a one-element array.twice_monthly/quarterly); the client derives the cron server-side (frequency:'cron', per-site hour jitter fortwice_monthly) — callers cannot pass raw cron. Kept as local literals matchingSCHEDULE_CADENCESso the module loads against the currently-installed client; can be swapped for the imported const once 1.14.0 is installed.orgId/imsOrgIdparams — DRS derives the tenant-isolation key fromsite_idserver-side and rejects any caller-suppliedimsOrgId(at any nesting/case). This PR deliberately does not threadimsOrgIdintocreateSchedule.Tests
test/controllers/llmo/llmo-onboarding.test.js(mock DRS client; no realcreateScheduledependency):providerIds(array) + cadence withtriggerImmediately: true,enableBrandPresence: false, and noimsOrgId/orgId;createSchedule) whenisConfigured()is false;createSchedulefailure propagates to the caller (not swallowed at the helper);activateBrandAndGeneratePromptsregisters all three schedules after the Brandalf trigger;createSchedulefailure is logged at ERROR withsite_id+provider_id+statuswhile onboarding still completes.npm run lintclean. All 11 new tests pass. The fullllmo-onboarding.test.jsfile is 142 passing / 1 failing, where the single failure is a pre-existingsettleWithin"before all" hook timeout that also fails on cleanmain(environment-related, unrelated to this change).🤖 Generated with Claude Code