PluginProbe
Extendify / 3.0.5
Extendify v3.0.5
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 / chat.js

chat.js in Extendify 3.0.5, at src/Agent/state/chat.js

94 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { isChangeSiteDesignWorkflowAvailable, makeId } from '@agent/lib/util';
2 import apiFetch from '@wordpress/api-fetch';
3 import { __ } from '@wordpress/i18n';
4 import { create } from 'zustand';
5 import { createJSONStorage, devtools, persist } from 'zustand/middleware';
6
7 const { chatHistory } = window.extAgentData;
8
9 const welcomeMessage = [
10 {
11 id: 1,
12 type: 'message',
13 details: {
14 role: 'assistant',
15 // translators: this is the initial message in the agent chat, welcoming the user. Keep it short and friendly and follow the same markdown format and emoji.
16 content: isChangeSiteDesignWorkflowAvailable()
17 ? __(
18 '#### Your site is ready 🎉\nWant to explore other website designs?',
19 'extendify-local',
20 )
21 : __(
22 '#### Your site is ready 🎉\nWant to explore other site colors?',
23 'extendify-local',
24 ),
25 },
26 },
27 ];
28 const state = (set, get) => ({
29 messages: chatHistory?.length ? chatHistory.toReversed() : welcomeMessage,
30 // Messages sent to the api, user and assistant only. Up until the last workflow
31 getMessagesForAI: () => {
32 const messages = [];
33 let foundUserMessage = false;
34 for (const { type, details } of get().messages.toReversed()) {
35 const finished =
36 ['completed', 'canceled'].includes(details.status) ||
37 (['status'].includes(type) && details.type === 'workflow-canceled');
38 if (type === 'workflow' && finished) break;
39 if (type === 'workflow-component' && finished) break;
40 // This prevents a loop of assistant messages from being at the end
41 if (type === 'message' && details.role === 'user') {
42 foundUserMessage = true;
43 }
44 if (type === 'message' && !foundUserMessage) continue;
45 if (type === 'message') messages.push(details);
46 }
47 return messages.toReversed();
48 },
49 getLastAssistantMessage: () =>
50 get()?.messages?.findLast(
51 (message) =>
52 message.type === 'message' && message.details?.role === 'assistant',
53 ),
54 hasMessages: () => get().messages.length > 0,
55 addMessage: (type, details) => {
56 const id = makeId();
57 set((state) => {
58 // max 150 messages
59 const max = Math.max(0, state.messages.length - 149);
60 const next = { id, type, details };
61 return {
62 // { id: 1, type: message, details: { role: 'user', content: 'Hello' } }
63 // { id: 2, type: message, details: { role: 'assistant', content: 'Hi there!' } }
64 // { id: 3, type: workflow, details: { name: 'Workflow 1' } }
65 // { id: 5, type: status, details: { type: 'calling-agent' }
66 messages: [...state.messages.toSpliced(0, max), next],
67 };
68 });
69 return id;
70 },
71 // pop messages all the way back to the last agent message
72 popMessage: () => {
73 set((state) => ({
74 messages: state.messages?.slice(0, -1) || [],
75 }));
76 },
77 clearMessages: () => set({ messages: [] }),
78 });
79
80 const path = '/extendify/v1/agent/chat-events';
81 const storage = {
82 getItem: async () => await apiFetch({ path }),
83 setItem: async (_name, state) =>
84 await apiFetch({ path, method: 'POST', data: { state } }),
85 };
86
87 export const useChatStore = create()(
88 persist(devtools(state, { name: 'Extendify Agent Chat' }), {
89 name: `extendify-agent-chat-${window.extSharedData.siteId}`,
90 storage: createJSONStorage(() => storage),
91 skipHydration: true,
92 }),
93 );
94