@burdenoff/fluidgrids-fe-sdk 2026.1108.6 → 2026.1109.2

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-PY5OE2RJ.js → ExecutionDetailPage-NOHVD3GW.js} +13 -13
  3. package/dist/{ExecutionsListPage-LKNYPXNZ.js → ExecutionsListPage-BZ7MBERP.js} +10 -10
  4. package/dist/{TemplateDetailPanel-5WY75DVB.js → TemplateDetailPanel-AIMUAFCB.js} +1 -1
  5. package/dist/{WorkflowBuilder-FDSHLSC4.js → WorkflowBuilder-6VJMPSMM.js} +12 -12
  6. package/dist/{WorkflowsList-TETNEMYP.js → WorkflowsList-LXQT3O6D.js} +9 -9
  7. package/dist/{agentTools-BW2XMHRV.js → agentTools-4YHOYCIG.js} +4 -4
  8. package/dist/{chunk-ZHXJYOOG.js → chunk-3APMDE3W.js} +12 -30
  9. package/dist/{chunk-HSOSMPRC.js → chunk-3BY5BCHM.js} +1 -1
  10. package/dist/{chunk-54NXUOHI.js → chunk-3CJVRCFN.js} +1 -1
  11. package/dist/{chunk-MJ5EI5OT.js → chunk-5N7OLQBQ.js} +12 -12
  12. package/dist/{chunk-POYMF7L6.js → chunk-62AXA6DK.js} +1 -1
  13. package/dist/{chunk-GI6BQIQA.js → chunk-62DQJ7V7.js} +2 -2
  14. package/dist/{chunk-PXFGXC7J.js → chunk-6QXEVFKO.js} +3 -3
  15. package/dist/{chunk-KJB3WZVD.js → chunk-6ZB7AYSA.js} +2 -2
  16. package/dist/{chunk-CRTZL55P.js → chunk-7CIXQOB6.js} +5 -5
  17. package/dist/{chunk-JSJSBB76.js → chunk-BA6WBJIB.js} +2 -2
  18. package/dist/{chunk-SOZUAJYS.js → chunk-BRJDII74.js} +5 -5
  19. package/dist/{chunk-HPNZ3PYU.js → chunk-CST6ZGPS.js} +7 -7
  20. package/dist/{chunk-AR22A74Y.js → chunk-ERT444RG.js} +1 -0
  21. package/dist/{chunk-TN3NGTF7.js → chunk-H7WYQSBK.js} +3 -3
  22. package/dist/{chunk-L7PHZ7RY.js → chunk-I5T7RD3R.js} +1 -1
  23. package/dist/{chunk-F32UAOHF.js → chunk-LWEOPSWO.js} +4 -4
  24. package/dist/{chunk-MYPB2KTJ.js → chunk-NUQA7J3T.js} +2 -2
  25. package/dist/{chunk-DG4UO5OY.js → chunk-RFGO4NL3.js} +5 -5
  26. package/dist/{chunk-D5Y3DHGJ.js → chunk-S4A646OO.js} +1 -1
  27. package/dist/{chunk-LOMLLWHD.js → chunk-SUQVJ2Y7.js} +491 -9
  28. package/dist/{chunk-HICQ4J4W.js → chunk-SUXYCC3X.js} +1 -1
  29. package/dist/{chunk-HQSSW7K3.js → chunk-UKQXYQPG.js} +7 -7
  30. package/dist/{chunk-RNYFPG7R.js → chunk-VD4WCZJX.js} +4 -4
  31. package/dist/{chunk-2VSYOGNI.js → chunk-W5UXYPBV.js} +69 -302
  32. package/dist/{chunk-IZOPKR64.js → chunk-WDZDVYWB.js} +2 -2
  33. package/dist/{chunk-7XW6BC4B.js → chunk-X4HCPG2E.js} +1 -1
  34. package/dist/{chunk-JRR4VKYD.js → chunk-XOP5EU72.js} +2 -2
  35. package/dist/{chunk-YASVILWQ.js → chunk-Y6HULMZS.js} +1 -1
  36. package/dist/{chunk-VH3EET6H.js → chunk-ZCLVWKVA.js} +2 -2
  37. package/dist/{chunk-GOZR72NK.js → chunk-ZPPF65KT.js} +3 -9
  38. package/dist/executions.js +14 -14
  39. package/dist/history.js +6 -6
  40. package/dist/index.d.ts +643 -2383
  41. package/dist/index.js +62 -559
  42. package/dist/{node-detail-view-PLCZIWJS.js → node-detail-view-54IIQK6V.js} +9 -9
  43. package/dist/nodes.js +2 -2
  44. package/dist/observability.js +7 -7
  45. package/dist/{quick-config-panel-FMDKFGSY.js → quick-config-panel-6QFTEM75.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,465 @@
1
- import { AgentsTab } from './chunk-D5Y3DHGJ.js';
1
+ import { AgentsTab } from './chunk-S4A646OO.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-YASVILWQ.js';
4
- import { LogStreamingTab } from './chunk-POYMF7L6.js';
3
+ import { useResource, fetchPauseRules, FieldError, fetchSearchAttributes, StatusPill, NativeSelect, fetchArchiveSettings, fetchCodecServerSettings, deletePauseRule, createPauseRule, deleteSearchAttribute, createSearchAttribute, saveArchiveSettings, clearArchiveSettings, saveCodecServerSettings } from './chunk-Y6HULMZS.js';
4
+ import { LogStreamingTab } from './chunk-62AXA6DK.js';
5
5
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
6
- import { useFluidGridsFlag, FLUIDGRIDS_FLAGS, usePhaseCFlags, useSaveStatusStore, findSaveConflict, useDurableParityEnabled, useConnections } from './chunk-GI6BQIQA.js';
7
- import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS } from './chunk-AR22A74Y.js';
6
+ import { useFluidGridsFlag, FLUIDGRIDS_FLAGS, usePhaseCFlags, useSaveStatusStore, findSaveConflict, useDurableParityEnabled, useConnections } from './chunk-62DQJ7V7.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-GOZR72NK.js';
10
+ import { useWorkflowDefinitionQuery, useUpdateWorkflowDefinitionMutation, useWorkflowDefinitionsQuery, ManagedAiWorkspacePolicyDocument, UpdateManagedAiWorkspacePolicyDocument, DurableHistoryCapsDocument, UpdateDurableHistoryCapsDocument } from './chunk-ZPPF65KT.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.enabled !== "boolean" || !Number.isSafeInteger(value.revision) || value.revision < 0 || 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
+ enabled: value.enabled,
151
+ revision: value.revision,
152
+ requiredConsentVersion: value.requiredConsentVersion
153
+ };
154
+ }
155
+ function useManagedAiWorkspacePolicy(authority, enabled, requestFactory = createManagedAiRequest) {
156
+ const current = useRef(authority);
157
+ const pending = useRef(null);
158
+ const generation = useRef(0);
159
+ const writing = useRef(null);
160
+ const [state, setState] = useState(EMPTY);
161
+ useLayoutEffect(() => {
162
+ current.current = enabled ? authority : null;
163
+ return () => {
164
+ current.current = null;
165
+ generation.current += 1;
166
+ writing.current = null;
167
+ pending.current?.abort();
168
+ };
169
+ }, [authority, enabled]);
170
+ const request = useMemo(
171
+ () => authority ? requestFactory(authority, () => current.current) : null,
172
+ [authority, requestFactory]
173
+ );
174
+ const reload = useCallback(async () => {
175
+ if (!authority || !request || !enabled || current.current !== authority)
176
+ return;
177
+ pending.current?.abort();
178
+ const controller = new AbortController();
179
+ pending.current = controller;
180
+ const id = ++generation.current;
181
+ setState((previous) => ({
182
+ authority,
183
+ policy: null,
184
+ loading: true,
185
+ workspaceWideRequired: false,
186
+ error: null,
187
+ readVersion: previous.authority === authority ? previous.readVersion : 0
188
+ }));
189
+ clearGraphqlFetchResponseCache();
190
+ try {
191
+ const data = await request(
192
+ print(ManagedAiWorkspacePolicyDocument),
193
+ {},
194
+ controller.signal
195
+ );
196
+ const policy = policyView(data.workflowWorkspaceAiPolicy);
197
+ if (id !== generation.current || current.current !== authority || controller.signal.aborted)
198
+ return;
199
+ setState((previous) => ({
200
+ authority,
201
+ policy,
202
+ loading: false,
203
+ workspaceWideRequired: false,
204
+ error: null,
205
+ readVersion: previous.readVersion + 1
206
+ }));
207
+ } catch (error) {
208
+ if (id === generation.current && current.current === authority && !controller.signal.aborted) {
209
+ setState((previous) => ({
210
+ ...previous,
211
+ authority,
212
+ policy: null,
213
+ loading: false,
214
+ error: "Managed AI settings could not be confirmed.",
215
+ workspaceWideRequired: error instanceof ManagedAiWorkspaceWideRequired
216
+ }));
217
+ }
218
+ }
219
+ }, [authority, enabled, request]);
220
+ useEffect(() => {
221
+ void reload();
222
+ return () => {
223
+ pending.current?.abort();
224
+ };
225
+ }, [reload]);
226
+ const save = useCallback(
227
+ async (change) => {
228
+ if (writing.current !== null || !authority || !request || !enabled || current.current !== authority || state.authority !== authority || !state.policy?.enforcementActive || state.loading || state.error || change.enabled && change.consentVersion !== state.policy.requiredConsentVersion || change.expectedRevision !== state.policy.revision) {
229
+ throw new Error(
230
+ "Reload the current managed AI setting before continuing."
231
+ );
232
+ }
233
+ pending.current?.abort();
234
+ const controller = new AbortController();
235
+ pending.current = controller;
236
+ const id = ++generation.current;
237
+ writing.current = id;
238
+ clearGraphqlFetchResponseCache();
239
+ try {
240
+ const data = await request(
241
+ print(UpdateManagedAiWorkspacePolicyDocument),
242
+ { input: change },
243
+ controller.signal
244
+ );
245
+ const policy = policyView(data.updateWorkflowWorkspaceAiPolicy);
246
+ if (id !== generation.current || current.current !== authority || controller.signal.aborted || !policy.enforcementActive || policy.enabled !== change.enabled || policy.revision <= change.expectedRevision)
247
+ throw new Error("Managed AI change could not be confirmed.");
248
+ setState((previous) => ({
249
+ ...previous,
250
+ authority,
251
+ policy,
252
+ loading: false,
253
+ error: null
254
+ }));
255
+ } catch (error) {
256
+ clearGraphqlFetchResponseCache();
257
+ if (id === generation.current && current.current === authority)
258
+ setState((previous) => ({
259
+ ...previous,
260
+ authority,
261
+ policy: null,
262
+ loading: false,
263
+ error: "Reload to confirm the managed AI setting.",
264
+ workspaceWideRequired: error instanceof ManagedAiWorkspaceWideRequired
265
+ }));
266
+ throw new Error("Managed AI change could not be confirmed.");
267
+ } finally {
268
+ if (writing.current === id) writing.current = null;
269
+ }
270
+ },
271
+ [authority, enabled, request, state]
272
+ );
273
+ const visible = enabled && authority !== null && state.authority === authority;
274
+ return {
275
+ policy: visible ? state.policy : null,
276
+ loading: enabled && authority !== null && (!visible || state.loading),
277
+ error: visible ? state.error : null,
278
+ readVersion: visible ? state.readVersion : 0,
279
+ workspaceWideRequired: visible && state.workspaceWideRequired,
280
+ reload,
281
+ save
282
+ };
283
+ }
284
+ function ManagedAiPolicyCard(props) {
285
+ const versionKey = JSON.stringify([
286
+ props.scopeKey,
287
+ props.readVersion,
288
+ props.policy?.revision,
289
+ props.policy?.requiredConsentVersion,
290
+ props.policy?.enabled,
291
+ props.policy?.enforcementActive
292
+ ]);
293
+ return /* @__PURE__ */ jsx(ManagedAiPolicyForm, { ...props }, versionKey);
294
+ }
295
+ function ManagedAiPolicyForm({
296
+ policy,
297
+ loading,
298
+ error,
299
+ workspaceWideRequired,
300
+ canManage,
301
+ reload,
302
+ save
303
+ }) {
304
+ const tr = useTr();
305
+ const [acknowledged, setAcknowledged] = useState(false);
306
+ const [saving, setSaving] = useState(false);
307
+ const [saveFailed, setSaveFailed] = useState(false);
308
+ const change = async (enabled) => {
309
+ if (!policy?.enforcementActive || !canManage || saving || saveFailed)
310
+ return;
311
+ if (enabled && !acknowledged) return;
312
+ setSaving(true);
313
+ setSaveFailed(false);
314
+ try {
315
+ await save({
316
+ enabled,
317
+ expectedRevision: policy.revision,
318
+ ...enabled ? { consentVersion: policy.requiredConsentVersion } : {}
319
+ });
320
+ setAcknowledged(false);
321
+ } catch {
322
+ setSaveFailed(true);
323
+ } finally {
324
+ setSaving(false);
325
+ }
326
+ };
327
+ return /* @__PURE__ */ jsxs(
328
+ "section",
329
+ {
330
+ className: "space-y-4 rounded-lg border border-border-default bg-background-secondary p-5",
331
+ "aria-label": tr("fluidgrids.settings.managedAi.title", "Managed AI"),
332
+ children: [
333
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-text-primary", children: tr("fluidgrids.settings.managedAi.title", "Managed AI") }),
334
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary", children: tr(
335
+ "fluidgrids.settings.managedAi.disclosure",
336
+ "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."
337
+ ) }),
338
+ /* @__PURE__ */ jsx(
339
+ "a",
340
+ {
341
+ href: "https://www.fluidgrids.ai/ai-terms",
342
+ target: "_blank",
343
+ rel: "noopener noreferrer",
344
+ className: "text-sm text-text-primary underline underline-offset-4",
345
+ children: tr("fluidgrids.settings.managedAi.terms", "Read AI Product Terms")
346
+ }
347
+ ),
348
+ /* @__PURE__ */ jsx(
349
+ ManagedAiPolicyStatus,
350
+ {
351
+ policy,
352
+ loading,
353
+ error,
354
+ workspaceWideRequired,
355
+ children: policy && /* @__PURE__ */ jsx(Fragment, { children: canManage ? /* @__PURE__ */ jsxs(Fragment, { children: [
356
+ !policy.enabled && /* @__PURE__ */ jsxs("label", { className: "flex items-start gap-3 text-sm text-text-secondary", children: [
357
+ /* @__PURE__ */ jsx(
358
+ "input",
359
+ {
360
+ type: "checkbox",
361
+ checked: acknowledged,
362
+ onChange: (event) => setAcknowledged(event.target.checked),
363
+ disabled: saving || saveFailed
364
+ }
365
+ ),
366
+ tr(
367
+ "fluidgrids.settings.managedAi.acknowledge",
368
+ "I reviewed the current AI disclosure and approve managed AI requests for this workspace."
369
+ )
370
+ ] }),
371
+ /* @__PURE__ */ jsx(
372
+ Button,
373
+ {
374
+ onClick: () => void change(!policy.enabled),
375
+ disabled: saving || saveFailed || !policy.enabled && !acknowledged,
376
+ children: saving ? tr("fluidgrids.settings.managedAi.saving", "Saving\u2026") : policy.enabled ? tr(
377
+ "fluidgrids.settings.managedAi.disable",
378
+ "Turn off managed AI"
379
+ ) : tr(
380
+ "fluidgrids.settings.managedAi.enable",
381
+ "Enable managed AI"
382
+ )
383
+ }
384
+ )
385
+ ] }) : /* @__PURE__ */ jsx("p", { className: "text-sm text-text-secondary", children: tr(
386
+ "fluidgrids.settings.managedAi.ownerOnly",
387
+ "A workspace administrator manages this setting."
388
+ ) }) })
389
+ }
390
+ ),
391
+ saveFailed && /* @__PURE__ */ jsx("p", { role: "alert", children: tr(
392
+ "fluidgrids.settings.managedAi.saveFailed",
393
+ "The change could not be confirmed. Reload the current setting before trying again."
394
+ ) }),
395
+ /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: reload, disabled: loading || saving, children: tr("fluidgrids.settings.managedAi.reload", "Reload current setting") })
396
+ ]
397
+ }
398
+ );
399
+ }
400
+ function ManagedAiPolicyStatus({
401
+ policy,
402
+ loading,
403
+ error,
404
+ workspaceWideRequired,
405
+ children
406
+ }) {
407
+ const tr = useTr();
408
+ if (loading)
409
+ return /* @__PURE__ */ jsx("p", { role: "status", children: tr(
410
+ "fluidgrids.settings.managedAi.loading",
411
+ "Loading workspace AI settings\u2026"
412
+ ) });
413
+ if (error || !policy)
414
+ return /* @__PURE__ */ jsx("p", { role: "alert", children: workspaceWideRequired ? tr(
415
+ "fluidgrids.settings.managedAi.workspaceWideRequired",
416
+ "Select the workspace without a project, then reload its AI setting."
417
+ ) : tr(
418
+ "fluidgrids.settings.managedAi.loadFailed",
419
+ "Workspace AI settings could not be loaded. Reload before changing approval."
420
+ ) });
421
+ if (!policy.enforcementActive)
422
+ return /* @__PURE__ */ jsx("p", { role: "status", children: tr(
423
+ "fluidgrids.settings.managedAi.pending",
424
+ "Workspace AI controls are not active yet. Existing managed AI behavior is unchanged, and no approval change can be saved."
425
+ ) });
426
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
427
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-text-primary", role: "status", children: policy.enabled ? tr(
428
+ "fluidgrids.settings.managedAi.enabled",
429
+ "Managed AI is on for this workspace."
430
+ ) : tr(
431
+ "fluidgrids.settings.managedAi.disabled",
432
+ "Managed AI is off for this workspace."
433
+ ) }),
434
+ children
435
+ ] });
436
+ }
437
+ function ManagedAiSettings() {
438
+ const authority = useManagedAiPolicyAuthority();
439
+ const read = useFluidGridsPermission(FLUIDGRIDS_PERMISSIONS.WORKFLOW_READ);
440
+ const manage = useFluidGridsPermission(
441
+ FLUIDGRIDS_PERMISSIONS.SYSTEM_CONFIG_MANAGE
442
+ );
443
+ const state = useManagedAiWorkspacePolicy(authority, read.allowed);
444
+ if (!authority || !read.allowed) return null;
445
+ const scopeKey = JSON.stringify([
446
+ authority.authority,
447
+ authority.url,
448
+ authority.actorId,
449
+ authority.workspaceId,
450
+ authority.organizationId,
451
+ authority.tenantId,
452
+ authority.projectId
453
+ ]);
454
+ return /* @__PURE__ */ jsx(
455
+ ManagedAiPolicyCard,
456
+ {
457
+ ...state,
458
+ scopeKey,
459
+ canManage: manage.enforced && manage.allowed
460
+ }
461
+ );
462
+ }
26
463
  function SettingRow({
27
464
  label,
28
465
  description,
@@ -3643,7 +4080,10 @@ function SettingsPage({
3643
4080
  ]
3644
4081
  }
3645
4082
  ),
3646
- /* @__PURE__ */ jsx(TabsContent, { value: "general", children: /* @__PURE__ */ jsx(GeneralTab, {}) }),
4083
+ /* @__PURE__ */ jsxs(TabsContent, { value: "general", children: [
4084
+ /* @__PURE__ */ jsx(GeneralTab, {}),
4085
+ /* @__PURE__ */ jsx("div", { className: "mt-6", children: /* @__PURE__ */ jsx(ManagedAiSettings, {}) })
4086
+ ] }),
3647
4087
  /* @__PURE__ */ jsx(TabsContent, { value: "execution", children: /* @__PURE__ */ jsx(ExecutionTab, { workflowKey }) }),
3648
4088
  /* @__PURE__ */ jsx(TabsContent, { value: "run-data", children: /* @__PURE__ */ jsx(RunDataTab, {}) }),
3649
4089
  runControlSettings ? /* @__PURE__ */ jsx(TabsContent, { value: "run-control", children: /* @__PURE__ */ jsx(RunControlTab, { flags: phaseC }) }) : null,
@@ -3656,5 +4096,47 @@ function SettingsPage({
3656
4096
  ] })
3657
4097
  ] });
3658
4098
  }
4099
+ function ManagedAiPolicyAuthorityProvider({
4100
+ scope,
4101
+ children
4102
+ }) {
4103
+ const {
4104
+ authority,
4105
+ url,
4106
+ actorId,
4107
+ workspaceId,
4108
+ organizationId,
4109
+ tenantId,
4110
+ projectId,
4111
+ authToken,
4112
+ workspaceToken
4113
+ } = scope ?? {};
4114
+ const value = useMemo(() => {
4115
+ if (!authority || !url || !actorId || !workspaceId || !organizationId || !tenantId || !authToken)
4116
+ return null;
4117
+ return Object.freeze({
4118
+ authority,
4119
+ url,
4120
+ actorId,
4121
+ workspaceId,
4122
+ organizationId,
4123
+ tenantId,
4124
+ projectId,
4125
+ authToken,
4126
+ workspaceToken
4127
+ });
4128
+ }, [
4129
+ authority,
4130
+ url,
4131
+ actorId,
4132
+ workspaceId,
4133
+ organizationId,
4134
+ tenantId,
4135
+ projectId,
4136
+ authToken,
4137
+ workspaceToken
4138
+ ]);
4139
+ return /* @__PURE__ */ jsx(ManagedAiAuthorityContext.Provider, { value, children });
4140
+ }
3659
4141
 
3660
- export { SettingsPage };
4142
+ export { ManagedAiPolicyAuthorityProvider, SettingsPage };
@@ -1,4 +1,4 @@
1
- import { FluidgridsEntityTagsDocument, AvailableFluidgridsTagsDocument, SearchFluidgridsTagsDocument, TagFluidgridsEntityDocument, UntagFluidgridsEntityDocument, ReplaceFluidgridsEntityTagsDocument, CreateFluidgridsTagDocument, DataTablesTagsDocument } from './chunk-GOZR72NK.js';
1
+ import { FluidgridsEntityTagsDocument, AvailableFluidgridsTagsDocument, SearchFluidgridsTagsDocument, TagFluidgridsEntityDocument, UntagFluidgridsEntityDocument, ReplaceFluidgridsEntityTagsDocument, CreateFluidgridsTagDocument, DataTablesTagsDocument } from './chunk-ZPPF65KT.js';
2
2
  import { getFluidGridsClient } from './chunk-PDODDDHY.js';
3
3
  import { useState, useCallback, useEffect } from 'react';
4
4
 
@@ -1,14 +1,14 @@
1
- import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-7XW6BC4B.js';
2
- import { useExecutions } from './chunk-JRR4VKYD.js';
3
- import { useExportWorkflowAs, WorkflowShareDialog, downloadWorkflowExport, importAcceptAttribute, canEditWorkflow, canShareWorkflow, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-JSJSBB76.js';
1
+ import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-X4HCPG2E.js';
2
+ import { useExecutions } from './chunk-XOP5EU72.js';
3
+ import { useExportWorkflowAs, WorkflowShareDialog, downloadWorkflowExport, importAcceptAttribute, canEditWorkflow, canShareWorkflow, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-BA6WBJIB.js';
4
4
  import { workflowsListControls } from './chunk-FNZZ5JJL.js';
5
- import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, usePreviewN8nImport, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-KJB3WZVD.js';
5
+ import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, usePreviewN8nImport, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-6ZB7AYSA.js';
6
6
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
7
7
  import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
8
- import { createThenOpen, FluidGridsContext, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, isQuotaExhaustedFailure } from './chunk-GI6BQIQA.js';
9
- import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton, SdkPermissionGate } from './chunk-AR22A74Y.js';
8
+ import { createThenOpen, FluidGridsContext, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, isQuotaExhaustedFailure } from './chunk-62DQJ7V7.js';
9
+ import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton, SdkPermissionGate } from './chunk-ERT444RG.js';
10
10
  import { useFlowStore } from './chunk-X3F5IQBP.js';
11
- import { WorkflowFoldersDocument, CreateWorkflowFolderDocument, RenameWorkflowFolderDocument, MoveWorkflowFolderDocument, DeleteWorkflowFolderDocument, WorkflowProjectsDocument, CreateWorkflowProjectDocument, RenameWorkflowProjectDocument, DeleteWorkflowProjectDocument, BulkMoveWorkflowsToFolderDocument, BulkAssignWorkflowsToProjectDocument, BulkDeleteWorkflowsDocument } from './chunk-GOZR72NK.js';
11
+ import { WorkflowFoldersDocument, CreateWorkflowFolderDocument, RenameWorkflowFolderDocument, MoveWorkflowFolderDocument, DeleteWorkflowFolderDocument, WorkflowProjectsDocument, CreateWorkflowProjectDocument, RenameWorkflowProjectDocument, DeleteWorkflowProjectDocument, BulkMoveWorkflowsToFolderDocument, BulkAssignWorkflowsToProjectDocument, BulkDeleteWorkflowsDocument } from './chunk-ZPPF65KT.js';
12
12
  import { useTr } from './chunk-UULVIT25.js';
13
13
  import { getFluidGridsClient } from './chunk-PDODDDHY.js';
14
14
  import { describeOperationError, throwIfResultError } from './chunk-JKLZ6YZ3.js';
@@ -1,10 +1,10 @@
1
- import { validateDateRange, statusCountFilter, STATUS_COUNT_GROUP_BY, statusCountsOf } from './chunk-JRR4VKYD.js';
1
+ import { validateDateRange, statusCountFilter, STATUS_COUNT_GROUP_BY, statusCountsOf } from './chunk-XOP5EU72.js';
2
2
  import { isAgentNodeType } from './chunk-WZ3EJVS6.js';
3
- import { useAvailableTags, formatRunVersion, nodeDisplayTitle } from './chunk-HICQ4J4W.js';
3
+ import { useAvailableTags, formatRunVersion, nodeDisplayTitle } from './chunk-SUXYCC3X.js';
4
4
  import { executionsControls } from './chunk-FNZZ5JJL.js';
5
5
  import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
6
- import { useDurableParityEnabled, formatElapsedMs, runDurationMs, nodeStateDurationMs } from './chunk-GI6BQIQA.js';
7
- import { SetWorkflowRunVersioningOverrideDocument, WorkflowRunsCountDocument, DurableParityRunFieldsDocument, WorkflowRunPendingDocument, WorkflowRunMetadataDocument } from './chunk-GOZR72NK.js';
6
+ import { useDurableParityEnabled, formatElapsedMs, runDurationMs, nodeStateDurationMs } from './chunk-62DQJ7V7.js';
7
+ import { SetWorkflowRunVersioningOverrideDocument, WorkflowRunsCountDocument, DurableParityRunFieldsDocument, WorkflowRunPendingDocument, WorkflowRunMetadataDocument } from './chunk-ZPPF65KT.js';
8
8
  import { useTr } from './chunk-UULVIT25.js';
9
9
  import { getFluidGridsClient } from './chunk-PDODDDHY.js';
10
10
  import { throwIfResultError, describeOperationError } from './chunk-JKLZ6YZ3.js';