Introduce prompt management - #949
Closed
chrfritsch wants to merge 30 commits into
Closed
Conversation
* Add prompt testing * fix * added save button and model selector * add suggestion field widget * add dependencies * Fix PHPStan errors in thunder_ai_prompt_management Resolves the 19 static analysis errors that failed the deprecation testing CI job (missing return types, undefined methods/properties on generic entity interfaces, an unhandled match branch, and a return type mismatch). * Fix coding style violations in thunder_ai_prompt_management Resolves the errors from the drupal-coder coding style check: a same-namespace use statement, missing match() spacing, an over-long line, undocumented parameters, and an unused import. * Require drupal/field_widget_actions ^1.4 explicitly field_widget_actions was only a transitive dependency, so a fresh composer resolve (this distribution ships no composer.lock) could land on 1.3.0, which lacks the #validate/clearErrorsForAction wiring that AiTaskSuggestion relies on to suppress unrelated required-field errors on AJAX suggestion requests. That is what broke the "kernel" CI job: AiTaskSuggestionTest asserted on a #validate key that 1.3.0 never sets. --------- Co-authored-by: Christian Fritsch <christian.fritsch@burda.com>
Optional chaining (?.) isn't supported by the project's pinned eslint/parser, causing a parse error that hid the further issues below it. Replaced it with plain && checks, named the wrapping IIFE, and renamed the summary callback's parameter to stop it shadowing the outer attach(context) parameter.
CI's prettier defaults to arrowParens: always (my local eslint-config-drupal bundles an older prettier defaulting to "avoid"), so the single-param arrow needs parens.
- Fix a real int/string type-mismatch bug in AIPromptAccessControlHandler::checkAccess() (entity->getOwnerId() is int, account->id() is string, so the strict === always failed for real users) - caught after fixing the test below. - Fix AIPromptAccessControlHandlerTest to not let its "own" prompt owner become uid 1, which bypasses access checks as the superuser and made the update/delete own-vs-any assertions vacuous. - Guard AIPromptTestForm against a stale entity_context referencing an uninstalled/renamed entity type (getDefinition() no longer throws). - Replace leftover "example" scaffold text in AiTaskForm messages and AiTask's property docblocks with actual AI task wording. - Switch AIPromptForm to AutowireTrait + promoted properties instead of a manual constructor/create(). - Extract the "type.bundle" string decoding shared by EntityContextWidget and AIPromptTestForm into one static helper. - Memoize AiTaskSuggestion::loadPrompts() per task/type/bundle to avoid re-querying once per delta on multi-value fields. - Switch form.js to an arrow-function IIFE per JS conventions. - Condense multi-line rationale comments down to one line per the project's comment convention.
The drupal-coder check fails on any phpcs finding, warnings included, so the condensed one-line comments from the previous commit still needed trimming to stay under 80 characters.
…957) * Add ThunderPromptSource: ai_prompt_content-backed prompt source seam Implements ai_chatbot_assistant_ui's PromptSourceInterface against this module's ai_prompt_content entity, grouped by ai_task and filtered by the entity_context field (type.bundle / type.* values). Swapped in via ThunderAiPromptManagementServiceProvider::alter(), guarded by hasDefinition() so this module carries no hard dependency on the chatbot module. getSlashGroups()/getSuggestions() take a CacheableMetadata argument and add their own tags via addCacheableDependency() as they build the response, matching the interface signature after the seam's cacheability rework - the block and controllers own route/session.exists/user.permissions themselves, since those apply regardless of which provider is active. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Fix CI failures on ThunderPromptSource - phpcs: capitalize the ThunderPromptSourceTest doc comment that starts with a method name. - phpstan: read entity_context values via getValue()['value'], matching EntityContextWidget's existing pattern, instead of the untyped ->value property access that FieldItemInterface doesn't declare. - phpstan: baseline the "unknown interface" finding for PromptSourceInterface - ai_chatbot_assistant_ui is an optional integration with no hard composer dependency, same as the existing entity_browser baseline entries. * Require ai_chatbot_assistant_ui as a dev dependency for phpstan interface.notFound is non-ignorable in phpstan, so the earlier baseline entry for PromptSourceInterface never actually worked. Add the module to require-dev (1.0.x-dev, same pattern as thunder_testing_demo - it has no tagged release yet) so the interface is resolvable, and drop the baseline entry now that the error is gone at the source. This module stays a dev-only/soft dependency: it's absent from require and from thunder_ai_prompt_management's .info.yml, so production installs are unaffected; only test/static-analysis tooling needs it on disk. * Enable entity_blueprint in ThunderPromptSourceTest thunder_ai_prompt_management's entity_context_prompt_builder service autowires entity_blueprint's BlueprintSchemaBuilderInterface. Enabling thunder_ai_prompt_management without entity_blueprint (and its own field/text/filter/entity_test dependencies - the same set EntityContextPromptBuilderTest already enables) leaves that interface unbound, so the container fails to compile for every test method. --------- Co-authored-by: Christian Fritsch <christian.fritsch@burda.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The "type.bundle"/"type.*" encoding, decoding, grouping, and matching rules were reimplemented independently in EntityContextWidget, AIPromptTestForm, ThunderPromptSource, and AiTaskSuggestion, already drifting into three different styles. Move the shared logic into one dependency-free EntityContext class and delegate to it from all four call sites; no behavior change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Consolidate the entity_context field-value extraction loop, still duplicated in three call sites, into EntityContext::valuesFromField(). - Fill in the info.yml description/package placeholders. - Add declare(strict_types=1) to the .module file, matching the rest of the module. - Use match() in AIPromptForm::save(), matching AiTaskForm's pattern. - Mark ThunderAiPromptManagementServiceProvider final, matching every other single-implementation class in the module. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Matches the PHP attribute already used elsewhere in the module (AiTaskSuggestion) instead of the older docblock annotation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
EntityContextWidget::currentSelections(), ThunderPromptSource:: matchesContext(), and AIPromptTestForm::allowedContexts() each added no logic of their own beyond a single delegating call into EntityContext. Inline them at their call sites. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Ai prompt list filters. * Ai prompt list filters test fix. * Ai prompt list filters test fix. * Ai prompt list filters test fix.
Rebuilds the AI Prompts admin page as a proper View (matching the Content view): sortable columns, native bulk operations wired to the existing delete/save actions, and Gin's status marker styling for free. Adds filters for label, prompt type, and model (the entity reference and model filters need small custom Views plugins since the base fields aren't attached Field API fields). AIPromptListBuilder now only supplies row operations (Edit/Delete/Test prompt), since Views owns the listing itself; the custom AIPromptListFilterForm is fully superseded and removed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- AiTask entity's own label/label_collection read "AiTask"/"AiTasks" (no space) while everywhere else referring to it said "AI Task" - fix the entity labels, its route/menu titles, and the config schema label to match. - Capitalize "ai" to "AI" throughout: permission titles, action link titles, route titles, entity label_singular/plural/label_count, status/log messages, field descriptions, and class doc comments. Also fixes AIPrompt's label_count, which reused the plural string for the singular form. - Rename the "Test prompt" row operation to "Test", matching the terse "Edit"/"Delete" style already used in the same dropdown. - Rename the module itself from "Thunder ai prompt management" to "Thunder AI Prompt Management", matching sibling module names. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Full-width prompt/model fields and a bordered, scrollable response block, matching the styling already used on the main edit form. - Run test/Save prompt now submit via Drupal's Form API AJAX instead of a full page reload, with a throbber during the request. - Gin's sticky-header button clones sit outside the real #actions container (which Gin squeezes to a 1x1px fixed box once sticky actions take over), so the built-in AJAX throbber never reached the visible buttons. js/form.js mirrors the real button's disabled state onto the sticky clone via a real sibling spinner element (::after never paints on <input>, which the sticky buttons are). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wraps the once() call, the sticky-button selector template literal, the optional-chaining replacement, and the MutationObserver options object to stay under the project's 80-char print width. Co-Authored-By: Claude Sonnet 5 <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.
Make sure these boxes are checked before submitting your pull request - thank you!
If you are really awesome, then your feature is covered by additional tests. Well done!