Initial implementation of automations frontend - #896
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Test check b16302a — action needed PR introduces 17 frontend files with non-trivial pure utility functions and mock CRUD logic but no tests whatsoever. More details (truncated)Test Files Detected
AnalysisThis draft PR adds an "Automations" frontend to the plugin. All 17 modified files are in New production logic introduced:
Mitigating factors:
Even accounting for draft status, the pure utility functions ( ...truncated. View full analysis details Suggestions
To override, comment |
🤖 LLM Evaluation ResultsOpenAI
❌ Failed EvaluationsShow 6 failuresOPENAI1. TestConversationMentionHandling/[openai]_conversation_from_attribution_long_thread.json
2. TestConversationMentionHandling/[openai]_conversation_from_attribution_long_thread.json
3. TestConversationMentionHandling/[openai]_conversation_from_attribution_long_thread.json
4. TestConversationMentionHandling/[openai]_conversation_from_attribution_long_thread.json
5. TestConversationMentionHandling/[openai]_conversation_from_attribution_long_thread.json
6. TestDirectMessageConversations/[openai]_bot_dm_tool_introspection
Anthropic
❌ Failed EvaluationsShow 6 failuresANTHROPIC1. TestConversationMentionHandling/[anthropic]_conversation_from_attribution_long_thread.json
2. TestConversationMentionHandling/[anthropic]_conversation_from_attribution_long_thread.json
3. TestConversationMentionHandling/[anthropic]_conversation_from_attribution_long_thread.json
4. TestConversationMentionHandling/[anthropic]_conversation_from_attribution_long_thread.json
5. TestConversationMentionHandling/[anthropic]_conversation_from_attribution_long_thread.json
6. TestDirectMessageConversations/[anthropic]_bot_dm_tool_introspection
This comment was automatically generated by the eval CI pipeline. |
📝 WalkthroughWalkthroughAdds a complete automation interface with typed models, mocked CRUD operations, list filtering, creation and editing flows, trigger and agent selectors, reusable configuration shells, and integration into the agents page. ChangesAutomation management
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant AgentsPage
participant AutomationsList
participant AutomationConfigView
participant ClientCRUD
User->>AgentsPage: select Automations
AgentsPage->>AutomationsList: render list
AutomationsList->>ClientCRUD: getAutomations and getAgents
ClientCRUD-->>AutomationsList: return data
User->>AutomationsList: create or edit automation
AutomationsList->>AutomationConfigView: render configuration
User->>AutomationConfigView: save changes
AutomationConfigView->>AutomationsList: return AutomationUpdate
AutomationsList->>ClientCRUD: createAutomation or updateAutomation
ClientCRUD-->>AutomationsList: return saved automation
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Checkov (3.3.8)webapp/src/i18n/en.jsonTraceback (most recent call last): Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (9)
webapp/src/components/agents/agent_selector.tsx (1)
25-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated MCP/tools meta-formatting logic across two files. Both
formatAgentMetaandformatPickerMetaindependently recompute the samemcpCount(distinctserver_origincount) andtoolsLabel(all-tools vs. pluralized count) derivation fromUserAgent, differing only in the join separator (·vs•).
webapp/src/components/agents/agent_selector.tsx#L25-L40: extract themcpCount/toolsLabelcomputation into a shared helper (e.g.,webapp/src/types/agents.tsor a newagent_meta.ts) and haveformatAgentMetacall it.webapp/src/components/agents/new_automation_agent_menu.tsx#L24-L46: haveformatPickerMetacall the same shared helper instead of recomputingmcpCount/toolsLabellocally.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/agent_selector.tsx` around lines 25 - 40, The MCP/tool metadata derivation is duplicated between formatAgentMeta and formatPickerMeta. Create a shared helper for distinct server_origin counting and the all-tools versus pluralized tools label, then update formatAgentMeta in webapp/src/components/agents/agent_selector.tsx:25-40 and formatPickerMeta in webapp/src/components/agents/new_automation_agent_menu.tsx:24-46 to use it while preserving their different separators and channel labels.webapp/src/components/agents/new_automation_agent_menu.tsx (2)
214-216: 🎯 Functional Correctness | 🔵 TrivialAuthor-flagged TODO: description fallback needs to change before merging.
Want me to help wire in a real
descriptionfield (or confirm the intended fallback) before this leaves draft?🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/new_automation_agent_menu.tsx` around lines 214 - 216, Update the agent display logic surrounding the fallback return in the new automation agent menu to use the agent’s real description field instead of custom instructions. If the description field is not yet available, confirm and implement the intended replacement fallback before merging, and remove the temporary TODO.
156-198: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winDropdown ARIA/keyboard gaps.
role='listbox'is applied to a container whose direct children include a header and a search<input>, not just options — this breaks the expected ARIA listbox structure for assistive tech (e.g., wrap only the option items in the listbox role, or usecomboboxwith an owned listbox). Also, there's noEscapekey handling to close the dropdown (only click-outside).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/new_automation_agent_menu.tsx` around lines 156 - 198, The dropdown in the open state has an invalid listbox structure and lacks Escape handling. Update the JSX around Dropdown and OptionsList so the listbox role applies only to the agent options (or implement the equivalent combobox with an owned listbox), keeping the header and SearchInput outside that role; add keyboard handling tied to the existing open/close state so pressing Escape closes the dropdown and preserves the current focus behavior.webapp/src/components/agents/automations_list.tsx (2)
86-95: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the
AIProviderTypeAgentconstant instead of the literal'agent'.
@/types/automationsexportsAIProviderTypeAgentfor this exact purpose, and it's already used the same way inautomation_config_view.tsx'sensureAIPromptAction. Hardcoding'agent'here risks drift/typos.♻️ Proposed fix
import { Automation, AutomationUpdate, + AIProviderTypeAgent, getAIPromptAction, getTriggerType, } from '`@/types/automations`'; ... { id: 'run-agent', ai_prompt: { prompt: '', - provider_type: 'agent', + provider_type: AIProviderTypeAgent, provider_id: agent.id, }, },🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/automations_list.tsx` around lines 86 - 95, In the automation action configuration, update the provider_type value within the run-agent action to use the exported AIProviderTypeAgent constant from `@/types/automations` instead of the literal 'agent'. Preserve the surrounding action and prompt configuration.
137-171: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winMissing-profile fetch re-runs on every unrelated automations-state change.
This effect depends on
automations(a new array reference on every toggle/edit/delete/create) andprofiles. If anycreated_byid never resolves (e.g. deleted user), it will stay inmissingIdsforever and this effect re-fetches it on every unrelated list mutation, with no memoization of ids already attempted.♻️ Proposed fix (track attempted ids)
+ const attemptedIdsRef = useRef<Set<string>>(new Set()); + useEffect(() => { const missingIds = [...new Set( automations. map((item) => item.created_by). - filter((id): id is string => Boolean(id) && !profiles[id]), + filter((id): id is string => Boolean(id) && !profiles[id] && !attemptedIdsRef.current.has(id)), )]; if (missingIds.length === 0) { return () => { // No profiles to fetch }; } + missingIds.forEach((id) => attemptedIdsRef.current.add(id));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/automations_list.tsx` around lines 137 - 171, Update the profile-fetching useEffect and its surrounding state in automations_list.tsx to track creator IDs already attempted, using a stable attempted-ID set/ref so unresolved IDs are not fetched again after unrelated automations or profiles changes. Build missingIds by excluding both cached profiles and attempted IDs, mark IDs as attempted before calling getProfilesByIds, and preserve the existing cancellation and RECEIVED_PROFILES dispatch behavior.webapp/src/components/agents/row_actions_menu.tsx (1)
29-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDropdown doesn't close on Escape.
Only an outside-
mousedownlistener closes the menu; keyboard-only users have no way to dismiss it via Escape.♻️ Proposed fix
useEffect(() => { if (!open) { return () => { // No mousedown listener while menu is closed }; } const handler = (e: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { updateOpen(false); } }; + const keyHandler = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + updateOpen(false); + } + }; document.addEventListener('mousedown', handler); - return () => document.removeEventListener('mousedown', handler); + document.addEventListener('keydown', keyHandler); + return () => { + document.removeEventListener('mousedown', handler); + document.removeEventListener('keydown', keyHandler); + }; }, [open, updateOpen]);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/row_actions_menu.tsx` around lines 29 - 42, The open-menu effect in the row actions component only handles outside mousedown events. Add a keydown listener while open that calls updateOpen(false) when the Escape key is pressed, and remove that listener during cleanup alongside the existing mousedown listener.webapp/src/components/agents/config_view_shell.tsx (1)
111-128: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winBoth tab strips render plain buttons without ARIA tab semantics. Neither
ConfigViewShell's section tabs norFilterTabs' ownership tabs exposerole="tablist"/"tab"oraria-selected, so screen-reader users don't get standard tab navigation semantics.
webapp/src/components/agents/config_view_shell.tsx#L111-L128: addrole="tablist"toTabsContainerandrole="tab"+aria-selected={activeTabId === tab.id}to eachTabButton.webapp/src/components/agents/filter_tabs.tsx#L25-L42: addrole="tablist"toTabBarandrole="tab"+aria-selected={value === 'all'/'yours'}to eachTabButton.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/config_view_shell.tsx` around lines 111 - 128, Add tab semantics to both tab strips: in webapp/src/components/agents/config_view_shell.tsx lines 111-128, give TabsContainer role="tablist" and each TabButton role="tab" with aria-selected reflecting activeTabId === tab.id; in webapp/src/components/agents/filter_tabs.tsx lines 25-42, give TabBar role="tablist" and each ownership TabButton role="tab" with aria-selected reflecting whether value is "all" or "yours".webapp/src/types/automations.ts (1)
15-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
provider_typeshould use the exported literal constants as a type, notstring.
AIProviderTypeAgent/AIProviderTypeServiceare defined butprovider_typeis typed as plainstring(comment-only documentation of the two valid values). This allows any string to type-check, defeating the purpose of the constants and the strict-typing guideline.As per coding guidelines, "keep TypeScript strictly typed" for `webapp/**/*.{ts,tsx}`.♻️ Proposed fix
export const AIProviderTypeAgent = 'agent'; export const AIProviderTypeService = 'service'; +export type AIProviderType = typeof AIProviderTypeAgent | typeof AIProviderTypeService; export type AIPromptActionParams = { system_prompt?: string; prompt: string; - provider_type: string; // "agent" | "service" + provider_type: AIProviderType; provider_id: string; allowed_tools?: string[]; guardrails?: Guardrails; request_as?: AIPromptRequestAs; };Also applies to: 69-77
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/types/automations.ts` around lines 15 - 16, Update the automation type containing provider_type to use the literal union typeof AIProviderTypeAgent | typeof AIProviderTypeService instead of string. Reuse the exported constants AIProviderTypeAgent and AIProviderTypeService so only the two supported provider values are accepted.Source: Coding guidelines
webapp/src/components/agents/agents_page.tsx (1)
42-59: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider adding tab ARIA semantics. The tab bar uses plain buttons; adding
role="tablist"on the container androle="tab"+aria-selected={$active}on eachPageTabButton(with the panel wired viarole="tabpanel"/aria-labelledby) would let assistive tech announce this as a tab set. Functionally correct as-is.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@webapp/src/components/agents/agents_page.tsx` around lines 42 - 59, Add ARIA tab semantics around the existing activeTab controls: apply role="tablist" to TabsBar, role="tab" and aria-selected based on $active to each PageTabButton, and associate the rendered tab panel with the selected tab using role="tabpanel" and aria-labelledby. Use stable IDs for the tab and panel relationships while preserving the existing click and active-state behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@webapp/src/client.tsx`:
- Around line 1160-1181: The createAutomation function generates IDs using only
Date.now(), allowing same-millisecond collisions. Update the ID generation in
createAutomation to append a unique per-creation value while preserving the
mock- identifier format, so mockAutomations entries remain distinct for React
keys and updateAutomation/deleteAutomation lookups.
In `@webapp/src/components/agents/automation_config_view.tsx`:
- Around line 51-58: Update toUpdate and the AutomationUpdate model to include
the context selector value, and include context in isDirty comparisons so
changes are persisted and trigger the unsaved-changes prompt. Reuse the existing
context state/control value and ensure the automation model carries it through
save and load flows; do not leave the selector as local-only state.
---
Nitpick comments:
In `@webapp/src/components/agents/agent_selector.tsx`:
- Around line 25-40: The MCP/tool metadata derivation is duplicated between
formatAgentMeta and formatPickerMeta. Create a shared helper for distinct
server_origin counting and the all-tools versus pluralized tools label, then
update formatAgentMeta in webapp/src/components/agents/agent_selector.tsx:25-40
and formatPickerMeta in
webapp/src/components/agents/new_automation_agent_menu.tsx:24-46 to use it while
preserving their different separators and channel labels.
In `@webapp/src/components/agents/agents_page.tsx`:
- Around line 42-59: Add ARIA tab semantics around the existing activeTab
controls: apply role="tablist" to TabsBar, role="tab" and aria-selected based on
$active to each PageTabButton, and associate the rendered tab panel with the
selected tab using role="tabpanel" and aria-labelledby. Use stable IDs for the
tab and panel relationships while preserving the existing click and active-state
behavior.
In `@webapp/src/components/agents/automations_list.tsx`:
- Around line 86-95: In the automation action configuration, update the
provider_type value within the run-agent action to use the exported
AIProviderTypeAgent constant from `@/types/automations` instead of the literal
'agent'. Preserve the surrounding action and prompt configuration.
- Around line 137-171: Update the profile-fetching useEffect and its surrounding
state in automations_list.tsx to track creator IDs already attempted, using a
stable attempted-ID set/ref so unresolved IDs are not fetched again after
unrelated automations or profiles changes. Build missingIds by excluding both
cached profiles and attempted IDs, mark IDs as attempted before calling
getProfilesByIds, and preserve the existing cancellation and RECEIVED_PROFILES
dispatch behavior.
In `@webapp/src/components/agents/config_view_shell.tsx`:
- Around line 111-128: Add tab semantics to both tab strips: in
webapp/src/components/agents/config_view_shell.tsx lines 111-128, give
TabsContainer role="tablist" and each TabButton role="tab" with aria-selected
reflecting activeTabId === tab.id; in
webapp/src/components/agents/filter_tabs.tsx lines 25-42, give TabBar
role="tablist" and each ownership TabButton role="tab" with aria-selected
reflecting whether value is "all" or "yours".
In `@webapp/src/components/agents/new_automation_agent_menu.tsx`:
- Around line 214-216: Update the agent display logic surrounding the fallback
return in the new automation agent menu to use the agent’s real description
field instead of custom instructions. If the description field is not yet
available, confirm and implement the intended replacement fallback before
merging, and remove the temporary TODO.
- Around line 156-198: The dropdown in the open state has an invalid listbox
structure and lacks Escape handling. Update the JSX around Dropdown and
OptionsList so the listbox role applies only to the agent options (or implement
the equivalent combobox with an owned listbox), keeping the header and
SearchInput outside that role; add keyboard handling tied to the existing
open/close state so pressing Escape closes the dropdown and preserves the
current focus behavior.
In `@webapp/src/components/agents/row_actions_menu.tsx`:
- Around line 29-42: The open-menu effect in the row actions component only
handles outside mousedown events. Add a keydown listener while open that calls
updateOpen(false) when the Escape key is pressed, and remove that listener
during cleanup alongside the existing mousedown listener.
In `@webapp/src/types/automations.ts`:
- Around line 15-16: Update the automation type containing provider_type to use
the literal union typeof AIProviderTypeAgent | typeof AIProviderTypeService
instead of string. Reuse the exported constants AIProviderTypeAgent and
AIProviderTypeService so only the two supported provider values are accepted.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: ad7e41a7-8e11-41d7-9fe8-86a7b68aac88
📒 Files selected for processing (18)
webapp/src/client.tsxwebapp/src/components/agents/agent_config_view.tsxwebapp/src/components/agents/agent_row.tsxwebapp/src/components/agents/agent_selector.tsxwebapp/src/components/agents/agents_list.tsxwebapp/src/components/agents/agents_page.tsxwebapp/src/components/agents/automation_config_view.tsxwebapp/src/components/agents/automation_row.tsxwebapp/src/components/agents/automations_list.tsxwebapp/src/components/agents/avatar.tsxwebapp/src/components/agents/config_view_shell.tsxwebapp/src/components/agents/filter_tabs.tsxwebapp/src/components/agents/new_automation_agent_menu.tsxwebapp/src/components/agents/row_actions_menu.tsxwebapp/src/components/agents/trigger_selector.tsxwebapp/src/components/select.tsxwebapp/src/i18n/en.jsonwebapp/src/types/automations.ts
| export async function createAutomation(data: AutomationUpdate): Promise<Automation> { | ||
| const now = Date.now(); | ||
| let createdBy = ''; | ||
| try { | ||
| const me = await Client4.getMe(); | ||
| createdBy = me.id; | ||
| } catch { | ||
| createdBy = ''; | ||
| } | ||
| const created: Automation = { | ||
| id: `mock-${now}`, | ||
| name: data.name, | ||
| enabled: data.enabled ?? true, | ||
| trigger: data.trigger, | ||
| actions: data.actions, | ||
| created_at: now, | ||
| updated_at: now, | ||
| created_by: createdBy, | ||
| }; | ||
| mockAutomations = [...mockAutomations, created]; | ||
| return cloneAutomation(created); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Generated automation id can collide. mock-${now} uses only Date.now(), so two automations created within the same millisecond share an id. Downstream this breaks React key uniqueness in the list and causes updateAutomation/deleteAutomation (which match by id) to hit the wrong record.
Proposed fix
- const created: Automation = {
- id: `mock-${now}`,
+ const created: Automation = {
+ id: `mock-${now}-${Math.random().toString(36).slice(2, 8)}`,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export async function createAutomation(data: AutomationUpdate): Promise<Automation> { | |
| const now = Date.now(); | |
| let createdBy = ''; | |
| try { | |
| const me = await Client4.getMe(); | |
| createdBy = me.id; | |
| } catch { | |
| createdBy = ''; | |
| } | |
| const created: Automation = { | |
| id: `mock-${now}`, | |
| name: data.name, | |
| enabled: data.enabled ?? true, | |
| trigger: data.trigger, | |
| actions: data.actions, | |
| created_at: now, | |
| updated_at: now, | |
| created_by: createdBy, | |
| }; | |
| mockAutomations = [...mockAutomations, created]; | |
| return cloneAutomation(created); | |
| } | |
| export async function createAutomation(data: AutomationUpdate): Promise<Automation> { | |
| const now = Date.now(); | |
| let createdBy = ''; | |
| try { | |
| const me = await Client4.getMe(); | |
| createdBy = me.id; | |
| } catch { | |
| createdBy = ''; | |
| } | |
| const created: Automation = { | |
| id: `mock-${now}-${Math.random().toString(36).slice(2, 8)}`, | |
| name: data.name, | |
| enabled: data.enabled ?? true, | |
| trigger: data.trigger, | |
| actions: data.actions, | |
| created_at: now, | |
| updated_at: now, | |
| created_by: createdBy, | |
| }; | |
| mockAutomations = [...mockAutomations, created]; | |
| return cloneAutomation(created); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webapp/src/client.tsx` around lines 1160 - 1181, The createAutomation
function generates IDs using only Date.now(), allowing same-millisecond
collisions. Update the ID generation in createAutomation to append a unique
per-creation value while preserving the mock- identifier format, so
mockAutomations entries remain distinct for React keys and
updateAutomation/deleteAutomation lookups.
| function toUpdate(automation: Automation): AutomationUpdate { | ||
| return { | ||
| name: automation.name, | ||
| enabled: automation.enabled, | ||
| trigger: automation.trigger, | ||
| actions: automation.actions, | ||
| }; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
rg -n "context" webapp/src/types/automations.ts webapp/src/client.tsxRepository: mattermost/mattermost-plugin-agents
Length of output: 273
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- automation_config_view.tsx (outline) ---'
ast-grep outline webapp/src/components/agents/automation_config_view.tsx --view expanded || true
echo
echo '--- automations types (outline) ---'
ast-grep outline webapp/src/types/automations.ts --view expanded || true
echo
echo '--- search AutomationUpdate / selectedContext / contextOptions ---'
rg -n "AutomationUpdate|selectedContext|contextOptions|isDirty|toUpdate\\(" webapp/src/components/agents/automation_config_view.tsx webapp/src/types/automations.ts webapp/src -g '!**/*.map'Repository: mattermost/mattermost-plugin-agents
Length of output: 6959
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,260p' webapp/src/components/agents/automation_config_view.tsx | nl -ba | sed -n '1,260p'
echo '---'
sed -n '1,260p' webapp/src/types/automations.ts | nl -ba | sed -n '1,260p'Repository: mattermost/mattermost-plugin-agents
Length of output: 213
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- webapp/src/types/automations.ts ---'
sed -n '1,180p' webapp/src/types/automations.ts
echo
echo '--- webapp/src/components/agents/automation_config_view.tsx (relevant ranges) ---'
sed -n '1,260p' webapp/src/components/agents/automation_config_view.tsx
echo '---'
sed -n '260,450p' webapp/src/components/agents/automation_config_view.tsx
echo
echo '--- save path usages ---'
sed -n '1140,1205p' webapp/src/client.tsxRepository: mattermost/mattermost-plugin-agents
Length of output: 21809
Persist the context selector
context is still local-only state: toUpdate() and AutomationUpdate omit it, and isDirty compares only the automation payload. Changing “Where the automation can read from” can be saved without affecting the stored automation, and it won’t trigger the unsaved-changes prompt when it’s the only edit.
Wire context through the automation model, or remove this control until it’s backed by persisted state.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@webapp/src/components/agents/automation_config_view.tsx` around lines 51 -
58, Update toUpdate and the AutomationUpdate model to include the context
selector value, and include context in isDirty comparisons so changes are
persisted and trigger the unsaved-changes prompt. Reuse the existing context
state/control value and ensure the automation model carries it through save and
load flows; do not leave the selector as local-only state.
Summary
Draft for the implementation of automations frontend.
Ticket Link
NONE
Screenshots
TBD
Release Note
TBD
Summary by CodeRabbit
New Features
Improvements