@aglyn/plugins-ai 1.0.0-beta.229 → 1.0.0-beta.230
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.
- package/README.md +3 -3
- package/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.js +7 -1
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-automation-zones.d.ts +38 -0
- package/src/lib/components/ai-automation-zones.js +5 -1
- package/src/lib/components/ai-automation-zones.js.map +1 -1
- package/src/lib/components/ai-brief-dialog.component.d.ts +20 -2
- package/src/lib/components/ai-brief-dialog.component.js +87 -8
- package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
- package/src/lib/components/ai-campaign-create.component.d.ts +54 -0
- package/src/lib/components/ai-campaign-create.component.js +270 -0
- package/src/lib/components/ai-campaign-create.component.js.map +1 -0
- package/src/lib/components/ai-describe-automation.component.d.ts +8 -3
- package/src/lib/components/ai-describe-automation.component.js +15 -6
- package/src/lib/components/ai-describe-automation.component.js.map +1 -1
- package/src/lib/components/ai-describe-button.component.d.ts +20 -8
- package/src/lib/components/ai-describe-button.component.js +19 -36
- package/src/lib/components/ai-describe-button.component.js.map +1 -1
- package/src/lib/components/ai-describe-email.component.d.ts +31 -0
- package/src/lib/components/ai-describe-email.component.js +22 -0
- package/src/lib/components/ai-describe-email.component.js.map +1 -0
- package/src/lib/components/ai-describe-org-automation.component.d.ts +36 -0
- package/src/lib/components/ai-describe-org-automation.component.js +238 -0
- package/src/lib/components/ai-describe-org-automation.component.js.map +1 -0
- package/src/lib/components/ai-experiment-cards.component.d.ts +9 -1
- package/src/lib/components/ai-experiment-cards.component.js +104 -18
- package/src/lib/components/ai-experiment-cards.component.js.map +1 -1
- package/src/lib/components/ai-explain-automation.component.js +1 -5
- package/src/lib/components/ai-explain-automation.component.js.map +1 -1
- package/src/lib/components/ai-funnel-zones.component.d.ts +61 -0
- package/src/lib/components/ai-funnel-zones.component.js +178 -0
- package/src/lib/components/ai-funnel-zones.component.js.map +1 -0
- package/src/lib/components/ai-insight-card.component.d.ts +42 -0
- package/src/lib/components/ai-insight-card.component.js +137 -0
- package/src/lib/components/ai-insight-card.component.js.map +1 -0
- package/src/lib/components/ai-insight-dialog.component.d.ts +6 -0
- package/src/lib/components/ai-insight-dialog.component.js +9 -3
- package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
- package/src/lib/components/ai-job-plan.component.d.ts +7 -2
- package/src/lib/components/ai-job-plan.component.js +35 -5
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +17 -1
- package/src/lib/components/ai-job-requests.js +39 -3
- package/src/lib/components/ai-job-requests.js.map +1 -1
- package/src/lib/components/ai-logic-zones.d.ts +64 -0
- package/src/lib/components/ai-logic-zones.js +18 -0
- package/src/lib/components/ai-logic-zones.js.map +1 -0
- package/src/lib/components/ai-logic.component.d.ts +77 -0
- package/src/lib/components/ai-logic.component.js +553 -0
- package/src/lib/components/ai-logic.component.js.map +1 -0
- package/src/lib/components/ai-marketing-insight.component.d.ts +30 -0
- package/src/lib/components/ai-marketing-insight.component.js +80 -0
- package/src/lib/components/ai-marketing-insight.component.js.map +1 -0
- package/src/lib/components/ai-media-create.component.d.ts +55 -0
- package/src/lib/components/ai-media-create.component.js +433 -0
- package/src/lib/components/ai-media-create.component.js.map +1 -0
- package/src/lib/components/ai-overlay-cards.component.d.ts +83 -0
- package/src/lib/components/ai-overlay-cards.component.js +505 -0
- package/src/lib/components/ai-overlay-cards.component.js.map +1 -0
- package/src/lib/components/ai-product-zones.d.ts +5 -0
- package/src/lib/components/ai-product-zones.js +1 -1
- package/src/lib/components/ai-product-zones.js.map +1 -1
- package/src/lib/components/ai-products-create-button.component.d.ts +42 -0
- package/src/lib/components/ai-products-create-button.component.js +67 -0
- package/src/lib/components/ai-products-create-button.component.js.map +1 -0
- package/src/lib/components/ai-products-hub-card.component.js +100 -81
- package/src/lib/components/ai-products-hub-card.component.js.map +1 -1
- package/src/lib/components/ai-revise-automation.component.d.ts +16 -0
- package/src/lib/components/ai-revise-automation.component.js +207 -0
- package/src/lib/components/ai-revise-automation.component.js.map +1 -0
- package/src/lib/components/ai-site-build-page.component.js +140 -16
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-upsell-dialog.component.d.ts +53 -0
- package/src/lib/components/ai-upsell-dialog.component.js +177 -0
- package/src/lib/components/ai-upsell-dialog.component.js.map +1 -0
- package/src/lib/components/assist-build-card.component.d.ts +42 -0
- package/src/lib/components/assist-build-card.component.js +183 -0
- package/src/lib/components/assist-build-card.component.js.map +1 -0
- package/src/lib/components/assist-edit-canvas.d.ts +2 -0
- package/src/lib/components/assist-edit-canvas.js +56 -1
- package/src/lib/components/assist-edit-canvas.js.map +1 -1
- package/src/lib/components/assist-jobs-drawer.component.js +48 -3
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +51 -2
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/use-ai-job-run.d.ts +3 -14
- package/src/lib/components/use-ai-job-run.js +0 -50
- package/src/lib/components/use-ai-job-run.js.map +1 -1
- package/src/lib/jobs/ai-build-capabilities.d.ts +58 -0
- package/src/lib/jobs/ai-build-capabilities.js +256 -0
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -0
- package/src/lib/jobs/ai-build-unit-outcome.d.ts +52 -0
- package/src/lib/jobs/ai-build-unit-outcome.js +138 -0
- package/src/lib/jobs/ai-build-unit-outcome.js.map +1 -0
- package/src/lib/jobs/ai-job-build-step.d.ts +144 -0
- package/src/lib/jobs/ai-job-build-step.js +657 -0
- package/src/lib/jobs/ai-job-build-step.js.map +1 -0
- package/src/lib/jobs/ai-job-draft-ids.js +9 -1
- package/src/lib/jobs/ai-job-draft-ids.js.map +1 -1
- package/src/lib/jobs/ai-job-drafts.d.ts +14 -4
- package/src/lib/jobs/ai-job-drafts.js +25 -4
- package/src/lib/jobs/ai-job-drafts.js.map +1 -1
- package/src/lib/jobs/ai-job-logic-step.d.ts +107 -0
- package/src/lib/jobs/ai-job-logic-step.js +395 -0
- package/src/lib/jobs/ai-job-logic-step.js.map +1 -0
- package/src/lib/jobs/ai-job-overlay-copy.d.ts +70 -0
- package/src/lib/jobs/ai-job-overlay-copy.js +178 -0
- package/src/lib/jobs/ai-job-overlay-copy.js.map +1 -0
- package/src/lib/jobs/ai-job-page-step.js +6 -6
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +26 -1
- package/src/lib/jobs/ai-job-plan-step.js +79 -11
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +15 -1
- package/src/lib/jobs/ai-job-site-step.js +200 -58
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-text-step.d.ts +22 -1
- package/src/lib/jobs/ai-job-text-step.js +12 -0
- package/src/lib/jobs/ai-job-text-step.js.map +1 -1
- package/src/lib/jobs/ai-job-workflow-step.d.ts +54 -4
- package/src/lib/jobs/ai-job-workflow-step.js +318 -13
- package/src/lib/jobs/ai-job-workflow-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs.d.ts +80 -2
- package/src/lib/jobs/ai-jobs.js +377 -13
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/jobs/ai-logic-records.d.ts +40 -0
- package/src/lib/jobs/ai-logic-records.js +55 -0
- package/src/lib/jobs/ai-logic-records.js.map +1 -0
- package/src/lib/jobs/ai-site-publish.d.ts +7 -0
- package/src/lib/jobs/ai-site-publish.js +9 -0
- package/src/lib/jobs/ai-site-publish.js.map +1 -1
- package/src/lib/jobs/ai-workflow-records.d.ts +4 -0
- package/src/lib/jobs/ai-workflow-records.js +40 -1
- package/src/lib/jobs/ai-workflow-records.js.map +1 -1
- package/src/lib/model/ai-automation-draft.d.ts +18 -0
- package/src/lib/model/ai-automation-draft.js +86 -0
- package/src/lib/model/ai-automation-draft.js.map +1 -1
- package/src/lib/model/ai-build-job.d.ts +201 -0
- package/src/lib/model/ai-build-job.js +471 -0
- package/src/lib/model/ai-build-job.js.map +1 -0
- package/src/lib/model/ai-build-plan.d.ts +61 -0
- package/src/lib/model/ai-build-plan.js +154 -9
- package/src/lib/model/ai-build-plan.js.map +1 -1
- package/src/lib/model/ai-build-progress.d.ts +56 -0
- package/src/lib/model/ai-build-progress.js +128 -0
- package/src/lib/model/ai-build-progress.js.map +1 -0
- package/src/lib/model/ai-insight.d.ts +20 -10
- package/src/lib/model/ai-insight.js +72 -9
- package/src/lib/model/ai-insight.js.map +1 -1
- package/src/lib/model/ai-job-activity.js +3 -1
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +80 -2
- package/src/lib/model/ai-jobs.types.js +3 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-logic-job.d.ts +108 -0
- package/src/lib/model/ai-logic-job.js +327 -0
- package/src/lib/model/ai-logic-job.js.map +1 -0
- package/src/lib/model/ai-media-credits.d.ts +52 -0
- package/src/lib/model/ai-media-credits.js +61 -0
- package/src/lib/model/ai-media-credits.js.map +1 -0
- package/src/lib/model/ai-overlay-copy.d.ts +114 -0
- package/src/lib/model/ai-overlay-copy.js +175 -0
- package/src/lib/model/ai-overlay-copy.js.map +1 -0
- package/src/lib/model/ai-site-build-progress.d.ts +20 -3
- package/src/lib/model/ai-site-build-progress.js +170 -10
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-svg.d.ts +69 -0
- package/src/lib/model/ai-svg.js +265 -0
- package/src/lib/model/ai-svg.js.map +1 -0
- package/src/lib/model/ai-usage-by-user.d.ts +3 -2
- package/src/lib/model/ai-usage-by-user.js.map +1 -1
- package/src/lib/model/ai-workflow-job.d.ts +92 -4
- package/src/lib/model/ai-workflow-job.js +124 -7
- package/src/lib/model/ai-workflow-job.js.map +1 -1
- package/src/lib/model/assist-build.d.ts +58 -0
- package/src/lib/model/assist-build.js +52 -0
- package/src/lib/model/assist-build.js.map +1 -0
- package/src/lib/model/assist-edit.d.ts +48 -3
- package/src/lib/model/assist-edit.js +48 -4
- package/src/lib/model/assist-edit.js.map +1 -1
- package/src/lib/plugin-config.js +2 -0
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +240 -11
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/catalog.d.ts +81 -4
- package/src/lib/providers/catalog.js +80 -9
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/providers/image-contract.d.ts +116 -0
- package/src/lib/providers/image-contract.js +74 -0
- package/src/lib/providers/image-contract.js.map +1 -0
- package/src/lib/providers/model-choice.js +11 -0
- package/src/lib/providers/model-choice.js.map +1 -1
- package/src/lib/providers/routing.js +18 -0
- package/src/lib/providers/routing.js.map +1 -1
- package/src/lib/providers/vertex-image.d.ts +121 -0
- package/src/lib/providers/vertex-image.js +312 -0
- package/src/lib/providers/vertex-image.js.map +1 -0
- package/src/lib/runtime/ai-doctrine-validators.d.ts +19 -0
- package/src/lib/runtime/ai-doctrine-validators.js +89 -0
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-doctrine.js +11 -5
- package/src/lib/runtime/ai-doctrine.js.map +1 -1
- package/src/lib/runtime/ai-eval-live.js +4 -0
- package/src/lib/runtime/ai-eval-live.js.map +1 -1
- package/src/lib/runtime/ai-eval.d.ts +15 -1
- package/src/lib/runtime/ai-eval.js +52 -1
- package/src/lib/runtime/ai-eval.js.map +1 -1
- package/src/lib/runtime/experiment-variant-copy.d.ts +34 -0
- package/src/lib/runtime/experiment-variant-copy.js +102 -0
- package/src/lib/runtime/experiment-variant-copy.js.map +1 -0
- package/src/lib/server/ai-experiment-versions.d.ts +51 -0
- package/src/lib/server/ai-experiment-versions.js +270 -0
- package/src/lib/server/ai-experiment-versions.js.map +1 -0
- package/src/lib/server/ai-jobs-resume.js +74 -4
- package/src/lib/server/ai-jobs-resume.js.map +1 -1
- package/src/lib/server/ai-media-image.d.ts +66 -0
- package/src/lib/server/ai-media-image.js +521 -0
- package/src/lib/server/ai-media-image.js.map +1 -0
- package/src/lib/server/ai-media-svg.d.ts +91 -0
- package/src/lib/server/ai-media-svg.js +186 -0
- package/src/lib/server/ai-media-svg.js.map +1 -0
- package/src/lib/server/assist-build.d.ts +54 -0
- package/src/lib/server/assist-build.js +121 -0
- package/src/lib/server/assist-build.js.map +1 -0
- package/src/lib/server/assist-chat.js +108 -12
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit.js +213 -3
- package/src/lib/server/assist-edit.js.map +1 -1
- package/src/lib/server/assist-view-context.js +242 -4
- package/src/lib/server/assist-view-context.js.map +1 -1
- package/src/lib/server.js +26 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/tools/ai-logic-tool.d.ts +27 -0
- package/src/lib/tools/ai-logic-tool.js +207 -0
- package/src/lib/tools/ai-logic-tool.js.map +1 -0
- package/src/lib/tools/ai-overlay-tool.d.ts +35 -0
- package/src/lib/tools/ai-overlay-tool.js +107 -0
- package/src/lib/tools/ai-overlay-tool.js.map +1 -0
- package/src/lib/tools/ai-workflow-tool.d.ts +11 -0
- package/src/lib/tools/ai-workflow-tool.js +31 -0
- package/src/lib/tools/ai-workflow-tool.js.map +1 -1
- package/src/lib/usage/assist-job-refund.d.ts +28 -1
- package/src/lib/usage/assist-job-refund.js +44 -9
- package/src/lib/usage/assist-job-refund.js.map +1 -1
- package/src/lib/usage/assist-usage.d.ts +5 -0
- package/src/lib/usage/assist-usage.js +2 -0
- package/src/lib/usage/assist-usage.js.map +1 -1
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2026 Aglyn LLC
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/ import { pluginDocsHelp } from "@aglyn/aglyn/app-utils/docs-help";
|
|
19
|
+
import { mdiCreation } from "@aglyn/shared-data-mdi";
|
|
20
|
+
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
21
|
+
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
22
|
+
import { Alert, Box, Button, CircularProgress, Link, Stack, TextField, Typography } from "@mui/material";
|
|
23
|
+
import { useState } from "react";
|
|
24
|
+
import { openAiJobs } from "./ai-jobs-store.js";
|
|
25
|
+
import { aiJobProblem, useAiJobRun } from "./use-ai-job-run.js";
|
|
26
|
+
/**
|
|
27
|
+
* "Fix with AI" and "Change with AI" in the editor of a saved ACTION
|
|
28
|
+
* (AGL-3603), through the `automationEditor` zone. Each starts a `workflow`
|
|
29
|
+
* job in `revise` mode: the action as it is saved, and the change asked of
|
|
30
|
+
* it, become a NEW automation drafted switched off. The saved action is never
|
|
31
|
+
* written; the person opens the copy, reads what changed, and switches it on
|
|
32
|
+
* in place of the old one when it is right.
|
|
33
|
+
*
|
|
34
|
+
* A workflow of function calls is not offered either: the draft writer writes
|
|
35
|
+
* actions, and a workflow is explained rather than revised.
|
|
36
|
+
*/ /** The longest change a job admits as its brief. */ const BRIEF_MAX_CHARS = 4000;
|
|
37
|
+
export const AI_AUTOMATION_REVISE_COPY = {
|
|
38
|
+
intro: 'Describe a change, or let AI fix what would stop it working. You get a changed copy, switched off, to review — this one is left as it is.',
|
|
39
|
+
label: 'What should change?',
|
|
40
|
+
placeholder: 'Also tag them “newsletter”, and wait a day before the email',
|
|
41
|
+
change: 'Change with AI',
|
|
42
|
+
fix: 'Fix with AI',
|
|
43
|
+
running: 'Drafting the changed copy. This can take a few minutes.',
|
|
44
|
+
drafted: 'Changed copy drafted',
|
|
45
|
+
review: 'Review the copy',
|
|
46
|
+
notListed: 'The copy is saved. It appears in the list in a moment.',
|
|
47
|
+
failed: 'The automation could not be changed. Try again.',
|
|
48
|
+
fixBrief: (name)=>`Fix whatever in “${name}” would stop it working as intended — a record the site no longer has, a condition that can never match, a step in the wrong order. Change nothing else.`
|
|
49
|
+
};
|
|
50
|
+
export function AiReviseAutomation({ hostId, orgId, target, openAction }) {
|
|
51
|
+
var _aiJobProblem;
|
|
52
|
+
const copy = AI_AUTOMATION_REVISE_COPY;
|
|
53
|
+
const help = pluginDocsHelp('aiAutomations', {
|
|
54
|
+
anchor: '#change'
|
|
55
|
+
});
|
|
56
|
+
const { data: user } = useUser();
|
|
57
|
+
const run = useAiJobRun(user, copy.failed);
|
|
58
|
+
const [brief, setBrief] = useState('');
|
|
59
|
+
const [notListed, setNotListed] = useState(false);
|
|
60
|
+
if (target.type !== 'action') return null;
|
|
61
|
+
const { job } = run;
|
|
62
|
+
const busy = run.starting || run.running;
|
|
63
|
+
const draft = (job == null ? void 0 : job.status) === 'done' ? job.outputs.find((output)=>output.resource === 'workflow') : undefined;
|
|
64
|
+
const problem = (_aiJobProblem = aiJobProblem(job, copy.failed)) != null ? _aiJobProblem : (job == null ? void 0 : job.status) === 'done' && !draft ? copy.failed : null;
|
|
65
|
+
const start = async (text)=>{
|
|
66
|
+
const trimmed = text.trim();
|
|
67
|
+
if (!orgId || !trimmed) return;
|
|
68
|
+
setNotListed(false);
|
|
69
|
+
if (await run.start({
|
|
70
|
+
orgId,
|
|
71
|
+
hostId,
|
|
72
|
+
kind: 'workflow',
|
|
73
|
+
brief: trimmed,
|
|
74
|
+
inputs: {
|
|
75
|
+
mode: 'revise',
|
|
76
|
+
targetType: 'action',
|
|
77
|
+
targetId: target.id
|
|
78
|
+
}
|
|
79
|
+
})) {
|
|
80
|
+
setBrief('');
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const review = ()=>{
|
|
84
|
+
if (!draft) return;
|
|
85
|
+
if (!(openAction == null ? void 0 : openAction(draft.id))) setNotListed(true);
|
|
86
|
+
};
|
|
87
|
+
return /*#__PURE__*/ _jsx(Box, {
|
|
88
|
+
sx: {
|
|
89
|
+
border: 1,
|
|
90
|
+
borderColor: 'divider',
|
|
91
|
+
borderRadius: 1,
|
|
92
|
+
p: 1.5
|
|
93
|
+
},
|
|
94
|
+
"aria-label": "Change this automation with AI",
|
|
95
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
96
|
+
spacing: 1,
|
|
97
|
+
children: [
|
|
98
|
+
/*#__PURE__*/ _jsxs(Typography, {
|
|
99
|
+
variant: "body2",
|
|
100
|
+
color: "text.secondary",
|
|
101
|
+
children: [
|
|
102
|
+
copy.intro,
|
|
103
|
+
' ',
|
|
104
|
+
/*#__PURE__*/ _jsx(Link, {
|
|
105
|
+
href: help.href,
|
|
106
|
+
target: "_blank",
|
|
107
|
+
rel: "noopener",
|
|
108
|
+
title: help.excerpt,
|
|
109
|
+
children: 'How it works'
|
|
110
|
+
})
|
|
111
|
+
]
|
|
112
|
+
}),
|
|
113
|
+
/*#__PURE__*/ _jsx(TextField, {
|
|
114
|
+
size: "small",
|
|
115
|
+
label: copy.label,
|
|
116
|
+
placeholder: copy.placeholder,
|
|
117
|
+
value: brief,
|
|
118
|
+
multiline: true,
|
|
119
|
+
maxRows: 4,
|
|
120
|
+
onChange: (event)=>setBrief(event.target.value.slice(0, BRIEF_MAX_CHARS)),
|
|
121
|
+
disabled: busy
|
|
122
|
+
}),
|
|
123
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
124
|
+
direction: "row",
|
|
125
|
+
spacing: 1,
|
|
126
|
+
children: [
|
|
127
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
128
|
+
size: "small",
|
|
129
|
+
variant: "outlined",
|
|
130
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
131
|
+
path: mdiCreation.path
|
|
132
|
+
}),
|
|
133
|
+
disabled: busy || !orgId || !brief.trim(),
|
|
134
|
+
onClick: ()=>void start(brief),
|
|
135
|
+
children: copy.change
|
|
136
|
+
}),
|
|
137
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
138
|
+
size: "small",
|
|
139
|
+
variant: "text",
|
|
140
|
+
startIcon: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
141
|
+
path: mdiCreation.path
|
|
142
|
+
}),
|
|
143
|
+
disabled: busy || !orgId,
|
|
144
|
+
onClick: ()=>void start(copy.fixBrief(target.name)),
|
|
145
|
+
children: copy.fix
|
|
146
|
+
})
|
|
147
|
+
]
|
|
148
|
+
}),
|
|
149
|
+
run.running && job ? /*#__PURE__*/ _jsx(Alert, {
|
|
150
|
+
severity: "info",
|
|
151
|
+
icon: /*#__PURE__*/ _jsx(CircularProgress, {
|
|
152
|
+
size: 18,
|
|
153
|
+
"aria-label": "Drafting"
|
|
154
|
+
}),
|
|
155
|
+
action: /*#__PURE__*/ _jsx(Button, {
|
|
156
|
+
color: "inherit",
|
|
157
|
+
size: "small",
|
|
158
|
+
variant: "outlined",
|
|
159
|
+
onClick: ()=>openAiJobs({
|
|
160
|
+
jobId: job.id
|
|
161
|
+
}),
|
|
162
|
+
children: 'Open AI jobs'
|
|
163
|
+
}),
|
|
164
|
+
children: copy.running
|
|
165
|
+
}) : null,
|
|
166
|
+
draft ? /*#__PURE__*/ _jsxs(Alert, {
|
|
167
|
+
severity: "success",
|
|
168
|
+
action: openAction ? /*#__PURE__*/ _jsx(Button, {
|
|
169
|
+
color: "inherit",
|
|
170
|
+
size: "small",
|
|
171
|
+
variant: "outlined",
|
|
172
|
+
onClick: review,
|
|
173
|
+
children: copy.review
|
|
174
|
+
}) : undefined,
|
|
175
|
+
children: [
|
|
176
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
177
|
+
variant: "body2",
|
|
178
|
+
sx: {
|
|
179
|
+
fontWeight: 600
|
|
180
|
+
},
|
|
181
|
+
children: `${copy.drafted}: ${draft.label}`
|
|
182
|
+
}),
|
|
183
|
+
draft.note ? /*#__PURE__*/ _jsx(Typography, {
|
|
184
|
+
variant: "body2",
|
|
185
|
+
children: draft.note
|
|
186
|
+
}) : null
|
|
187
|
+
]
|
|
188
|
+
}) : null,
|
|
189
|
+
problem ? /*#__PURE__*/ _jsx(Alert, {
|
|
190
|
+
severity: (job == null ? void 0 : job.status) === 'failed' ? 'error' : 'warning',
|
|
191
|
+
children: problem
|
|
192
|
+
}) : null,
|
|
193
|
+
run.notice ? /*#__PURE__*/ _jsx(Alert, {
|
|
194
|
+
severity: "warning",
|
|
195
|
+
children: run.notice
|
|
196
|
+
}) : null,
|
|
197
|
+
notListed ? /*#__PURE__*/ _jsx(Alert, {
|
|
198
|
+
severity: "info",
|
|
199
|
+
children: copy.notListed
|
|
200
|
+
}) : null
|
|
201
|
+
]
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
export default AiReviseAutomation;
|
|
206
|
+
|
|
207
|
+
//# sourceMappingURL=ai-revise-automation.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-revise-automation.component.tsx"],"sourcesContent":["'use client'\n\n/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { pluginDocsHelp } from '@aglyn/aglyn/app-utils/docs-help'\nimport { mdiCreation } from '@aglyn/shared-data-mdi'\nimport { MdiIcon } from '@aglyn/shared-ui-jsx'\nimport { useUser } from '@aglyn/tenant-feature-instance'\nimport {\n Alert,\n Box,\n Button,\n CircularProgress,\n Link,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { useState } from 'react'\nimport { openAiJobs } from './ai-jobs-store'\nimport type { ConsoleAutomationEditorZoneProps } from './ai-automation-zones'\nimport { aiJobProblem, useAiJobRun } from './use-ai-job-run'\n\n/**\n * \"Fix with AI\" and \"Change with AI\" in the editor of a saved ACTION\n * (AGL-3603), through the `automationEditor` zone. Each starts a `workflow`\n * job in `revise` mode: the action as it is saved, and the change asked of\n * it, become a NEW automation drafted switched off. The saved action is never\n * written; the person opens the copy, reads what changed, and switches it on\n * in place of the old one when it is right.\n *\n * A workflow of function calls is not offered either: the draft writer writes\n * actions, and a workflow is explained rather than revised.\n */\n\n/** The longest change a job admits as its brief. */\nconst BRIEF_MAX_CHARS = 4_000\n\nexport const AI_AUTOMATION_REVISE_COPY = {\n intro: 'Describe a change, or let AI fix what would stop it working. You get a changed copy, switched off, to review — this one is left as it is.',\n label: 'What should change?',\n placeholder: 'Also tag them “newsletter”, and wait a day before the email',\n change: 'Change with AI',\n fix: 'Fix with AI',\n running: 'Drafting the changed copy. This can take a few minutes.',\n drafted: 'Changed copy drafted',\n review: 'Review the copy',\n notListed: 'The copy is saved. It appears in the list in a moment.',\n failed: 'The automation could not be changed. Try again.',\n fixBrief: (name: string) =>\n `Fix whatever in “${name}” would stop it working as intended — a record the site no longer has, a condition that can never match, a step in the wrong order. Change nothing else.`,\n} as const\n\nexport function AiReviseAutomation({ hostId, orgId, target, openAction }: ConsoleAutomationEditorZoneProps) {\n const copy = AI_AUTOMATION_REVISE_COPY\n const help = pluginDocsHelp('aiAutomations', { anchor: '#change' })\n const { data: user } = useUser()\n const run = useAiJobRun(user, copy.failed)\n const [brief, setBrief] = useState('')\n const [notListed, setNotListed] = useState(false)\n\n if (target.type !== 'action') return null\n const { job } = run\n const busy = run.starting || run.running\n const draft = job?.status === 'done' ? job.outputs.find((output) => output.resource === 'workflow') : undefined\n const problem = aiJobProblem(job, copy.failed) ?? (job?.status === 'done' && !draft ? copy.failed : null)\n\n const start = async (text: string) => {\n const trimmed = text.trim()\n if (!orgId || !trimmed) return\n setNotListed(false)\n if (\n await run.start({\n orgId,\n hostId,\n kind: 'workflow',\n brief: trimmed,\n inputs: { mode: 'revise', targetType: 'action', targetId: target.id },\n })\n ) {\n setBrief('')\n }\n }\n\n const review = () => {\n if (!draft) return\n if (!openAction?.(draft.id)) setNotListed(true)\n }\n\n return (\n <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 1, p: 1.5 }} aria-label=\"Change this automation with AI\">\n <Stack spacing={1}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {copy.intro}{' '}\n <Link href={help.href} target=\"_blank\" rel=\"noopener\" title={help.excerpt}>\n {'How it works'}\n </Link>\n </Typography>\n <TextField\n size=\"small\"\n label={copy.label}\n placeholder={copy.placeholder}\n value={brief}\n multiline\n maxRows={4}\n onChange={(event) => setBrief(event.target.value.slice(0, BRIEF_MAX_CHARS))}\n disabled={busy}\n />\n <Stack direction=\"row\" spacing={1}>\n <Button\n size=\"small\"\n variant=\"outlined\"\n startIcon={<MdiIcon path={mdiCreation.path} />}\n disabled={busy || !orgId || !brief.trim()}\n onClick={() => void start(brief)}\n >\n {copy.change}\n </Button>\n <Button\n size=\"small\"\n variant=\"text\"\n startIcon={<MdiIcon path={mdiCreation.path} />}\n disabled={busy || !orgId}\n onClick={() => void start(copy.fixBrief(target.name))}\n >\n {copy.fix}\n </Button>\n </Stack>\n {run.running && job ? (\n <Alert\n severity=\"info\"\n icon={<CircularProgress size={18} aria-label=\"Drafting\" />}\n action={\n <Button color=\"inherit\" size=\"small\" variant=\"outlined\" onClick={() => openAiJobs({ jobId: job.id })}>\n {'Open AI jobs'}\n </Button>\n }\n >\n {copy.running}\n </Alert>\n ) : null}\n {draft ? (\n <Alert\n severity=\"success\"\n action={\n openAction ? (\n <Button color=\"inherit\" size=\"small\" variant=\"outlined\" onClick={review}>\n {copy.review}\n </Button>\n ) : undefined\n }\n >\n <Typography variant=\"body2\" sx={{ fontWeight: 600 }}>\n {`${copy.drafted}: ${draft.label}`}\n </Typography>\n {draft.note ? <Typography variant=\"body2\">{draft.note}</Typography> : null}\n </Alert>\n ) : null}\n {problem ? <Alert severity={job?.status === 'failed' ? 'error' : 'warning'}>{problem}</Alert> : null}\n {run.notice ? <Alert severity=\"warning\">{run.notice}</Alert> : null}\n {notListed ? <Alert severity=\"info\">{copy.notListed}</Alert> : null}\n </Stack>\n </Box>\n )\n}\n\nexport default AiReviseAutomation\n"],"names":["pluginDocsHelp","mdiCreation","MdiIcon","useUser","Alert","Box","Button","CircularProgress","Link","Stack","TextField","Typography","useState","openAiJobs","aiJobProblem","useAiJobRun","BRIEF_MAX_CHARS","AI_AUTOMATION_REVISE_COPY","intro","label","placeholder","change","fix","running","drafted","review","notListed","failed","fixBrief","name","AiReviseAutomation","hostId","orgId","target","openAction","copy","help","anchor","data","user","run","brief","setBrief","setNotListed","type","job","busy","starting","draft","status","outputs","find","output","resource","undefined","problem","start","text","trimmed","trim","kind","inputs","mode","targetType","targetId","id","sx","border","borderColor","borderRadius","p","aria-label","spacing","variant","color","href","rel","title","excerpt","size","value","multiline","maxRows","onChange","event","slice","disabled","direction","startIcon","path","onClick","severity","icon","action","jobId","fontWeight","note","notice"],"mappings":"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"}
|
|
@@ -17,18 +17,20 @@
|
|
|
17
17
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
18
|
import { PLATFORM_BRAND_NAME } from "@aglyn/aglyn";
|
|
19
19
|
import { PageHeaderRecord } from "@aglyn/aglyn/app-utils/page-header-record-context";
|
|
20
|
-
import { mdiAlertCircle, mdiCheckCircle, mdiChevronDown, mdiClockOutline } from "@aglyn/shared-data-mdi";
|
|
20
|
+
import { mdiAlertCircle, mdiCheckCircle, mdiChevronDown, mdiClockOutline, mdiMinusCircleOutline } from "@aglyn/shared-data-mdi";
|
|
21
21
|
import { AppLink, MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
22
22
|
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
23
23
|
import { Accordion, AccordionDetails, AccordionSummary, Alert, Box, Button, Card, CircularProgress, Container, LinearProgress, Stack, Typography } from "@mui/material";
|
|
24
24
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
25
|
-
import { aiJobPageCopy, aiSiteBuildCreditsLine, aiSiteBuildPhase, aiSiteBuildRows } from "../model/ai-site-build-progress.js";
|
|
25
|
+
import { aiJobPageCopy, aiSiteBuildCreditsLine, aiSiteBuildFraction, aiSiteBuildPhase, aiSiteBuildRows } from "../model/ai-site-build-progress.js";
|
|
26
26
|
import { aiJobRefundCopy, aiSiteStarterFallbackOffered } from "../model/ai-job-failure-copy.js";
|
|
27
27
|
import { aiSiteStartAnswersFromInputs } from "../model/ai-site-start.js";
|
|
28
28
|
import { AiSiteStartCard } from "./ai-site-start-card.component.js";
|
|
29
29
|
import { AI_JOB_TERMINAL_STATUSES } from "../model/ai-jobs.types.js";
|
|
30
30
|
import { followAiJobEvents } from "./ai-job-events.js";
|
|
31
31
|
import { aiSiteBuildDoneLinks } from "./ai-job-links.js";
|
|
32
|
+
import { AiJobPlan } from "./ai-job-plan.component.js";
|
|
33
|
+
import { aiBuildCanRetry } from "../model/ai-build-progress.js";
|
|
32
34
|
import { resumeAiJobRequest } from "./ai-job-requests.js";
|
|
33
35
|
import { useAiJobSite } from "./ai-job-site.js";
|
|
34
36
|
import { AiSiteStarterFallback } from "./ai-site-starter-fallback.component.js";
|
|
@@ -113,6 +115,11 @@ const ROW_ICON = {
|
|
|
113
115
|
path: mdiAlertCircle.path,
|
|
114
116
|
color: 'error.main',
|
|
115
117
|
label: 'Stopped'
|
|
118
|
+
},
|
|
119
|
+
skipped: {
|
|
120
|
+
path: mdiMinusCircleOutline.path,
|
|
121
|
+
color: 'text.disabled',
|
|
122
|
+
label: 'Not built'
|
|
116
123
|
}
|
|
117
124
|
};
|
|
118
125
|
function RowIcon({ state }) {
|
|
@@ -138,7 +145,30 @@ function RowIcon({ state }) {
|
|
|
138
145
|
})
|
|
139
146
|
});
|
|
140
147
|
}
|
|
141
|
-
/** The page's frame: the site's name over the heading and its sentence. */
|
|
148
|
+
/** The page's frame: the site's name over the heading and its sentence. */ /** "0:42", "3:05": how long the active row has been running, from when it started or was first seen. */ function useElapsed(key, startedAt) {
|
|
149
|
+
const [now, setNow] = useState(()=>Date.now());
|
|
150
|
+
const seen = useRef({
|
|
151
|
+
key: null,
|
|
152
|
+
at: Date.now()
|
|
153
|
+
});
|
|
154
|
+
if (seen.current.key !== key) seen.current = {
|
|
155
|
+
key,
|
|
156
|
+
at: Date.now()
|
|
157
|
+
};
|
|
158
|
+
useEffect(()=>{
|
|
159
|
+
if (!key) return;
|
|
160
|
+
const timer = setInterval(()=>setNow(Date.now()), 1000);
|
|
161
|
+
return ()=>clearInterval(timer);
|
|
162
|
+
}, [
|
|
163
|
+
key
|
|
164
|
+
]);
|
|
165
|
+
if (!key) return null;
|
|
166
|
+
const started = startedAt ? Date.parse(startedAt) : NaN;
|
|
167
|
+
const from = Number.isFinite(started) ? Math.min(started, seen.current.at) : seen.current.at;
|
|
168
|
+
const seconds = Math.max(0, Math.floor((now - from) / 1000));
|
|
169
|
+
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, '0')}`;
|
|
170
|
+
}
|
|
171
|
+
function Frame({ siteName, heading, lede, children }) {
|
|
142
172
|
return /*#__PURE__*/ _jsx(Container, {
|
|
143
173
|
maxWidth: "sm",
|
|
144
174
|
sx: {
|
|
@@ -180,8 +210,8 @@ function RowIcon({ state }) {
|
|
|
180
210
|
});
|
|
181
211
|
}
|
|
182
212
|
export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
183
|
-
var _split_, _ready_sitePublish, _ready_refundedCredits;
|
|
184
|
-
var _ready_review, _ready_review1;
|
|
213
|
+
var _split_, _aiSiteBuildRows_find, _rows_find, _ready_sitePublish, _ready_refundedCredits;
|
|
214
|
+
var _ready_review, _ready_review1, _ready_review2;
|
|
185
215
|
const { data: user } = useUser();
|
|
186
216
|
const jobId = (segments == null ? void 0 : segments[0]) ? decodeURIComponent(String(segments[0])) : null;
|
|
187
217
|
const orgSlug = (_split_ = (basePath != null ? basePath : '').split('/')[1]) != null ? _split_ : '';
|
|
@@ -200,7 +230,10 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
200
230
|
if (!orgId || !job || typeof job !== 'object') return;
|
|
201
231
|
setBusy(true);
|
|
202
232
|
setNotice(null);
|
|
203
|
-
|
|
233
|
+
// A finished build tries again only what failed (AGL-3616).
|
|
234
|
+
const decision = await resumeAiJobRequest(user, orgId, job, aiBuildCanRetry(job) ? {
|
|
235
|
+
retry: 'failed-items'
|
|
236
|
+
} : {});
|
|
204
237
|
if (decision.job) setJob(decision.job);
|
|
205
238
|
if (decision.error) setNotice(decision.error);
|
|
206
239
|
setBusy(false);
|
|
@@ -210,8 +243,24 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
210
243
|
user,
|
|
211
244
|
setJob
|
|
212
245
|
]);
|
|
246
|
+
const confirmPlan = useCallback(async (target, options = {})=>{
|
|
247
|
+
if (!orgId) return;
|
|
248
|
+
setBusy(true);
|
|
249
|
+
setNotice(null);
|
|
250
|
+
const decision = await resumeAiJobRequest(user, orgId, target, options);
|
|
251
|
+
if (decision.job) setJob(decision.job);
|
|
252
|
+
if (decision.error) setNotice(decision.error);
|
|
253
|
+
setBusy(false);
|
|
254
|
+
}, [
|
|
255
|
+
orgId,
|
|
256
|
+
user,
|
|
257
|
+
setJob
|
|
258
|
+
]);
|
|
213
259
|
const ready = job && typeof job === 'object' ? job : null;
|
|
214
260
|
const copy = ready ? aiJobPageCopy(ready, PLATFORM_BRAND_NAME) : null;
|
|
261
|
+
// The active row's running time, read before any early return (a hook).
|
|
262
|
+
const liveRow = ready && aiSiteBuildPhase(ready) === 'working' ? (_aiSiteBuildRows_find = aiSiteBuildRows(ready).find((row)=>row.state === 'active')) != null ? _aiSiteBuildRows_find : null : null;
|
|
263
|
+
const elapsed = useElapsed(liveRow ? `${ready == null ? void 0 : ready.id}:${liveRow.id}` : null, liveRow == null ? void 0 : liveRow.startedAt);
|
|
215
264
|
// The shell's header names the job's page as the page does, and its trail
|
|
216
265
|
// walks back to the site's AI jobs.
|
|
217
266
|
const record = /*#__PURE__*/ _jsx(PageHeaderRecord, {
|
|
@@ -279,6 +328,8 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
279
328
|
}
|
|
280
329
|
const phase = aiSiteBuildPhase(ready);
|
|
281
330
|
const rows = aiSiteBuildRows(ready);
|
|
331
|
+
const fraction = aiSiteBuildFraction(rows);
|
|
332
|
+
const activeRow = phase === 'working' ? (_rows_find = rows.find((row)=>row.state === 'active')) != null ? _rows_find : null : null;
|
|
282
333
|
const credits = aiSiteBuildCreditsLine(ready);
|
|
283
334
|
const links = phase === 'done' ? aiSiteBuildDoneLinks(ready, orgSlug) : {
|
|
284
335
|
view: null,
|
|
@@ -287,7 +338,9 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
287
338
|
const sitePublish = ready.kind === 'site' && phase === 'done' ? (_ready_sitePublish = ready.sitePublish) != null ? _ready_sitePublish : null : null;
|
|
288
339
|
const liveUrl = sitePublish && sitePublish.published.length > 0 ? sitePublish.liveUrl : null;
|
|
289
340
|
const retryRefusal = (_ready_review = ready.review) == null ? void 0 : _ready_review.retryRefusal;
|
|
290
|
-
const
|
|
341
|
+
const buildRetry = aiBuildCanRetry(ready);
|
|
342
|
+
const canRetry = phase === 'stopped' && ((_ready_review1 = ready.review) == null ? void 0 : _ready_review1.reason) === 'doctrine' || buildRetry;
|
|
343
|
+
const buildPlanWaiting = ready.kind === 'build' && phase === 'stopped' && ((_ready_review2 = ready.review) == null ? void 0 : _ready_review2.reason) === 'plan';
|
|
291
344
|
// A guided start that ended without building its site starts over from its
|
|
292
345
|
// own answers, as a fresh job: the questions reopen filled in.
|
|
293
346
|
const restartAnswers = ready.kind === 'site' && (phase === 'failed' || phase === 'canceled') ? aiSiteStartAnswersFromInputs(ready.siteInputs) : null;
|
|
@@ -308,9 +361,13 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
308
361
|
borderRadius: 2
|
|
309
362
|
},
|
|
310
363
|
children: [
|
|
311
|
-
phase === 'working' && /*#__PURE__*/ _jsx(LinearProgress, {
|
|
364
|
+
phase === 'working' && (fraction !== null ? /*#__PURE__*/ _jsx(LinearProgress, {
|
|
365
|
+
variant: "determinate",
|
|
366
|
+
value: Math.round(fraction * 100),
|
|
367
|
+
"aria-label": `Building: ${rows.filter((row)=>row.state === 'done').length} of ${rows.length} steps done`
|
|
368
|
+
}) : /*#__PURE__*/ _jsx(LinearProgress, {
|
|
312
369
|
"aria-label": "Building"
|
|
313
|
-
}),
|
|
370
|
+
})),
|
|
314
371
|
/*#__PURE__*/ _jsx(Box, {
|
|
315
372
|
component: "ol",
|
|
316
373
|
"aria-label": "Progress",
|
|
@@ -324,12 +381,14 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
324
381
|
},
|
|
325
382
|
children: /*#__PURE__*/ _jsx(Stack, {
|
|
326
383
|
spacing: 2,
|
|
327
|
-
children: rows.map((row)
|
|
384
|
+
children: rows.map((row)=>{
|
|
385
|
+
var _row_sections;
|
|
386
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
328
387
|
component: "li",
|
|
329
388
|
direction: "row",
|
|
330
389
|
spacing: 2,
|
|
331
390
|
sx: {
|
|
332
|
-
alignItems: '
|
|
391
|
+
alignItems: 'flex-start'
|
|
333
392
|
},
|
|
334
393
|
children: [
|
|
335
394
|
/*#__PURE__*/ _jsx(Box, {
|
|
@@ -342,13 +401,62 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
342
401
|
state: row.state
|
|
343
402
|
})
|
|
344
403
|
}),
|
|
345
|
-
/*#__PURE__*/
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
404
|
+
/*#__PURE__*/ _jsxs(Box, {
|
|
405
|
+
sx: {
|
|
406
|
+
flex: 1,
|
|
407
|
+
minWidth: 0
|
|
408
|
+
},
|
|
409
|
+
children: [
|
|
410
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
411
|
+
direction: "row",
|
|
412
|
+
spacing: 1,
|
|
413
|
+
sx: {
|
|
414
|
+
alignItems: 'baseline',
|
|
415
|
+
justifyContent: 'space-between'
|
|
416
|
+
},
|
|
417
|
+
children: [
|
|
418
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
419
|
+
variant: "body1",
|
|
420
|
+
color: row.state === 'waiting' || row.state === 'skipped' ? 'text.secondary' : 'text.primary',
|
|
421
|
+
children: row.label
|
|
422
|
+
}),
|
|
423
|
+
row.id === (activeRow == null ? void 0 : activeRow.id) && elapsed ? /*#__PURE__*/ _jsx(Typography, {
|
|
424
|
+
variant: "body2",
|
|
425
|
+
color: "text.secondary",
|
|
426
|
+
sx: {
|
|
427
|
+
fontVariantNumeric: 'tabular-nums'
|
|
428
|
+
},
|
|
429
|
+
children: elapsed
|
|
430
|
+
}) : typeof row.credits === 'number' && row.credits > 0 ? /*#__PURE__*/ _jsx(Typography, {
|
|
431
|
+
variant: "body2",
|
|
432
|
+
color: "text.secondary",
|
|
433
|
+
sx: {
|
|
434
|
+
whiteSpace: 'nowrap'
|
|
435
|
+
},
|
|
436
|
+
children: `${row.credits} ${row.credits === 1 ? 'credit' : 'credits'}`
|
|
437
|
+
}) : null
|
|
438
|
+
]
|
|
439
|
+
}),
|
|
440
|
+
row.id === (activeRow == null ? void 0 : activeRow.id) && row.hint ? /*#__PURE__*/ _jsx(Typography, {
|
|
441
|
+
variant: "body2",
|
|
442
|
+
color: "text.secondary",
|
|
443
|
+
children: row.hint
|
|
444
|
+
}) : null,
|
|
445
|
+
((_row_sections = row.sections) == null ? void 0 : _row_sections.length) && (row.state === 'active' || row.state === 'done') ? /*#__PURE__*/ _jsx(Typography, {
|
|
446
|
+
variant: "body2",
|
|
447
|
+
color: "text.secondary",
|
|
448
|
+
children: `${row.state === 'active' ? 'Writing' : 'Wrote'}: ${row.sections.join(', ')}`
|
|
449
|
+
}) : null,
|
|
450
|
+
row.detail ? /*#__PURE__*/ _jsx(Typography, {
|
|
451
|
+
variant: "body2",
|
|
452
|
+
color: "text.secondary",
|
|
453
|
+
children: row.detail
|
|
454
|
+
}) : null
|
|
455
|
+
]
|
|
349
456
|
})
|
|
350
457
|
]
|
|
351
|
-
}, row.id)
|
|
458
|
+
}, row.id);
|
|
459
|
+
})
|
|
352
460
|
})
|
|
353
461
|
})
|
|
354
462
|
]
|
|
@@ -370,6 +478,12 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
370
478
|
startBlank: ()=>setRetrying(false),
|
|
371
479
|
leave: ()=>setRetrying(false)
|
|
372
480
|
}) : null,
|
|
481
|
+
buildPlanWaiting ? // A build's plan, confirmed here as in the chat (AGL-3616).
|
|
482
|
+
/*#__PURE__*/ _jsx(AiJobPlan, {
|
|
483
|
+
job: ready,
|
|
484
|
+
busy: busy,
|
|
485
|
+
onResume: (target, options)=>void confirmPlan(target, options)
|
|
486
|
+
}) : null,
|
|
373
487
|
sitePublish && sitePublish.drafts.length > 0 && // The pages the publish left as drafts, each with its plain reason;
|
|
374
488
|
// Edit your pages is where they are fixed and published.
|
|
375
489
|
/*#__PURE__*/ _jsxs(Alert, {
|
|
@@ -404,6 +518,14 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
404
518
|
})
|
|
405
519
|
]
|
|
406
520
|
}),
|
|
521
|
+
phase === 'done' && buildRetry && /*#__PURE__*/ _jsx(Box, {
|
|
522
|
+
children: /*#__PURE__*/ _jsx(Button, {
|
|
523
|
+
variant: "outlined",
|
|
524
|
+
disabled: busy,
|
|
525
|
+
onClick: ()=>void tryAgain(),
|
|
526
|
+
children: 'Try again what failed'
|
|
527
|
+
})
|
|
528
|
+
}),
|
|
407
529
|
phase === 'done' && /*#__PURE__*/ _jsxs(Stack, {
|
|
408
530
|
direction: {
|
|
409
531
|
xs: 'column',
|
|
@@ -476,6 +598,8 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
476
598
|
]
|
|
477
599
|
}),
|
|
478
600
|
ready.plan && ready.plan.screens.length > 0 && /*#__PURE__*/ _jsxs(Accordion, {
|
|
601
|
+
// Open while the site is built, so the plan is in view as each part of it is written.
|
|
602
|
+
defaultExpanded: phase === 'working',
|
|
479
603
|
variant: "outlined",
|
|
480
604
|
disableGutters: true,
|
|
481
605
|
sx: {
|