@burdenoff/fluidgrids-fe-sdk 2026.1109.1 → 2026.1109.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +26 -0
  2. package/dist/{ExecutionDetailPage-NZSHNEZZ.js → ExecutionDetailPage-IGDA3C36.js} +13 -13
  3. package/dist/{ExecutionsListPage-4VWCCOH6.js → ExecutionsListPage-BY7HA64B.js} +10 -10
  4. package/dist/{TemplateDetailPanel-5WY75DVB.js → TemplateDetailPanel-AIMUAFCB.js} +1 -1
  5. package/dist/{WorkflowBuilder-XJED5JFG.js → WorkflowBuilder-VKOPUT3O.js} +12 -12
  6. package/dist/{WorkflowsList-5F7GNYBN.js → WorkflowsList-HB5FN5YQ.js} +9 -9
  7. package/dist/{agentTools-73I63CED.js → agentTools-GRPT3OXR.js} +4 -4
  8. package/dist/{chunk-HBMU63XF.js → chunk-3CAYQ57D.js} +1 -1
  9. package/dist/{chunk-ACNJS4OL.js → chunk-5YLS3WH5.js} +1 -1
  10. package/dist/{chunk-4I7DGU7J.js → chunk-6CIPJJTP.js} +4 -4
  11. package/dist/{chunk-5RFTTNIN.js → chunk-6YEJN4S2.js} +5 -5
  12. package/dist/{chunk-MI4XR2FB.js → chunk-C5C7ONWO.js} +3 -3
  13. package/dist/{chunk-D6NTP4FK.js → chunk-DFFQYK2X.js} +1 -1
  14. package/dist/{chunk-BR7MKKPP.js → chunk-EGCUHKON.js} +4 -4
  15. package/dist/{chunk-AR22A74Y.js → chunk-ERT444RG.js} +1 -0
  16. package/dist/{chunk-7ZPDLWYR.js → chunk-FHMMAGOG.js} +7 -7
  17. package/dist/{chunk-5IPDTB6T.js → chunk-IU52TFZA.js} +1 -1
  18. package/dist/{chunk-V4PXEJLI.js → chunk-IZSWG5G3.js} +1 -1
  19. package/dist/{chunk-RIJ7IB5D.js → chunk-JFUQH6HV.js} +2 -2
  20. package/dist/{chunk-V3HRW36F.js → chunk-M2ELYF52.js} +1 -1
  21. package/dist/{chunk-IOW5LL6I.js → chunk-MUIVZFIU.js} +2 -2
  22. package/dist/{chunk-TJKT64AI.js → chunk-MYE6CMGK.js} +3 -3
  23. package/dist/{chunk-M2MTUG6O.js → chunk-ODXI4P3V.js} +11 -11
  24. package/dist/{chunk-6BO4LPNT.js → chunk-OJPRKEP4.js} +2 -2
  25. package/dist/{chunk-W5UXYPBV.js → chunk-POCNG3PM.js} +476 -1
  26. package/dist/{chunk-I567MFKA.js → chunk-Q526TUOC.js} +1 -1
  27. package/dist/{chunk-3STFYDFC.js → chunk-U6VWCHYM.js} +12 -12
  28. package/dist/{chunk-SFMPBZGO.js → chunk-UKOXHS4T.js} +2 -2
  29. package/dist/{chunk-QXCLFJ5J.js → chunk-URLZGUSW.js} +5 -5
  30. package/dist/{chunk-BV6GWPSH.js → chunk-V3R4HTLC.js} +2 -2
  31. package/dist/{chunk-ZGUW4GHR.js → chunk-VAWYR6P4.js} +3 -1
  32. package/dist/{chunk-F4NVFLG7.js → chunk-VNXGRNDK.js} +2 -2
  33. package/dist/{chunk-DJUIJ3W4.js → chunk-VPFEBZOB.js} +1 -1
  34. package/dist/{chunk-43P7AHQU.js → chunk-XO5ND2HT.js} +531 -9
  35. package/dist/{chunk-V7MQXTHD.js → chunk-XSUFTJCE.js} +2 -2
  36. package/dist/{chunk-R6GXIC2D.js → chunk-ZE7AHJWF.js} +5 -5
  37. package/dist/{chunk-3RZYBITM.js → chunk-ZMEBM2GZ.js} +7 -7
  38. package/dist/executions.js +14 -14
  39. package/dist/history.js +6 -6
  40. package/dist/index.d.ts +3270 -5
  41. package/dist/index.js +44 -44
  42. package/dist/{node-detail-view-AI4TF2YS.js → node-detail-view-EQVKHAIS.js} +9 -9
  43. package/dist/nodes.js +2 -2
  44. package/dist/observability.js +7 -7
  45. package/dist/{quick-config-panel-FTFAQCMV.js → quick-config-panel-N354ZISU.js} +7 -7
  46. package/dist/settings.d.ts +19 -1
  47. package/dist/settings.js +8 -8
  48. package/dist/templates.js +11 -11
  49. package/dist/workflow-builder.js +13 -13
  50. package/dist/workflows-list.js +9 -9
  51. package/package.json +2 -2
@@ -1,28 +1,505 @@
1
- import { AgentsTab } from './chunk-V3HRW36F.js';
1
+ import { AgentsTab } from './chunk-M2ELYF52.js';
2
2
  import { ActionPoliciesTab, checkCodecServerUrl } from './chunk-OJHBCOBA.js';
3
- import { useResource, fetchPauseRules, FieldError, fetchSearchAttributes, StatusPill, NativeSelect, fetchArchiveSettings, fetchCodecServerSettings, deletePauseRule, createPauseRule, deleteSearchAttribute, createSearchAttribute, saveArchiveSettings, clearArchiveSettings, saveCodecServerSettings } from './chunk-ACNJS4OL.js';
4
- import { LogStreamingTab } from './chunk-HBMU63XF.js';
3
+ import { useResource, fetchPauseRules, FieldError, fetchSearchAttributes, StatusPill, NativeSelect, fetchArchiveSettings, fetchCodecServerSettings, deletePauseRule, createPauseRule, deleteSearchAttribute, createSearchAttribute, saveArchiveSettings, clearArchiveSettings, saveCodecServerSettings } from './chunk-5YLS3WH5.js';
4
+ import { LogStreamingTab } from './chunk-3CAYQ57D.js';
5
5
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
6
- import { useFluidGridsFlag, FLUIDGRIDS_FLAGS, usePhaseCFlags, useSaveStatusStore, findSaveConflict, useDurableParityEnabled, useConnections } from './chunk-V7MQXTHD.js';
7
- import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-AR22A74Y.js';
6
+ import { useFluidGridsFlag, FLUIDGRIDS_FLAGS, usePhaseCFlags, useSaveStatusStore, findSaveConflict, useDurableParityEnabled, useConnections } from './chunk-XSUFTJCE.js';
7
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-ERT444RG.js';
8
8
  import { useFlowStore } from './chunk-X3F5IQBP.js';
9
9
  import { getGlobalStoreClient } from './chunk-TYI2XOSI.js';
10
- import { useWorkflowDefinitionQuery, useUpdateWorkflowDefinitionMutation, useWorkflowDefinitionsQuery, DurableHistoryCapsDocument, UpdateDurableHistoryCapsDocument } from './chunk-ZGUW4GHR.js';
10
+ import { useWorkflowDefinitionQuery, useUpdateWorkflowDefinitionMutation, useWorkflowDefinitionsQuery, ManagedAiWorkspacePolicyDocument, UpdateManagedAiWorkspacePolicyDocument, DurableHistoryCapsDocument, UpdateDurableHistoryCapsDocument } from './chunk-VAWYR6P4.js';
11
11
  import { useTr } from './chunk-UULVIT25.js';
12
12
  import { getFluidGridsClient } from './chunk-PDODDDHY.js';
13
13
  import { throwIfResultError, describeOperationError } from './chunk-JKLZ6YZ3.js';
14
14
  import { getFluidGridsConfig } from './chunk-UEG2WC3G.js';
15
- import { useState, useMemo, useEffect, useCallback } from 'react';
15
+ import { createContext, useState, useMemo, useEffect, useCallback, useContext, useRef, useLayoutEffect } from 'react';
16
16
  import { useNavigate, useParams } from 'react-router';
17
17
  import { Icon } from '@iconify/react';
18
18
  import { Button } from '@burdenoff/fe-libs/button';
19
19
  import { Tabs, TabsList, TabsTrigger, TabsContent, Input, Switch, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Label, Card as Card$1, CardHeader, Badge, Checkbox, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '@burdenoff/fe-libs/ui';
20
20
  import { toast } from 'sonner';
21
+ import { print } from 'graphql';
22
+ import { getStoredProjectId, getStoredOrganizationId, graphqlFetchPinned, prepareWorkspaceRequest, clearGraphqlFetchResponseCache, getWorkspaceTokenPayload, isWorkspaceTokenValidForContext } from '@burdenoff/fe-libs/shared';
21
23
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
22
24
  import { gql } from '@apollo/client';
23
25
  import { resolveExternalGatewayUrls } from '@burdenoff/fe-libs/shared/config';
24
26
  import { cn } from '@burdenoff/fe-libs/utils';
25
27
 
28
+ var ManagedAiAuthorityContext = createContext(null);
29
+ function useManagedAiPolicyAuthority() {
30
+ return useContext(ManagedAiAuthorityContext);
31
+ }
32
+ var canonical = {
33
+ prepare: prepareWorkspaceRequest,
34
+ send: graphqlFetchPinned,
35
+ organizationId: getStoredOrganizationId,
36
+ projectId: getStoredProjectId
37
+ };
38
+ var ManagedAiWorkspaceWideRequired = class extends Error {
39
+ constructor() {
40
+ super("Managed AI workspace authority requires workspace-wide context.");
41
+ }
42
+ };
43
+ function sameScope(a, b) {
44
+ return b !== null && a.authority === b.authority && a.url === b.url && a.actorId === b.actorId && a.workspaceId === b.workspaceId && a.organizationId === b.organizationId && a.tenantId === b.tenantId && a.projectId === b.projectId && a.authToken === b.authToken && a.workspaceToken === b.workspaceToken;
45
+ }
46
+ function createManagedAiRequest(captured, current, dependencies = canonical) {
47
+ const scope = Object.freeze({ ...captured });
48
+ const assertScope = (signal) => {
49
+ if (signal.aborted) {
50
+ throw new DOMException("The operation was aborted.", "AbortError");
51
+ }
52
+ if (!sameScope(scope, current()) || !scope.authToken || !scope.actorId || !scope.workspaceId || !scope.organizationId || !scope.tenantId) {
53
+ throw new Error(
54
+ "Managed AI authority changed. Reload before continuing."
55
+ );
56
+ }
57
+ };
58
+ return async function request(query, variables, signal) {
59
+ assertScope(signal);
60
+ if (scope.projectId) throw new ManagedAiWorkspaceWideRequired();
61
+ let workspaceToken;
62
+ let assertWorkspace;
63
+ const assertCapturedToken = (value) => {
64
+ const payload = getWorkspaceTokenPayload(value, {
65
+ validateTenantClaim: true
66
+ });
67
+ if (payload?.projectId) throw new ManagedAiWorkspaceWideRequired();
68
+ if (payload?.sub !== scope.actorId || !isWorkspaceTokenValidForContext(
69
+ value,
70
+ {
71
+ workspaceId: scope.workspaceId,
72
+ organizationId: scope.organizationId,
73
+ tenantId: scope.tenantId,
74
+ workspaceWide: true
75
+ },
76
+ 3e4
77
+ ))
78
+ throw new Error(
79
+ "Managed AI workspace authority is unavailable. Reload before continuing."
80
+ );
81
+ };
82
+ if (scope.authority === "profile") {
83
+ if (dependencies.organizationId() !== scope.organizationId)
84
+ throw new Error(
85
+ "Managed AI authority changed. Reload before continuing."
86
+ );
87
+ if (dependencies.projectId()) throw new ManagedAiWorkspaceWideRequired();
88
+ const prepared = await dependencies.prepare({
89
+ url: scope.url,
90
+ authToken: scope.authToken,
91
+ actorId: scope.actorId,
92
+ workspaceId: scope.workspaceId,
93
+ tenantId: scope.tenantId,
94
+ workspaceToken: scope.workspaceToken,
95
+ currentQuery: query,
96
+ signal
97
+ });
98
+ workspaceToken = prepared.workspaceToken;
99
+ assertWorkspace = () => {
100
+ prepared.assertCurrent();
101
+ assertCapturedToken(workspaceToken);
102
+ };
103
+ } else if (scope.authority === "provided") {
104
+ workspaceToken = scope.workspaceToken ?? "";
105
+ assertWorkspace = () => assertCapturedToken(workspaceToken);
106
+ } else {
107
+ throw new Error("Explicit managed AI authority is required.");
108
+ }
109
+ assertScope(signal);
110
+ assertWorkspace();
111
+ const response = await dependencies.send({
112
+ gateway: "workspace",
113
+ baseUrl: scope.url,
114
+ query,
115
+ variables,
116
+ authToken: scope.authToken,
117
+ workspaceToken,
118
+ workspaceId: scope.workspaceId,
119
+ organizationId: scope.organizationId,
120
+ tenantId: scope.tenantId,
121
+ projectId: false,
122
+ signal,
123
+ suppressGlobalErrorEvent: true,
124
+ skipAuthRetry: true
125
+ });
126
+ assertScope(signal);
127
+ assertWorkspace();
128
+ if (response.errors?.length || response.data === null || response.data === void 0) {
129
+ throw new Error("Managed AI response could not be confirmed.");
130
+ }
131
+ return response.data;
132
+ };
133
+ }
134
+
135
+ // src/modules/settings/hooks/useManagedAiWorkspacePolicy.ts
136
+ var EMPTY = {
137
+ authority: null,
138
+ policy: null,
139
+ loading: false,
140
+ error: null,
141
+ readVersion: 0,
142
+ workspaceWideRequired: false
143
+ };
144
+ function policyView(value) {
145
+ if (!value || typeof value.enforcementActive !== "boolean" || typeof value.enrollmentAvailable !== "boolean" || typeof value.enabled !== "boolean" || !Number.isSafeInteger(value.revision) || value.revision < 0 || value.enforcementActive && value.revision < 1 || typeof value.requiredConsentVersion !== "string" || !value.requiredConsentVersion || value.requiredConsentVersion.length > 128) {
146
+ throw new Error("Managed AI policy could not be confirmed.");
147
+ }
148
+ return {
149
+ enforcementActive: value.enforcementActive,
150
+ enrollmentAvailable: value.enrollmentAvailable,
151
+ enabled: value.enabled,
152
+ revision: value.revision,
153
+ requiredConsentVersion: value.requiredConsentVersion
154
+ };
155
+ }
156
+ function useManagedAiWorkspacePolicy(authority, enabled, requestFactory = createManagedAiRequest) {
157
+ const current = useRef(authority);
158
+ const pending = useRef(null);
159
+ const generation = useRef(0);
160
+ const writing = useRef(null);
161
+ const [state, setState] = useState(EMPTY);
162
+ useLayoutEffect(() => {
163
+ current.current = enabled ? authority : null;
164
+ return () => {
165
+ current.current = null;
166
+ generation.current += 1;
167
+ writing.current = null;
168
+ pending.current?.abort();
169
+ };
170
+ }, [authority, enabled]);
171
+ const request = useMemo(
172
+ () => authority ? requestFactory(authority, () => current.current) : null,
173
+ [authority, requestFactory]
174
+ );
175
+ const reload = useCallback(async () => {
176
+ if (!authority || !request || !enabled || current.current !== authority)
177
+ return;
178
+ pending.current?.abort();
179
+ const controller = new AbortController();
180
+ pending.current = controller;
181
+ const id = ++generation.current;
182
+ setState((previous) => ({
183
+ authority,
184
+ policy: null,
185
+ loading: true,
186
+ workspaceWideRequired: false,
187
+ error: null,
188
+ readVersion: previous.authority === authority ? previous.readVersion : 0
189
+ }));
190
+ clearGraphqlFetchResponseCache();
191
+ try {
192
+ const data = await request(
193
+ print(ManagedAiWorkspacePolicyDocument),
194
+ {},
195
+ controller.signal
196
+ );
197
+ const policy = policyView(data.workflowWorkspaceAiPolicy);
198
+ if (id !== generation.current || current.current !== authority || controller.signal.aborted)
199
+ return;
200
+ setState((previous) => ({
201
+ authority,
202
+ policy,
203
+ loading: false,
204
+ workspaceWideRequired: false,
205
+ error: null,
206
+ readVersion: previous.readVersion + 1
207
+ }));
208
+ } catch (error) {
209
+ if (id === generation.current && current.current === authority && !controller.signal.aborted) {
210
+ setState((previous) => ({
211
+ ...previous,
212
+ authority,
213
+ policy: null,
214
+ loading: false,
215
+ error: "Managed AI settings could not be confirmed.",
216
+ workspaceWideRequired: error instanceof ManagedAiWorkspaceWideRequired
217
+ }));
218
+ }
219
+ }
220
+ }, [authority, enabled, request]);
221
+ useEffect(() => {
222
+ void reload();
223
+ return () => {
224
+ pending.current?.abort();
225
+ };
226
+ }, [reload]);
227
+ const save = useCallback(
228
+ async (change) => {
229
+ if (writing.current !== null || !authority || !request || !enabled || current.current !== authority || state.authority !== authority || !state.policy?.enforcementActive && state.policy?.enrollmentAvailable !== true || state.loading || state.error || change.enabled && change.consentVersion !== state.policy.requiredConsentVersion || change.expectedRevision !== state.policy.revision) {
230
+ throw new Error(
231
+ "Reload the current managed AI setting before continuing."
232
+ );
233
+ }
234
+ pending.current?.abort();
235
+ const controller = new AbortController();
236
+ pending.current = controller;
237
+ const id = ++generation.current;
238
+ writing.current = id;
239
+ clearGraphqlFetchResponseCache();
240
+ try {
241
+ const data = await request(
242
+ print(UpdateManagedAiWorkspacePolicyDocument),
243
+ { input: change },
244
+ controller.signal
245
+ );
246
+ const policy = policyView(data.updateWorkflowWorkspaceAiPolicy);
247
+ if (id !== generation.current || current.current !== authority || controller.signal.aborted || !policy.enforcementActive || policy.enabled !== change.enabled || policy.revision <= change.expectedRevision)
248
+ throw new Error("Managed AI change could not be confirmed.");
249
+ setState((previous) => ({
250
+ ...previous,
251
+ authority,
252
+ policy,
253
+ loading: false,
254
+ error: null
255
+ }));
256
+ } catch (error) {
257
+ clearGraphqlFetchResponseCache();
258
+ if (id === generation.current && current.current === authority)
259
+ setState((previous) => ({
260
+ ...previous,
261
+ authority,
262
+ policy: null,
263
+ loading: false,
264
+ error: "Reload to confirm the managed AI setting.",
265
+ workspaceWideRequired: error instanceof ManagedAiWorkspaceWideRequired
266
+ }));
267
+ throw new Error("Managed AI change could not be confirmed.");
268
+ } finally {
269
+ if (writing.current === id) writing.current = null;
270
+ }
271
+ },
272
+ [authority, enabled, request, state]
273
+ );
274
+ const visible = enabled && authority !== null && state.authority === authority;
275
+ return {
276
+ policy: visible ? state.policy : null,
277
+ loading: enabled && authority !== null && (!visible || state.loading),
278
+ error: visible ? state.error : null,
279
+ readVersion: visible ? state.readVersion : 0,
280
+ workspaceWideRequired: visible && state.workspaceWideRequired,
281
+ reload,
282
+ save
283
+ };
284
+ }
285
+ function ManagedAiPolicyCard(props) {
286
+ const versionKey = JSON.stringify([
287
+ props.scopeKey,
288
+ props.readVersion,
289
+ props.policy?.revision,
290
+ props.policy?.requiredConsentVersion,
291
+ props.policy?.enabled,
292
+ props.policy?.enforcementActive,
293
+ props.policy?.enrollmentAvailable
294
+ ]);
295
+ return /* @__PURE__ */ jsx(ManagedAiPolicyForm, { ...props }, versionKey);
296
+ }
297
+ function ManagedAiPolicyForm({
298
+ policy,
299
+ loading,
300
+ error,
301
+ workspaceWideRequired,
302
+ canManage,
303
+ reload,
304
+ save
305
+ }) {
306
+ const tr = useTr();
307
+ const [acknowledged, setAcknowledged] = useState(false);
308
+ const [saving, setSaving] = useState(false);
309
+ const [saveFailed, setSaveFailed] = useState(false);
310
+ const activelyEnabled = policy?.enforcementActive === true && policy.enabled;
311
+ const change = async (enabled) => {
312
+ if (!policy || !policy.enforcementActive && policy.enrollmentAvailable !== true || !canManage || saving || saveFailed)
313
+ return;
314
+ if (enabled && !acknowledged) return;
315
+ setSaving(true);
316
+ setSaveFailed(false);
317
+ try {
318
+ await save({
319
+ enabled,
320
+ expectedRevision: policy.revision,
321
+ ...enabled ? { consentVersion: policy.requiredConsentVersion } : {}
322
+ });
323
+ setAcknowledged(false);
324
+ } catch {
325
+ setSaveFailed(true);
326
+ } finally {
327
+ setSaving(false);
328
+ }
329
+ };
330
+ return /* @__PURE__ */ jsxs(
331
+ "section",
332
+ {
333
+ className: "space-y-4 rounded-lg border border-border-default bg-background-secondary p-5",
334
+ "aria-label": tr("fluidgrids.settings.managedAi.title", "Managed AI"),
335
+ children: [
336
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-text-primary", children: tr("fluidgrids.settings.managedAi.title", "Managed AI") }),
337
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary", children: tr(
338
+ "fluidgrids.settings.managedAi.disclosure",
339
+ "Managed AI sends prompts and relevant workflow context to configured external AI providers. Turning it off stops new managed requests; requests already started may finish."
340
+ ) }),
341
+ /* @__PURE__ */ jsx(
342
+ "a",
343
+ {
344
+ href: "https://www.fluidgrids.ai/ai-terms",
345
+ target: "_blank",
346
+ rel: "noopener noreferrer",
347
+ className: "text-sm text-text-primary underline underline-offset-4",
348
+ children: tr("fluidgrids.settings.managedAi.terms", "Read AI Product Terms")
349
+ }
350
+ ),
351
+ /* @__PURE__ */ jsx(
352
+ ManagedAiPolicyStatus,
353
+ {
354
+ policy,
355
+ loading,
356
+ error,
357
+ workspaceWideRequired,
358
+ children: policy && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
359
+ ManagedAiPolicyControls,
360
+ {
361
+ policy,
362
+ canManage,
363
+ activelyEnabled,
364
+ acknowledged,
365
+ setAcknowledged,
366
+ saving,
367
+ saveFailed,
368
+ change
369
+ }
370
+ ) })
371
+ }
372
+ ),
373
+ saveFailed && /* @__PURE__ */ jsx("p", { role: "alert", children: tr(
374
+ "fluidgrids.settings.managedAi.saveFailed",
375
+ "The change could not be confirmed. Reload the current setting before trying again."
376
+ ) }),
377
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: reload, disabled: loading || saving, children: tr("fluidgrids.settings.managedAi.reload", "Reload current setting") })
378
+ ]
379
+ }
380
+ );
381
+ }
382
+ function ManagedAiPolicyControls({
383
+ policy,
384
+ canManage,
385
+ activelyEnabled,
386
+ acknowledged,
387
+ setAcknowledged,
388
+ saving,
389
+ saveFailed,
390
+ change
391
+ }) {
392
+ const tr = useTr();
393
+ return canManage ? /* @__PURE__ */ jsxs(Fragment, { children: [
394
+ !activelyEnabled && /* @__PURE__ */ jsxs("label", { className: "flex items-start gap-3 text-sm text-text-secondary", children: [
395
+ /* @__PURE__ */ jsx(
396
+ "input",
397
+ {
398
+ type: "checkbox",
399
+ checked: acknowledged,
400
+ onChange: (event) => setAcknowledged(event.target.checked),
401
+ disabled: saving || saveFailed
402
+ }
403
+ ),
404
+ tr(
405
+ "fluidgrids.settings.managedAi.acknowledge",
406
+ "I reviewed the current AI disclosure and approve managed AI requests for this workspace."
407
+ )
408
+ ] }),
409
+ /* @__PURE__ */ jsx(
410
+ Button,
411
+ {
412
+ onClick: () => void change(!activelyEnabled),
413
+ disabled: saving || saveFailed || !activelyEnabled && !acknowledged,
414
+ children: saving ? tr("fluidgrids.settings.managedAi.saving", "Saving\u2026") : activelyEnabled ? tr("fluidgrids.settings.managedAi.disable", "Turn off managed AI") : tr("fluidgrids.settings.managedAi.enable", "Enable managed AI")
415
+ }
416
+ ),
417
+ !policy.enforcementActive && policy.enrollmentAvailable === true && /* @__PURE__ */ jsx(
418
+ Button,
419
+ {
420
+ variant: "outline",
421
+ onClick: () => void change(false),
422
+ disabled: saving || saveFailed,
423
+ children: tr("fluidgrids.settings.managedAi.disable", "Turn off managed AI")
424
+ }
425
+ )
426
+ ] }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary", children: tr(
427
+ "fluidgrids.settings.managedAi.ownerOnly",
428
+ "A workspace administrator manages this setting."
429
+ ) });
430
+ }
431
+ function ManagedAiPolicyStatus({
432
+ policy,
433
+ loading,
434
+ error,
435
+ workspaceWideRequired,
436
+ children
437
+ }) {
438
+ const tr = useTr();
439
+ if (loading)
440
+ return /* @__PURE__ */ jsx("p", { role: "status", children: tr(
441
+ "fluidgrids.settings.managedAi.loading",
442
+ "Loading workspace AI settings\u2026"
443
+ ) });
444
+ if (error || !policy)
445
+ return /* @__PURE__ */ jsx("p", { role: "alert", children: workspaceWideRequired ? tr(
446
+ "fluidgrids.settings.managedAi.workspaceWideRequired",
447
+ "Select the workspace without a project, then reload its AI setting."
448
+ ) : tr(
449
+ "fluidgrids.settings.managedAi.loadFailed",
450
+ "Workspace AI settings could not be loaded. Reload before changing approval."
451
+ ) });
452
+ if (!policy.enforcementActive && policy.enrollmentAvailable !== true)
453
+ return /* @__PURE__ */ jsx("p", { role: "status", children: tr(
454
+ "fluidgrids.settings.managedAi.pending",
455
+ "Workspace AI controls are not active yet. Existing managed AI behavior is unchanged, and no approval change can be saved."
456
+ ) });
457
+ if (!policy.enforcementActive) {
458
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
459
+ /* @__PURE__ */ jsx("p", { role: "status", className: "text-sm text-text-secondary", children: tr(
460
+ "fluidgrids.settings.managedAi.enrollmentAvailable",
461
+ "Workspace AI controls are available. Existing managed AI behavior continues until an administrator saves a choice. You can turn off new managed requests without approving provider use."
462
+ ) }),
463
+ children
464
+ ] });
465
+ }
466
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
467
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-text-primary", role: "status", children: policy.enabled ? tr(
468
+ "fluidgrids.settings.managedAi.enabled",
469
+ "Managed AI is on for this workspace."
470
+ ) : tr(
471
+ "fluidgrids.settings.managedAi.disabled",
472
+ "Managed AI is off for this workspace."
473
+ ) }),
474
+ children
475
+ ] });
476
+ }
477
+ function ManagedAiSettings() {
478
+ const authority = useManagedAiPolicyAuthority();
479
+ const read = useFluidGridsPermission(FLUIDGRIDS_PERMISSIONS.WORKFLOW_READ);
480
+ const manage = useFluidGridsPermission(
481
+ FLUIDGRIDS_PERMISSIONS.SYSTEM_CONFIG_MANAGE
482
+ );
483
+ const state = useManagedAiWorkspacePolicy(authority, read.allowed);
484
+ if (!authority || !read.allowed) return null;
485
+ const scopeKey = JSON.stringify([
486
+ authority.authority,
487
+ authority.url,
488
+ authority.actorId,
489
+ authority.workspaceId,
490
+ authority.organizationId,
491
+ authority.tenantId,
492
+ authority.projectId
493
+ ]);
494
+ return /* @__PURE__ */ jsx(
495
+ ManagedAiPolicyCard,
496
+ {
497
+ ...state,
498
+ scopeKey,
499
+ canManage: manage.enforced && manage.allowed
500
+ }
501
+ );
502
+ }
26
503
  function SettingRow({
27
504
  label,
28
505
  description,
@@ -3643,7 +4120,10 @@ function SettingsPage({
3643
4120
  ]
3644
4121
  }
3645
4122
  ),
3646
- /* @__PURE__ */ jsx(TabsContent, { value: "general", children: /* @__PURE__ */ jsx(GeneralTab, {}) }),
4123
+ /* @__PURE__ */ jsxs(TabsContent, { value: "general", children: [
4124
+ /* @__PURE__ */ jsx(GeneralTab, {}),
4125
+ /* @__PURE__ */ jsx("div", { className: "mt-6", children: /* @__PURE__ */ jsx(ManagedAiSettings, {}) })
4126
+ ] }),
3647
4127
  /* @__PURE__ */ jsx(TabsContent, { value: "execution", children: /* @__PURE__ */ jsx(ExecutionTab, { workflowKey }) }),
3648
4128
  /* @__PURE__ */ jsx(TabsContent, { value: "run-data", children: /* @__PURE__ */ jsx(RunDataTab, {}) }),
3649
4129
  runControlSettings ? /* @__PURE__ */ jsx(TabsContent, { value: "run-control", children: /* @__PURE__ */ jsx(RunControlTab, { flags: phaseC }) }) : null,
@@ -3656,5 +4136,47 @@ function SettingsPage({
3656
4136
  ] })
3657
4137
  ] });
3658
4138
  }
4139
+ function ManagedAiPolicyAuthorityProvider({
4140
+ scope,
4141
+ children
4142
+ }) {
4143
+ const {
4144
+ authority,
4145
+ url,
4146
+ actorId,
4147
+ workspaceId,
4148
+ organizationId,
4149
+ tenantId,
4150
+ projectId,
4151
+ authToken,
4152
+ workspaceToken
4153
+ } = scope ?? {};
4154
+ const value = useMemo(() => {
4155
+ if (!authority || !url || !actorId || !workspaceId || !organizationId || !tenantId || !authToken)
4156
+ return null;
4157
+ return Object.freeze({
4158
+ authority,
4159
+ url,
4160
+ actorId,
4161
+ workspaceId,
4162
+ organizationId,
4163
+ tenantId,
4164
+ projectId,
4165
+ authToken,
4166
+ workspaceToken
4167
+ });
4168
+ }, [
4169
+ authority,
4170
+ url,
4171
+ actorId,
4172
+ workspaceId,
4173
+ organizationId,
4174
+ tenantId,
4175
+ projectId,
4176
+ authToken,
4177
+ workspaceToken
4178
+ ]);
4179
+ return /* @__PURE__ */ jsx(ManagedAiAuthorityContext.Provider, { value, children });
4180
+ }
3659
4181
 
3660
- export { SettingsPage };
4182
+ export { ManagedAiPolicyAuthorityProvider, SettingsPage };
@@ -1,9 +1,9 @@
1
- import { SdkPermissionGate, FLUIDGRIDS_PERMISSIONS } from './chunk-AR22A74Y.js';
1
+ import { SdkPermissionGate, FLUIDGRIDS_PERMISSIONS } from './chunk-ERT444RG.js';
2
2
  import { useBuilderReadOnly } from './chunk-SDZEAIIE.js';
3
3
  import { STICKY_NOTE_TYPE, useFlowStore, resolveOperationName, synchronizeOperationUpdate, isNodeTrigger, resolveOutputHandles, resolveInputHandles, outputHandlesSpacerHeight, WAIT_FOR_SIGNAL_NODE_TYPE, CODE_WORKFLOW_NODE_TYPE, readSignalName, LogicNodeCard, NodeCard, NodeCardHeader, NodeCardBody, InputHandles, OutputHandles, NodeTypeIcon, nodeAccent, readCodeWorkflowState, partitionStickyNotes, interfaceFields, interfaceHandlers } from './chunk-X3F5IQBP.js';
4
4
  import { getGlobalStoreClient, createGlobalStoreClient, setGlobalStoreClient, resetGlobalStoreClient } from './chunk-TYI2XOSI.js';
5
5
  import { GetMyNodeInstallationsDocument } from './chunk-G77IGC3Y.js';
6
- import { fetchAllNodeEndpointConfigs, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, ExecuteStepDocument, TriggerWorkflowDocument, RunFromNodeDocument, ExecutionDetailDocument, WorkflowDefinitionDocument, WorkflowRunDocument } from './chunk-ZGUW4GHR.js';
6
+ import { fetchAllNodeEndpointConfigs, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, ExecuteStepDocument, TriggerWorkflowDocument, RunFromNodeDocument, ExecutionDetailDocument, WorkflowDefinitionDocument, WorkflowRunDocument } from './chunk-VAWYR6P4.js';
7
7
  import { useTr, ENGLISH_FALLBACK_TRANSLATOR, FluidGridsTranslationProvider } from './chunk-UULVIT25.js';
8
8
  import { waitForFluidGridsClient, getFluidGridsClient, getFluidGridsClientSafe, createFluidGridsClient, setFluidGridsClient, resetFluidGridsClient } from './chunk-PDODDDHY.js';
9
9
  import { throwIfResultError, emitFluidGridsEvent, emitOperationErrorEvent, describeOperationError, emitRunCompletedOnce } from './chunk-JKLZ6YZ3.js';
@@ -1,10 +1,10 @@
1
- import { FailureTriagePanel } from './chunk-I567MFKA.js';
1
+ import { FailureTriagePanel } from './chunk-Q526TUOC.js';
2
2
  import { aiSpendPeriod, AI_SPEND_RANGE_DAYS, evidenceFacts, monthlySavingLabel, evidenceWindowDays, shortRunId, DISMISS_REASONS, MAX_DISMISS_NOTE_LENGTH, aiCost, formatTokens, runsOfWorkflowPath } from './chunk-NZAYYUQ4.js';
3
- import { useDataSinks, useDataSinkData, useInsightsData, useRunReplayActions } from './chunk-HBMU63XF.js';
3
+ import { useDataSinks, useDataSinkData, useInsightsData, useRunReplayActions } from './chunk-3CAYQ57D.js';
4
4
  import { proposalCanvasPath } from './chunk-GLYINMOR.js';
5
- import { useContinuousOptimisationEnabled } from './chunk-V7MQXTHD.js';
6
- import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-AR22A74Y.js';
7
- import { SetContinuousOptimisationEnabledDocument, FgRunOptimisationScanDocument, ProposeOptimisationDocument, WorkflowProposalDocument, DismissOptimisationSuggestionDocument, SnoozeOptimisationSuggestionDocument, WorkspaceAiUsageDocument, OptimisationSuggestionsDocument, ContinuousOptimisationSettingsDocument } from './chunk-ZGUW4GHR.js';
5
+ import { useContinuousOptimisationEnabled } from './chunk-XSUFTJCE.js';
6
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-ERT444RG.js';
7
+ import { SetContinuousOptimisationEnabledDocument, FgRunOptimisationScanDocument, ProposeOptimisationDocument, WorkflowProposalDocument, DismissOptimisationSuggestionDocument, SnoozeOptimisationSuggestionDocument, WorkspaceAiUsageDocument, OptimisationSuggestionsDocument, ContinuousOptimisationSettingsDocument } from './chunk-VAWYR6P4.js';
8
8
  import { useTr } from './chunk-UULVIT25.js';
9
9
  import { getFluidGridsClient } from './chunk-PDODDDHY.js';
10
10
  import { throwIfResultError } from './chunk-JKLZ6YZ3.js';
@@ -1,11 +1,11 @@
1
- import { useRunStatusCounts, ExecutionStats, ExecutionFilters, ExecutionTable, ExecutionCards, ExecutionTimeline, Pagination, runStatusLabels } from './chunk-BR7MKKPP.js';
2
- import { useExecutionsWithStore, useExecutionStats, useExecutionActions, useAutoRefresh, searchFilterConflicts, WORKFLOW_ID_MAX_LENGTH, EMPTY_SEARCH_FILTER, buildSearchAttributeFilter, MAX_SEARCH_CONDITIONS, OPERATORS_BY_TYPE } from './chunk-6BO4LPNT.js';
3
- import { useResource, fetchSearchAttributes, NativeSelect, FieldError, RUN_CONTROL_DIALOG_STYLE, parseJsonInput, JsonField, fetchBatchOperations, StatusPill, fetchBatchOperation, cancelBatchOperation, startBatchTerminate, startBatchExport, startBatchOperation, jsonArg } from './chunk-ACNJS4OL.js';
4
- import { useWorkflowDefinitions } from './chunk-RIJ7IB5D.js';
1
+ import { useRunStatusCounts, ExecutionStats, ExecutionFilters, ExecutionTable, ExecutionCards, ExecutionTimeline, Pagination, runStatusLabels } from './chunk-EGCUHKON.js';
2
+ import { useExecutionsWithStore, useExecutionStats, useExecutionActions, useAutoRefresh, searchFilterConflicts, WORKFLOW_ID_MAX_LENGTH, EMPTY_SEARCH_FILTER, buildSearchAttributeFilter, MAX_SEARCH_CONDITIONS, OPERATORS_BY_TYPE } from './chunk-OJPRKEP4.js';
3
+ import { useResource, fetchSearchAttributes, NativeSelect, FieldError, RUN_CONTROL_DIALOG_STYLE, parseJsonInput, JsonField, fetchBatchOperations, StatusPill, fetchBatchOperation, cancelBatchOperation, startBatchTerminate, startBatchExport, startBatchOperation, jsonArg } from './chunk-5YLS3WH5.js';
4
+ import { useWorkflowDefinitions } from './chunk-JFUQH6HV.js';
5
5
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
6
- import { useDurableParityEnabled, usePhaseCFlags } from './chunk-V7MQXTHD.js';
7
- import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-AR22A74Y.js';
8
- import { WorkflowBatchOperationUpdatedDocument } from './chunk-ZGUW4GHR.js';
6
+ import { useDurableParityEnabled, usePhaseCFlags } from './chunk-XSUFTJCE.js';
7
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-ERT444RG.js';
8
+ import { WorkflowBatchOperationUpdatedDocument } from './chunk-VAWYR6P4.js';
9
9
  import { useTr } from './chunk-UULVIT25.js';
10
10
  import { getFluidGridsClient } from './chunk-PDODDDHY.js';
11
11
  import { describeOperationError } from './chunk-JKLZ6YZ3.js';
@@ -1,32 +1,32 @@
1
1
  import './chunk-AD3BXTJS.js';
2
- export { ExecutionDetailPage } from './chunk-M2MTUG6O.js';
3
- import './chunk-IOW5LL6I.js';
4
- export { ExecutionsListPage } from './chunk-3RZYBITM.js';
5
- import './chunk-BR7MKKPP.js';
6
- import './chunk-6BO4LPNT.js';
7
- import './chunk-I567MFKA.js';
2
+ export { ExecutionDetailPage } from './chunk-ODXI4P3V.js';
3
+ import './chunk-MUIVZFIU.js';
4
+ export { ExecutionsListPage } from './chunk-ZMEBM2GZ.js';
5
+ import './chunk-EGCUHKON.js';
6
+ import './chunk-OJPRKEP4.js';
7
+ import './chunk-Q526TUOC.js';
8
8
  import './chunk-NZAYYUQ4.js';
9
9
  import './chunk-OJHBCOBA.js';
10
- import './chunk-ACNJS4OL.js';
10
+ import './chunk-5YLS3WH5.js';
11
11
  import './chunk-WZ3EJVS6.js';
12
12
  import './chunk-5ERAJC2I.js';
13
- import './chunk-TJKT64AI.js';
13
+ import './chunk-MYE6CMGK.js';
14
14
  import './chunk-JDLQ6QIB.js';
15
- import './chunk-D6NTP4FK.js';
15
+ import './chunk-DFFQYK2X.js';
16
16
  import './chunk-Y53CVZVV.js';
17
17
  import './chunk-FNZZ5JJL.js';
18
- import './chunk-RIJ7IB5D.js';
18
+ import './chunk-JFUQH6HV.js';
19
19
  import './chunk-PJAWNFJV.js';
20
20
  import './chunk-4VJ3MDOV.js';
21
- import './chunk-W5UXYPBV.js';
22
- import './chunk-V7MQXTHD.js';
23
- import './chunk-AR22A74Y.js';
21
+ import './chunk-POCNG3PM.js';
22
+ import './chunk-XSUFTJCE.js';
23
+ import './chunk-ERT444RG.js';
24
24
  import './chunk-SDZEAIIE.js';
25
25
  import './chunk-X3F5IQBP.js';
26
26
  import './chunk-Y7FKJJMF.js';
27
27
  import './chunk-TYI2XOSI.js';
28
28
  import './chunk-G77IGC3Y.js';
29
- import './chunk-ZGUW4GHR.js';
29
+ import './chunk-VAWYR6P4.js';
30
30
  import './chunk-JL7CASN5.js';
31
31
  import './chunk-UULVIT25.js';
32
32
  import './chunk-PDODDDHY.js';