PluginProbe
Extendify / 3.1.3
Extendify v3.1.3
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Agent / state / workflows.js

workflows.js in Extendify 3.1.3, at src/Agent/state/workflows.js

119 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { isAbilityWorkflow } from '@agent/lib/abilities';
2 import { isChangeSiteDesignWorkflowAvailable } from '@agent/lib/util';
3 import { AbilityRunGate } from '@agent/workflows/abilities/components/AbilityRunGate';
4 import changeSiteDesignWorkflow from '@agent/workflows/theme/change-site-design';
5 import variationsWorkflow from '@agent/workflows/theme/change-theme-variation';
6 import { workflows } from '@agent/workflows/workflows';
7 import { useQuickEditStore } from '@quick-edit/state/store';
8 import { deepMerge } from '@shared/lib/utils';
9 import { create } from 'zustand';
10 import { devtools, persist } from 'zustand/middleware';
11
12 const onboarding = window.extAgentData.chatHistory?.length === 0;
13 const agentResponse = isChangeSiteDesignWorkflowAvailable()
14 ? changeSiteDesignWorkflow.example?.agentResponse
15 : variationsWorkflow.example?.agentResponse;
16 const onboardingToolProps = {
17 ...agentResponse.whenFinishedTool,
18 agentResponse,
19 };
20
21 // Used to check case-insensitive matches for workflow examples
22 const collator = new Intl.Collator(undefined, {
23 sensitivity: 'base',
24 usage: 'search',
25 });
26
27 const state = (set, get) => ({
28 workflow: null,
29 // Data for the tool component that shows up at the end of a workflow
30 whenFinishedToolProps: null,
31 getWorkflow: () => {
32 const curr = get().workflow;
33 // Workflows may define a "parent" workflow via templateId
34 const currId = curr?.templateId || curr?.id;
35 const wf = workflows.find(({ id }) => id === currId);
36 if (!wf?.id) {
37 if (!curr) return null;
38 // Ability workflows are shaped per request, so they carry no static
39 // whenFinished component; give them the generic run gate.
40 return isAbilityWorkflow(curr.id)
41 ? { ...curr, whenFinished: { component: AbilityRunGate } }
42 : curr;
43 }
44 return { ...deepMerge(curr, wf || {}), id: curr?.id };
45 },
46 getWorkflowByExample: (example) => {
47 const wf = workflows.find(
48 ({ example: ex }) => collator.compare(ex?.text, example) === 0,
49 );
50 if (!wf?.id) return null;
51 return wf;
52 },
53 // Gets the workflows available to the user
54 // TODO: maybe we need to have a way to include a
55 // workflow regardless of the block being active?
56 getAvailableWorkflows: () => {
57 const wfs = workflows.filter(({ available }) => available());
58 // If a block is set, only include those with 'block'
59 const blockWorkflows = wfs.filter(({ requires }) =>
60 requires?.includes('block'),
61 );
62 if (useQuickEditStore.getState().agentBlock) return blockWorkflows;
63 // otherwise remove all of the above
64 return wfs.filter(({ id }) => !blockWorkflows.some((w) => w.id === id));
65 },
66 getWorkflowsByFeature: ({ requires } = {}) => {
67 if (!requires) return workflows.filter(({ available }) => available());
68 // e.g. requires: ['block']
69 return workflows.filter(
70 ({ available, requires: workflowRequires }) =>
71 available() &&
72 (!requires || workflowRequires?.some((s) => requires.includes(s))),
73 );
74 },
75 workflowData: null,
76 mergeWorkflowData: (data) => {
77 set((state) => {
78 if (!state.workflowData) return { workflowData: data };
79 return {
80 workflowData: { ...state.workflowData, ...data },
81 };
82 });
83 },
84 setWorkflow: (workflow) => {
85 const agentBlockCode = useQuickEditStore.getState().agentBlockCode;
86 set({
87 workflow: workflow
88 ? { ...workflow, startingPage: window.location.href }
89 : null,
90 // If a block is selected, add it to the workflow data
91 // previousContent is named this way for legacy reasons
92 workflowData: agentBlockCode ? { previousContent: agentBlockCode } : null,
93 whenFinishedToolProps: null,
94 });
95 },
96 setWhenFinishedToolProps: (whenFinishedToolProps) =>
97 set({ whenFinishedToolProps }),
98 });
99
100 export const useWorkflowStore = create()(
101 persist(devtools(state, { name: 'Extendify Agent Workflows' }), {
102 name: `extendify-agent-workflows-${window.extSharedData.siteId}`,
103 merge: (persistedState, currentState) => {
104 // if we are in onboarding mode, add the starting workflow
105 if (onboarding) {
106 return {
107 ...currentState,
108 ...persistedState,
109 workflow: isChangeSiteDesignWorkflowAvailable()
110 ? changeSiteDesignWorkflow
111 : variationsWorkflow,
112 whenFinishedToolProps: onboardingToolProps,
113 };
114 }
115 return { ...currentState, ...persistedState };
116 },
117 }),
118 );
119