PluginProbe
Extendify / 3.0.4
Extendify v3.0.4
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 / api.js

api.js in Extendify 3.0.4, at src/Agent/api.js

174 lines 4.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { useChatStore } from '@agent/state/chat';
2 import { useGlobalStore } from '@agent/state/global';
3 import { useWorkflowStore } from '@agent/state/workflows';
4 import { tools } from '@agent/workflows/workflows';
5 import { AI_HOST } from '@constants';
6 import { reqDataBasics } from '@shared/lib/data';
7
8 const extra = () => {
9 const { x, y, width, height } = useGlobalStore.getState();
10 return {
11 userAgent: window?.navigator?.userAgent,
12 vendor: window?.navigator?.vendor || 'unknown',
13 platform:
14 window?.navigator?.userAgentData?.platform ||
15 window?.navigator?.platform ||
16 'unknown',
17 mobile: window?.navigator?.userAgentData?.mobile,
18 width: window.innerWidth,
19 height: window.innerHeight,
20 screenHeight: window.screen.height,
21 screenWidth: window.screen.width,
22 orientation: window.screen.orientation?.type,
23 touchSupport: 'ontouchstart' in window || navigator.maxTouchPoints > 0,
24 agentUI: { x, y, width, height },
25 };
26 };
27
28 export const pickWorkflow = async ({ workflows, options }) => {
29 const { failedWorkflows, context } = window.extAgentData;
30 const failed = failedWorkflows ?? new Set();
31 const filteredWorkflows = workflows.filter((wf) => !failed.has(wf.id));
32
33 const { workflowHistory: pastWorkflows, block } = useWorkflowStore.getState();
34
35 const messages = useChatStore.getState().getMessagesForAI();
36 const lastAssistantMessage = useChatStore
37 .getState()
38 .getLastAssistantMessage();
39
40 const response = await fetch(`${AI_HOST}/api/agent/find-agent`, {
41 method: 'POST',
42 headers: { 'Content-Type': 'application/json' },
43 signal: options?.signal,
44 body: JSON.stringify({
45 ...reqDataBasics,
46 workflows: filteredWorkflows,
47 previousAgentName: pastWorkflows.at(0)?.agentName,
48 previousWorkflow: {
49 lastMessage: lastAssistantMessage?.details?.content,
50 sessionId: lastAssistantMessage?.details?.sessionId,
51 ...pastWorkflows?.at(0),
52 },
53 context,
54 agentContext: window.extAgentData.agentContext,
55 messages: messages.slice(-5),
56 hasBlock: Boolean(block), // todo: remove this
57 blockDetails: block,
58 ...options,
59 extra: extra(),
60 }),
61 });
62
63 if (!response.ok) {
64 digest({
65 caller: 'pick-workflow',
66 error: {
67 name: response.statusText,
68 messages: response.statusMessage,
69 },
70 });
71 const error = new Error('Bad response from server');
72 error.response = response;
73 throw error;
74 }
75 return await response.json();
76 };
77
78 export const handleWorkflow = async ({ workflow, workflowData, options }) => {
79 const messages = useChatStore.getState().getMessagesForAI();
80 const response = await fetch(`${AI_HOST}/api/agent/handle-workflow`, {
81 method: 'POST',
82 headers: { 'Content-Type': 'application/json' },
83 signal: options?.signal,
84 body: JSON.stringify({
85 ...reqDataBasics,
86 workflow,
87 workflowData,
88 messages: messages,
89 context: window.extAgentData.context,
90 agentContext: window.extAgentData.agentContext,
91 retry: options?.retry || false,
92 extra: extra(),
93 }),
94 });
95
96 if (!response.ok) throw new Error('Bad response from server');
97 return await response.json();
98 };
99
100 export const rateAnswer = ({ answerId, rating }) =>
101 fetch(`${AI_HOST}/api/agent/rate-workflow`, {
102 method: 'POST',
103 headers: { 'Content-Type': 'application/json' },
104 body: JSON.stringify({ answerId, rating }),
105 }).catch((error) =>
106 digest({
107 caller: 'rateAnswer',
108 error,
109 extra: { answerId, rating },
110 }),
111 );
112
113 export const callTool = async ({ tool, inputs }) => {
114 if (!tools[tool]) throw new Error(`Tool ${tool} not found`);
115 return await tools[tool](inputs);
116 };
117
118 export const digest = ({ error, sessionId, caller, additional = {} }) => {
119 if (Boolean(reqDataBasics?.devbuild) === true) return;
120
121 const errorMessage = () => {
122 if (error.response?.statusText) {
123 return (
124 error.response?.statusText || error.response.message || 'Unknown error'
125 );
126 }
127 return typeof error === 'string'
128 ? error
129 : error?.message || 'Unknown error';
130 };
131
132 const errorData = {
133 message: errorMessage(),
134 name: error?.name,
135 };
136
137 return fetch(`${AI_HOST}/api/agent/digest`, {
138 method: 'POST',
139 keepalive: true,
140 headers: { 'Content-Type': 'application/json' },
141 body: JSON.stringify({
142 ...reqDataBasics,
143 phpVersion: window.extSharedData?.phpVersion,
144 sessionId,
145 error: errorData,
146 browser: {
147 userAgent: window.navigator?.userAgent,
148 vendor: window.navigator?.vendor,
149 platform: window.navigator?.platform,
150 width: window.innerWidth,
151 height: window.innerHeight,
152 touchSupport: 'ontouchstart' in window || navigator.maxTouchPoints > 0,
153 },
154 caller,
155 ...additional,
156 extra: extra(),
157 }),
158 }).catch(() => {});
159 };
160
161 export const recordAgentActivity = ({ action, sessionId, value = {} }) => {
162 return fetch(`${AI_HOST}/api/agent/activities`, {
163 keepalive: true,
164 method: 'POST',
165 headers: { 'Content-Type': 'application/json' },
166 body: JSON.stringify({
167 ...reqDataBasics,
168 action,
169 sessionId,
170 value,
171 }),
172 });
173 };
174