@aglyn/plugins-ai 1.0.0-beta.228 → 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-jobs-list-page.component.js +12 -1
- package/src/lib/components/ai-jobs-list-page.component.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.d.ts +1 -1
- package/src/lib/components/ai-site-build-page.component.js +177 -20
- package/src/lib/components/ai-site-build-page.component.js.map +1 -1
- package/src/lib/components/ai-site-start-card.component.d.ts +10 -1
- package/src/lib/components/ai-site-start-card.component.js +7 -4
- package/src/lib/components/ai-site-start-card.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.d.ts +11 -0
- package/src/lib/components/assist-jobs-drawer.component.js +85 -4
- 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-layout-site-pages.d.ts +70 -0
- package/src/lib/jobs/ai-job-layout-site-pages.js +216 -0
- package/src/lib/jobs/ai-job-layout-site-pages.js.map +1 -0
- package/src/lib/jobs/ai-job-layout-step.d.ts +2 -2
- package/src/lib/jobs/ai-job-layout-step.js +19 -1
- package/src/lib/jobs/ai-job-layout-step.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 +207 -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 +90 -2
- package/src/lib/jobs/ai-jobs.js +495 -61
- 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-job-failure-copy.d.ts +20 -1
- package/src/lib/model/ai-job-failure-copy.js +28 -1
- package/src/lib/model/ai-job-failure-copy.js.map +1 -1
- package/src/lib/model/ai-job-notice.d.ts +3 -0
- package/src/lib/model/ai-job-notice.js +11 -2
- package/src/lib/model/ai-job-notice.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +87 -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 +28 -3
- package/src/lib/model/ai-site-build-progress.js +231 -17
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-site-start-seo.d.ts +16 -0
- package/src/lib/model/ai-site-start-seo.js +54 -4
- package/src/lib/model/ai-site-start-seo.js.map +1 -1
- package/src/lib/model/ai-site-start.d.ts +14 -0
- package/src/lib/model/ai-site-start.js +43 -0
- package/src/lib/model/ai-site-start.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.d.ts +6 -0
- package/src/lib/runtime/ai-doctrine.js +16 -6
- 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 +31 -3
- package/src/lib/usage/assist-job-refund.js +46 -10
- 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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"}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import type { ConsolePluginPageProps } from '@aglyn/aglyn/plugin-manager/feature-plugins';
|
|
18
18
|
import type { MaybeTokenSource } from '@aglyn/shared-util-http/authorized-token';
|
|
19
|
-
import type
|
|
19
|
+
import { type AiJobSummary } from '../model/ai-jobs.types';
|
|
20
20
|
/**
|
|
21
21
|
* "Building your site" (AGL-3594): one job's page, at `/ai-jobs/{jobId}`
|
|
22
22
|
* under its site — where the guided start sends a person the moment they
|
|
@@ -17,15 +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";
|
|
26
|
-
import { aiSiteStarterFallbackOffered } from "../model/ai-job-failure-copy.js";
|
|
25
|
+
import { aiJobPageCopy, aiSiteBuildCreditsLine, aiSiteBuildFraction, aiSiteBuildPhase, aiSiteBuildRows } from "../model/ai-site-build-progress.js";
|
|
26
|
+
import { aiJobRefundCopy, aiSiteStarterFallbackOffered } from "../model/ai-job-failure-copy.js";
|
|
27
|
+
import { aiSiteStartAnswersFromInputs } from "../model/ai-site-start.js";
|
|
28
|
+
import { AiSiteStartCard } from "./ai-site-start-card.component.js";
|
|
29
|
+
import { AI_JOB_TERMINAL_STATUSES } from "../model/ai-jobs.types.js";
|
|
27
30
|
import { followAiJobEvents } from "./ai-job-events.js";
|
|
28
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";
|
|
29
34
|
import { resumeAiJobRequest } from "./ai-job-requests.js";
|
|
30
35
|
import { useAiJobSite } from "./ai-job-site.js";
|
|
31
36
|
import { AiSiteStarterFallback } from "./ai-site-starter-fallback.component.js";
|
|
@@ -55,7 +60,11 @@ import { AiSiteStarterFallback } from "./ai-site-starter-fallback.component.js";
|
|
|
55
60
|
const [job, setJob] = useState(null);
|
|
56
61
|
const [attempt, setAttempt] = useState(0);
|
|
57
62
|
const status = job && typeof job === 'object' ? job.status : null;
|
|
58
|
-
|
|
63
|
+
// Followed until the job ENDS (AGL-3596), not until it first stops: a guided
|
|
64
|
+
// start parks on its plan for the instant it takes to confirm it, and a page
|
|
65
|
+
// that stopped following there showed that park — the plan's 13 credits and
|
|
66
|
+
// "the plan is ready" — after the job had built, spent and failed.
|
|
67
|
+
const moving = status === null || !AI_JOB_TERMINAL_STATUSES.includes(status);
|
|
59
68
|
useEffect(()=>{
|
|
60
69
|
if (!orgId || !jobId || !moving) return undefined;
|
|
61
70
|
const controller = new AbortController();
|
|
@@ -106,6 +115,11 @@ const ROW_ICON = {
|
|
|
106
115
|
path: mdiAlertCircle.path,
|
|
107
116
|
color: 'error.main',
|
|
108
117
|
label: 'Stopped'
|
|
118
|
+
},
|
|
119
|
+
skipped: {
|
|
120
|
+
path: mdiMinusCircleOutline.path,
|
|
121
|
+
color: 'text.disabled',
|
|
122
|
+
label: 'Not built'
|
|
109
123
|
}
|
|
110
124
|
};
|
|
111
125
|
function RowIcon({ state }) {
|
|
@@ -131,7 +145,30 @@ function RowIcon({ state }) {
|
|
|
131
145
|
})
|
|
132
146
|
});
|
|
133
147
|
}
|
|
134
|
-
/** 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 }) {
|
|
135
172
|
return /*#__PURE__*/ _jsx(Container, {
|
|
136
173
|
maxWidth: "sm",
|
|
137
174
|
sx: {
|
|
@@ -173,22 +210,30 @@ function RowIcon({ state }) {
|
|
|
173
210
|
});
|
|
174
211
|
}
|
|
175
212
|
export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
176
|
-
var _split_, _ready_sitePublish;
|
|
177
|
-
var _ready_review, _ready_review1;
|
|
213
|
+
var _split_, _aiSiteBuildRows_find, _rows_find, _ready_sitePublish, _ready_refundedCredits;
|
|
214
|
+
var _ready_review, _ready_review1, _ready_review2;
|
|
178
215
|
const { data: user } = useUser();
|
|
179
216
|
const jobId = (segments == null ? void 0 : segments[0]) ? decodeURIComponent(String(segments[0])) : null;
|
|
180
217
|
const orgSlug = (_split_ = (basePath != null ? basePath : '').split('/')[1]) != null ? _split_ : '';
|
|
218
|
+
// `/{orgSlug}/hosts/{subdomain}/ai-jobs`: the site's subdomain, which a console URL names it by.
|
|
219
|
+
const hostSubdomain = (basePath != null ? basePath : '').split('/')[3] || null;
|
|
181
220
|
const site = useAiJobSite(hostId);
|
|
182
221
|
const orgId = site.status === 'ready' ? site.orgId : null;
|
|
183
222
|
const siteName = site.status === 'ready' ? site.name : undefined;
|
|
184
223
|
const [job, setJob, retry] = useAiJobById(user, orgId, jobId);
|
|
185
224
|
const [busy, setBusy] = useState(false);
|
|
186
225
|
const [notice, setNotice] = useState(null);
|
|
226
|
+
// A failed guided start's Try again reopens its questions, filled in (AGL-3596);
|
|
227
|
+
// `?retry=1` — what the AI jobs drawer links — opens them on arrival.
|
|
228
|
+
const [retrying, setRetrying] = useState(()=>typeof window !== 'undefined' && new URLSearchParams(window.location.search).get('retry') === '1');
|
|
187
229
|
const tryAgain = useCallback(async ()=>{
|
|
188
230
|
if (!orgId || !job || typeof job !== 'object') return;
|
|
189
231
|
setBusy(true);
|
|
190
232
|
setNotice(null);
|
|
191
|
-
|
|
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
|
+
} : {});
|
|
192
237
|
if (decision.job) setJob(decision.job);
|
|
193
238
|
if (decision.error) setNotice(decision.error);
|
|
194
239
|
setBusy(false);
|
|
@@ -198,8 +243,24 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
198
243
|
user,
|
|
199
244
|
setJob
|
|
200
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
|
+
]);
|
|
201
259
|
const ready = job && typeof job === 'object' ? job : null;
|
|
202
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);
|
|
203
264
|
// The shell's header names the job's page as the page does, and its trail
|
|
204
265
|
// walks back to the site's AI jobs.
|
|
205
266
|
const record = /*#__PURE__*/ _jsx(PageHeaderRecord, {
|
|
@@ -267,6 +328,8 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
267
328
|
}
|
|
268
329
|
const phase = aiSiteBuildPhase(ready);
|
|
269
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;
|
|
270
333
|
const credits = aiSiteBuildCreditsLine(ready);
|
|
271
334
|
const links = phase === 'done' ? aiSiteBuildDoneLinks(ready, orgSlug) : {
|
|
272
335
|
view: null,
|
|
@@ -275,7 +338,13 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
275
338
|
const sitePublish = ready.kind === 'site' && phase === 'done' ? (_ready_sitePublish = ready.sitePublish) != null ? _ready_sitePublish : null : null;
|
|
276
339
|
const liveUrl = sitePublish && sitePublish.published.length > 0 ? sitePublish.liveUrl : null;
|
|
277
340
|
const retryRefusal = (_ready_review = ready.review) == null ? void 0 : _ready_review.retryRefusal;
|
|
278
|
-
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';
|
|
344
|
+
// A guided start that ended without building its site starts over from its
|
|
345
|
+
// own answers, as a fresh job: the questions reopen filled in.
|
|
346
|
+
const restartAnswers = ready.kind === 'site' && (phase === 'failed' || phase === 'canceled') ? aiSiteStartAnswersFromInputs(ready.siteInputs) : null;
|
|
347
|
+
const refund = phase === 'failed' || phase === 'stopped' || phase === 'canceled' ? aiJobRefundCopy(ready) : null;
|
|
279
348
|
return /*#__PURE__*/ _jsxs(Frame, {
|
|
280
349
|
siteName: siteName,
|
|
281
350
|
heading: copy.heading,
|
|
@@ -292,9 +361,13 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
292
361
|
borderRadius: 2
|
|
293
362
|
},
|
|
294
363
|
children: [
|
|
295
|
-
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, {
|
|
296
369
|
"aria-label": "Building"
|
|
297
|
-
}),
|
|
370
|
+
})),
|
|
298
371
|
/*#__PURE__*/ _jsx(Box, {
|
|
299
372
|
component: "ol",
|
|
300
373
|
"aria-label": "Progress",
|
|
@@ -308,12 +381,14 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
308
381
|
},
|
|
309
382
|
children: /*#__PURE__*/ _jsx(Stack, {
|
|
310
383
|
spacing: 2,
|
|
311
|
-
children: rows.map((row)
|
|
384
|
+
children: rows.map((row)=>{
|
|
385
|
+
var _row_sections;
|
|
386
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
312
387
|
component: "li",
|
|
313
388
|
direction: "row",
|
|
314
389
|
spacing: 2,
|
|
315
390
|
sx: {
|
|
316
|
-
alignItems: '
|
|
391
|
+
alignItems: 'flex-start'
|
|
317
392
|
},
|
|
318
393
|
children: [
|
|
319
394
|
/*#__PURE__*/ _jsx(Box, {
|
|
@@ -326,22 +401,89 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
326
401
|
state: row.state
|
|
327
402
|
})
|
|
328
403
|
}),
|
|
329
|
-
/*#__PURE__*/
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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
|
+
]
|
|
333
456
|
})
|
|
334
457
|
]
|
|
335
|
-
}, row.id)
|
|
458
|
+
}, row.id);
|
|
459
|
+
})
|
|
336
460
|
})
|
|
337
461
|
})
|
|
338
462
|
]
|
|
339
463
|
}),
|
|
340
|
-
|
|
464
|
+
refund && ((_ready_refundedCredits = ready.refundedCredits) != null ? _ready_refundedCredits : 0) > 0 ? /*#__PURE__*/ _jsx(Alert, {
|
|
465
|
+
severity: "info",
|
|
466
|
+
children: refund
|
|
467
|
+
}) : credits ? /*#__PURE__*/ _jsx(Typography, {
|
|
341
468
|
variant: "body2",
|
|
342
469
|
color: "text.secondary",
|
|
343
470
|
children: credits
|
|
344
|
-
}),
|
|
471
|
+
}) : null,
|
|
472
|
+
retrying && restartAnswers && hostId ? /*#__PURE__*/ _jsx(AiSiteStartCard, {
|
|
473
|
+
hostId: hostId,
|
|
474
|
+
orgId: orgId != null ? orgId : undefined,
|
|
475
|
+
orgSlug: orgSlug,
|
|
476
|
+
host: hostSubdomain,
|
|
477
|
+
initialAnswers: restartAnswers,
|
|
478
|
+
startBlank: ()=>setRetrying(false),
|
|
479
|
+
leave: ()=>setRetrying(false)
|
|
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,
|
|
345
487
|
sitePublish && sitePublish.drafts.length > 0 && // The pages the publish left as drafts, each with its plain reason;
|
|
346
488
|
// Edit your pages is where they are fixed and published.
|
|
347
489
|
/*#__PURE__*/ _jsxs(Alert, {
|
|
@@ -376,6 +518,14 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
376
518
|
})
|
|
377
519
|
]
|
|
378
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
|
+
}),
|
|
379
529
|
phase === 'done' && /*#__PURE__*/ _jsxs(Stack, {
|
|
380
530
|
direction: {
|
|
381
531
|
xs: 'column',
|
|
@@ -428,6 +578,11 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
428
578
|
}
|
|
429
579
|
},
|
|
430
580
|
children: [
|
|
581
|
+
restartAnswers && hostId && /*#__PURE__*/ _jsx(Button, {
|
|
582
|
+
variant: "contained",
|
|
583
|
+
onClick: ()=>setRetrying(true),
|
|
584
|
+
children: 'Try again'
|
|
585
|
+
}),
|
|
431
586
|
canRetry && /*#__PURE__*/ _jsx(Button, {
|
|
432
587
|
variant: "contained",
|
|
433
588
|
disabled: busy || Boolean(retryRefusal),
|
|
@@ -443,6 +598,8 @@ export function AiSiteBuildPage({ hostId, segments, basePath }) {
|
|
|
443
598
|
]
|
|
444
599
|
}),
|
|
445
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',
|
|
446
603
|
variant: "outlined",
|
|
447
604
|
disableGutters: true,
|
|
448
605
|
sx: {
|