@aglyn/plugins-ai 1.0.0-beta.231 → 1.0.0-beta.232
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/package.json +17 -17
- package/src/lib/activity/ai-activity-actions.js +8 -4
- package/src/lib/activity/ai-activity-actions.js.map +1 -1
- package/src/lib/components/ai-job-follow.component.js +1 -0
- package/src/lib/components/ai-job-follow.component.js.map +1 -1
- package/src/lib/components/ai-job-links.js +13 -0
- package/src/lib/components/ai-job-links.js.map +1 -1
- package/src/lib/components/ai-jobs-list-page.component.js +1 -0
- package/src/lib/components/ai-jobs-list-page.component.js.map +1 -1
- package/src/lib/components/ai-media-create.component.d.ts +20 -7
- package/src/lib/components/ai-media-create.component.js +107 -55
- package/src/lib/components/ai-media-create.component.js.map +1 -1
- package/src/lib/components/ai-seo-fields-card.component.js +1 -0
- package/src/lib/components/ai-seo-fields-card.component.js.map +1 -1
- package/src/lib/components/ai-site-memory-card.component.d.ts +32 -0
- package/src/lib/components/ai-site-memory-card.component.js +187 -0
- package/src/lib/components/ai-site-memory-card.component.js.map +1 -0
- package/src/lib/components/ai-site-start-card.component.js +80 -77
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-theme-proposal-card.component.js +4 -0
- package/src/lib/components/ai-theme-proposal-card.component.js.map +1 -1
- package/src/lib/components/ai-usage-strip.component.js +1 -0
- package/src/lib/components/ai-usage-strip.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.d.ts +10 -0
- package/src/lib/components/assist-panel.component.js +119 -9
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/assist-signals-page.component.js +2 -0
- package/src/lib/components/assist-signals-page.component.js.map +1 -1
- package/src/lib/components/billing-ai-allotments.component.js +3 -0
- package/src/lib/components/billing-ai-allotments.component.js.map +1 -1
- package/src/lib/components/billing-ai-top-users.component.js +1 -0
- package/src/lib/components/billing-ai-top-users.component.js.map +1 -1
- package/src/lib/components/billing-assist-overage-card.component.js +2 -0
- package/src/lib/components/billing-assist-overage-card.component.js.map +1 -1
- package/src/lib/components/member-ai-usage-card.component.js +10 -0
- package/src/lib/components/member-ai-usage-card.component.js.map +1 -1
- package/src/lib/components/staff-org-ai-card.component.js +1 -0
- package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
- package/src/lib/components/staff-org-ai-conversations.component.d.ts +23 -0
- package/src/lib/components/staff-org-ai-conversations.component.js +346 -0
- package/src/lib/components/staff-org-ai-conversations.component.js.map +1 -0
- package/src/lib/jobs/ai-build-capabilities.d.ts +13 -1
- package/src/lib/jobs/ai-build-capabilities.js +101 -7
- package/src/lib/jobs/ai-build-capabilities.js.map +1 -1
- package/src/lib/jobs/ai-business-profile-prefill.d.ts +29 -0
- package/src/lib/jobs/ai-business-profile-prefill.js +85 -0
- package/src/lib/jobs/ai-business-profile-prefill.js.map +1 -0
- package/src/lib/jobs/ai-job-build-step.js +3 -1
- package/src/lib/jobs/ai-job-build-step.js.map +1 -1
- package/src/lib/jobs/ai-job-edit-step.d.ts +225 -0
- package/src/lib/jobs/ai-job-edit-step.js +631 -0
- package/src/lib/jobs/ai-job-edit-step.js.map +1 -0
- package/src/lib/jobs/ai-job-insight-step.js +21 -4
- package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-language.d.ts +8 -3
- package/src/lib/jobs/ai-job-layout-language.js +8 -2
- package/src/lib/jobs/ai-job-layout-language.js.map +1 -1
- package/src/lib/jobs/ai-job-layout-step.js +7 -6
- package/src/lib/jobs/ai-job-layout-step.js.map +1 -1
- package/src/lib/jobs/ai-job-logic-step.d.ts +20 -0
- package/src/lib/jobs/ai-job-logic-step.js +87 -6
- package/src/lib/jobs/ai-job-logic-step.js.map +1 -1
- package/src/lib/jobs/ai-job-page-language.d.ts +52 -7
- package/src/lib/jobs/ai-job-page-language.js +72 -9
- package/src/lib/jobs/ai-job-page-language.js.map +1 -1
- package/src/lib/jobs/ai-job-page-step.js +12 -2
- package/src/lib/jobs/ai-job-page-step.js.map +1 -1
- package/src/lib/jobs/ai-job-plan-step.d.ts +19 -5
- package/src/lib/jobs/ai-job-plan-step.js +54 -20
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-content.d.ts +163 -0
- package/src/lib/jobs/ai-job-site-content.js +443 -0
- package/src/lib/jobs/ai-job-site-content.js.map +1 -0
- package/src/lib/jobs/ai-job-site-look.d.ts +112 -0
- package/src/lib/jobs/ai-job-site-look.js +322 -0
- package/src/lib/jobs/ai-job-site-look.js.map +1 -0
- package/src/lib/jobs/ai-job-site-step.d.ts +26 -5
- package/src/lib/jobs/ai-job-site-step.js +163 -24
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs-notify.d.ts +6 -1
- package/src/lib/jobs/ai-jobs-notify.js +15 -3
- package/src/lib/jobs/ai-jobs-notify.js.map +1 -1
- package/src/lib/layout-language/ai-layout-compiler.d.ts +9 -0
- package/src/lib/layout-language/ai-layout-compiler.js +120 -33
- package/src/lib/layout-language/ai-layout-compiler.js.map +1 -1
- package/src/lib/layout-language/ai-layout-frame.js +5 -4
- package/src/lib/layout-language/ai-layout-frame.js.map +1 -1
- package/src/lib/layout-language/ai-layout-language.d.ts +12 -5
- package/src/lib/layout-language/ai-layout-language.js +92 -9
- package/src/lib/layout-language/ai-layout-language.js.map +1 -1
- package/src/lib/layout-language/ai-layout-pictures.d.ts +144 -0
- package/src/lib/layout-language/ai-layout-pictures.js +214 -0
- package/src/lib/layout-language/ai-layout-pictures.js.map +1 -0
- package/src/lib/layout-language/ai-layout-store.d.ts +2 -0
- package/src/lib/layout-language/ai-layout-store.js +7 -1
- package/src/lib/layout-language/ai-layout-store.js.map +1 -1
- package/src/lib/model/ai-build-progress.js +4 -1
- package/src/lib/model/ai-build-progress.js.map +1 -1
- package/src/lib/model/ai-edit-job.d.ts +109 -0
- package/src/lib/model/ai-edit-job.js +157 -0
- package/src/lib/model/ai-edit-job.js.map +1 -0
- package/src/lib/model/ai-job-activity.js +1 -0
- package/src/lib/model/ai-job-activity.js.map +1 -1
- package/src/lib/model/ai-jobs.types.d.ts +3 -1
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-logic-job.d.ts +18 -1
- package/src/lib/model/ai-logic-job.js +24 -3
- package/src/lib/model/ai-logic-job.js.map +1 -1
- package/src/lib/model/ai-media-credits.d.ts +8 -4
- package/src/lib/model/ai-media-credits.js +11 -4
- package/src/lib/model/ai-media-credits.js.map +1 -1
- package/src/lib/model/ai-media-kinds.d.ts +68 -0
- package/src/lib/model/ai-media-kinds.js +98 -0
- package/src/lib/model/ai-media-kinds.js.map +1 -0
- package/src/lib/model/ai-site-build-progress.d.ts +4 -0
- package/src/lib/model/ai-site-build-progress.js +28 -11
- package/src/lib/model/ai-site-build-progress.js.map +1 -1
- package/src/lib/model/ai-site-context.d.ts +111 -0
- package/src/lib/model/ai-site-context.js +222 -0
- package/src/lib/model/ai-site-context.js.map +1 -0
- package/src/lib/model/ai-site-job.d.ts +10 -2
- package/src/lib/model/ai-site-job.js +12 -5
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-kinds.d.ts +164 -0
- package/src/lib/model/ai-site-kinds.js +1942 -0
- package/src/lib/model/ai-site-kinds.js.map +1 -0
- package/src/lib/model/ai-site-look.d.ts +150 -0
- package/src/lib/model/ai-site-look.js +1236 -0
- package/src/lib/model/ai-site-look.js.map +1 -0
- package/src/lib/model/ai-site-memory.d.ts +80 -0
- package/src/lib/model/ai-site-memory.js +171 -0
- package/src/lib/model/ai-site-memory.js.map +1 -0
- package/src/lib/model/ai-site-start.d.ts +10 -1
- package/src/lib/model/ai-site-start.js +16 -2
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/model/assist-follow-up.d.ts +92 -0
- package/src/lib/model/assist-follow-up.js +128 -0
- package/src/lib/model/assist-follow-up.js.map +1 -0
- package/src/lib/plugin-config.js +2 -0
- package/src/lib/plugin-config.js.map +1 -1
- package/src/lib/plugin.js +20 -1
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/providers/anthropic.d.ts +9 -1
- package/src/lib/providers/anthropic.js +143 -9
- package/src/lib/providers/anthropic.js.map +1 -1
- package/src/lib/providers/catalog.d.ts +37 -7
- package/src/lib/providers/catalog.js +103 -11
- package/src/lib/providers/catalog.js.map +1 -1
- package/src/lib/providers/contract.d.ts +29 -0
- package/src/lib/providers/contract.js.map +1 -1
- package/src/lib/providers/image-contract.d.ts +22 -1
- package/src/lib/providers/image-contract.js +40 -1
- package/src/lib/providers/image-contract.js.map +1 -1
- package/src/lib/providers/image-endpoints.d.ts +24 -0
- package/src/lib/providers/image-endpoints.js +28 -0
- package/src/lib/providers/image-endpoints.js.map +1 -0
- package/src/lib/providers/model-choice.js +23 -2
- 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-endpoint.d.ts +48 -0
- package/src/lib/providers/vertex-image-endpoint.js +80 -0
- package/src/lib/providers/vertex-image-endpoint.js.map +1 -0
- package/src/lib/providers/vertex-image.d.ts +13 -27
- package/src/lib/providers/vertex-image.js +15 -42
- package/src/lib/providers/vertex-image.js.map +1 -1
- package/src/lib/runtime/ai-blog-post-generation.d.ts +62 -0
- package/src/lib/runtime/ai-blog-post-generation.js +89 -0
- package/src/lib/runtime/ai-blog-post-generation.js.map +1 -0
- package/src/lib/runtime/ai-dev-env.d.ts +53 -0
- package/src/lib/runtime/ai-dev-env.js +72 -0
- package/src/lib/runtime/ai-dev-env.js.map +1 -0
- package/src/lib/runtime/ai-dev-replay.d.ts +116 -0
- package/src/lib/runtime/ai-dev-replay.js +313 -0
- package/src/lib/runtime/ai-dev-replay.js.map +1 -0
- package/src/lib/runtime/ai-doctrine.js +5 -1
- 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 +13 -1
- package/src/lib/runtime/ai-eval.js +84 -1
- package/src/lib/runtime/ai-eval.js.map +1 -1
- package/src/lib/runtime/ai-live-batch.d.ts +45 -0
- package/src/lib/runtime/ai-live-batch.js +89 -0
- package/src/lib/runtime/ai-live-batch.js.map +1 -0
- package/src/lib/runtime/ai-runtime.js +46 -2
- package/src/lib/runtime/ai-runtime.js.map +1 -1
- package/src/lib/runtime/site-context.d.ts +58 -0
- package/src/lib/runtime/site-context.js +127 -0
- package/src/lib/runtime/site-context.js.map +1 -0
- package/src/lib/server/ai-admin-conversations.d.ts +22 -0
- package/src/lib/server/ai-admin-conversations.js +197 -0
- package/src/lib/server/ai-admin-conversations.js.map +1 -0
- package/src/lib/server/ai-media-image.d.ts +5 -5
- package/src/lib/server/ai-media-image.js +25 -11
- package/src/lib/server/ai-media-image.js.map +1 -1
- package/src/lib/server/ai-media-raster-prompt.d.ts +34 -0
- package/src/lib/server/ai-media-raster-prompt.js +53 -0
- package/src/lib/server/ai-media-raster-prompt.js.map +1 -0
- package/src/lib/server/assist-chat.d.ts +11 -0
- package/src/lib/server/assist-chat.js +57 -18
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/assist-edit-applied.js +16 -3
- package/src/lib/server/assist-edit-applied.js.map +1 -1
- package/src/lib/server/assist-view-context.d.ts +19 -1
- package/src/lib/server/assist-view-context.js +38 -1
- package/src/lib/server/assist-view-context.js.map +1 -1
- package/src/lib/server.js +10 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/subprocessors.js +17 -1
- package/src/lib/subprocessors.js.map +1 -1
- package/src/lib/tools/ai-blog-post-tool.d.ts +60 -0
- package/src/lib/tools/ai-blog-post-tool.js +175 -0
- package/src/lib/tools/ai-blog-post-tool.js.map +1 -0
- package/src/lib/usage/assist-usage.d.ts +3 -0
- package/src/lib/usage/assist-usage.js +4 -2
- package/src/lib/usage/assist-usage.js.map +1 -1
- package/src/lib/usage/staff-org-ai-conversations.d.ts +103 -0
- package/src/lib/usage/staff-org-ai-conversations.js +152 -0
- package/src/lib/usage/staff-org-ai-conversations.js.map +1 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { aiAddonName, pluginDocsHelp } from "@aglyn/aglyn";
|
|
19
|
+
import { CardDisplay, useConfirmationContext } from "@aglyn/shared-ui-jsx";
|
|
20
|
+
import EmptyStateComponent from "@aglyn/shared-ui-jsx/components/empty-state.component";
|
|
21
|
+
import { useSnackbar } from "@aglyn/shared-ui-snackstack";
|
|
22
|
+
import { useFirestore, useFirestoreCollection } from "@aglyn/tenant-feature-instance";
|
|
23
|
+
import { Button, Divider, IconButton, Stack, Tooltip, Typography } from "@mui/material";
|
|
24
|
+
import { collection, deleteDoc, doc, limit, query, writeBatch } from "firebase/firestore";
|
|
25
|
+
import { useCallback, useMemo, useState } from "react";
|
|
26
|
+
import { AI_SITE_MEMORY_MAX, AI_SITE_MEMORY_SUBCOLLECTION, aiSitePreferenceOf } from "../model/ai-site-memory.js";
|
|
27
|
+
/** The configured brand's AI, never ours by literal (AGL-2153). */ const AI_NAME = aiAddonName();
|
|
28
|
+
/** A close mark, drawn inline so the card ships no icon set. */ const ForgetIcon = ()=>/*#__PURE__*/ _jsx("svg", {
|
|
29
|
+
width: "18",
|
|
30
|
+
height: "18",
|
|
31
|
+
viewBox: "0 0 24 24",
|
|
32
|
+
"aria-hidden": true,
|
|
33
|
+
focusable: "false",
|
|
34
|
+
children: /*#__PURE__*/ _jsx("path", {
|
|
35
|
+
fill: "currentColor",
|
|
36
|
+
d: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"
|
|
37
|
+
})
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* What Aglyn AI learned from this site's edits (AGL-3661), on Setup →
|
|
41
|
+
* Business profile: the short preferences the assist edit route distilled
|
|
42
|
+
* from the edits the owner applied, which every later AI job for the site
|
|
43
|
+
* reads. The owner reads them here and forgets one, or all of them.
|
|
44
|
+
*
|
|
45
|
+
* Read and deleted on the client: the rules let a site's members read and
|
|
46
|
+
* delete `aiMemory` and refuse them a create or an update, because a client
|
|
47
|
+
* write would put words of its choosing into later prompts.
|
|
48
|
+
*/ export function AiSiteMemoryCard(props) {
|
|
49
|
+
const { hostId } = props;
|
|
50
|
+
const firestore = useFirestore();
|
|
51
|
+
const { enqueueSnackbar } = useSnackbar();
|
|
52
|
+
const { confirm } = useConfirmationContext();
|
|
53
|
+
const [busy, setBusy] = useState(false);
|
|
54
|
+
const { data, status } = useFirestoreCollection(()=>query(collection(firestore, 'hosts', hostId, AI_SITE_MEMORY_SUBCOLLECTION), limit(AI_SITE_MEMORY_MAX * 2)), [
|
|
55
|
+
firestore,
|
|
56
|
+
hostId
|
|
57
|
+
], {
|
|
58
|
+
idField: '$id'
|
|
59
|
+
});
|
|
60
|
+
const preferences = useMemo(()=>data.map((row)=>aiSitePreferenceOf(row.$id, row)).filter((row)=>row !== null).sort((a, b)=>b.count - a.count || b.lastSeenAtMs - a.lastSeenAtMs), [
|
|
61
|
+
data
|
|
62
|
+
]);
|
|
63
|
+
const forget = useCallback(async (preference)=>{
|
|
64
|
+
setBusy(true);
|
|
65
|
+
try {
|
|
66
|
+
await deleteDoc(doc(firestore, 'hosts', hostId, AI_SITE_MEMORY_SUBCOLLECTION, preference.id));
|
|
67
|
+
enqueueSnackbar(`${AI_NAME} will no longer use that preference`, {
|
|
68
|
+
variant: 'success'
|
|
69
|
+
});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error('ai memory forget failed', error);
|
|
72
|
+
enqueueSnackbar('That preference was not removed. Try again.', {
|
|
73
|
+
variant: 'error'
|
|
74
|
+
});
|
|
75
|
+
} finally{
|
|
76
|
+
setBusy(false);
|
|
77
|
+
}
|
|
78
|
+
}, [
|
|
79
|
+
enqueueSnackbar,
|
|
80
|
+
firestore,
|
|
81
|
+
hostId
|
|
82
|
+
]);
|
|
83
|
+
const forgetAll = useCallback(async ()=>{
|
|
84
|
+
const confirmed = await confirm({
|
|
85
|
+
title: `Forget everything ${AI_NAME} learned here?`,
|
|
86
|
+
description: `Later AI jobs for this site stop using these preferences. ${AI_NAME} learns again from the edits you apply next.`,
|
|
87
|
+
confirmationText: 'Forget all',
|
|
88
|
+
confirmationButtonProps: {
|
|
89
|
+
color: 'error'
|
|
90
|
+
}
|
|
91
|
+
}).then(()=>true).catch(()=>false);
|
|
92
|
+
if (!confirmed) return;
|
|
93
|
+
setBusy(true);
|
|
94
|
+
try {
|
|
95
|
+
const batch = writeBatch(firestore);
|
|
96
|
+
for (const preference of preferences){
|
|
97
|
+
batch.delete(doc(firestore, 'hosts', hostId, AI_SITE_MEMORY_SUBCOLLECTION, preference.id));
|
|
98
|
+
}
|
|
99
|
+
await batch.commit();
|
|
100
|
+
enqueueSnackbar(`${AI_NAME} forgot what it learned on this site`, {
|
|
101
|
+
variant: 'success'
|
|
102
|
+
});
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error('ai memory clear failed', error);
|
|
105
|
+
enqueueSnackbar('The preferences were not cleared. Try again.', {
|
|
106
|
+
variant: 'error'
|
|
107
|
+
});
|
|
108
|
+
} finally{
|
|
109
|
+
setBusy(false);
|
|
110
|
+
}
|
|
111
|
+
}, [
|
|
112
|
+
confirm,
|
|
113
|
+
enqueueSnackbar,
|
|
114
|
+
firestore,
|
|
115
|
+
hostId,
|
|
116
|
+
preferences
|
|
117
|
+
]);
|
|
118
|
+
return /*#__PURE__*/ _jsx(CardDisplay, {
|
|
119
|
+
header: `What ${AI_NAME} learned`,
|
|
120
|
+
subheader: "Short preferences from the edits you applied with Assist. Every AI job for this site reads them.",
|
|
121
|
+
help: pluginDocsHelp('aiBusinessProfile', {
|
|
122
|
+
anchor: '#what-aglyn-ai-learned',
|
|
123
|
+
excerpt: `Preferences ${AI_NAME} took from the edits you applied. Forget one, or all, at any time.`
|
|
124
|
+
}),
|
|
125
|
+
actions: preferences.length ? /*#__PURE__*/ _jsx(Button, {
|
|
126
|
+
color: "error",
|
|
127
|
+
disabled: busy,
|
|
128
|
+
onClick: ()=>void forgetAll(),
|
|
129
|
+
children: 'Forget all'
|
|
130
|
+
}) : undefined,
|
|
131
|
+
contentGutterX: true,
|
|
132
|
+
contentGutterY: true,
|
|
133
|
+
children: preferences.length ? /*#__PURE__*/ _jsx(Stack, {
|
|
134
|
+
divider: /*#__PURE__*/ _jsx(Divider, {
|
|
135
|
+
flexItem: true
|
|
136
|
+
}),
|
|
137
|
+
"data-testid": "ai-site-memory",
|
|
138
|
+
children: preferences.map((preference)=>/*#__PURE__*/ _jsxs(Stack, {
|
|
139
|
+
direction: "row",
|
|
140
|
+
spacing: 2,
|
|
141
|
+
sx: {
|
|
142
|
+
alignItems: 'center',
|
|
143
|
+
py: 1
|
|
144
|
+
},
|
|
145
|
+
children: [
|
|
146
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
147
|
+
sx: {
|
|
148
|
+
flex: 1,
|
|
149
|
+
minWidth: 0
|
|
150
|
+
},
|
|
151
|
+
children: [
|
|
152
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
153
|
+
variant: "body2",
|
|
154
|
+
children: preference.text
|
|
155
|
+
}),
|
|
156
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
157
|
+
variant: "caption",
|
|
158
|
+
color: "text.secondary",
|
|
159
|
+
children: preference.count === 1 ? 'Seen in 1 applied edit' : `Seen in ${preference.count} applied edits`
|
|
160
|
+
})
|
|
161
|
+
]
|
|
162
|
+
}),
|
|
163
|
+
/*#__PURE__*/ _jsx(Tooltip, {
|
|
164
|
+
title: "Forget this",
|
|
165
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
166
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
167
|
+
size: "small",
|
|
168
|
+
"aria-label": `Forget “${preference.text}”`,
|
|
169
|
+
disabled: busy,
|
|
170
|
+
onClick: ()=>void forget(preference),
|
|
171
|
+
children: /*#__PURE__*/ _jsx(ForgetIcon, {})
|
|
172
|
+
})
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
]
|
|
176
|
+
}, preference.id))
|
|
177
|
+
}) : /*#__PURE__*/ _jsx(EmptyStateComponent, {
|
|
178
|
+
compact: true,
|
|
179
|
+
label: status === 'loading' ? 'Loading…' : 'Nothing learned yet',
|
|
180
|
+
description: status === 'loading' ? undefined : 'When you apply an Assist edit that shows a preference, such as shorter copy or no emoji, it appears here.'
|
|
181
|
+
})
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
AiSiteMemoryCard.displayName = 'AiSiteMemoryCard';
|
|
185
|
+
export default AiSiteMemoryCard;
|
|
186
|
+
|
|
187
|
+
//# sourceMappingURL=ai-site-memory-card.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/components/ai-site-memory-card.component.tsx"],"sourcesContent":["/**\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\n'use client'\n\nimport { aiAddonName, pluginDocsHelp } from '@aglyn/aglyn'\nimport type { ConsoleHostBusinessProfileZoneProps } from '@aglyn/aglyn/plugin-manager/feature-plugins'\nimport { CardDisplay, useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport EmptyStateComponent from '@aglyn/shared-ui-jsx/components/empty-state.component'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport { useFirestore, useFirestoreCollection } from '@aglyn/tenant-feature-instance'\nimport { Button, Divider, IconButton, Stack, Tooltip, Typography } from '@mui/material'\nimport { collection, deleteDoc, doc, limit, query, writeBatch } from 'firebase/firestore'\nimport { useCallback, useMemo, useState } from 'react'\nimport {\n AI_SITE_MEMORY_MAX,\n AI_SITE_MEMORY_SUBCOLLECTION,\n aiSitePreferenceOf,\n type AiSitePreference,\n} from '../model/ai-site-memory'\n\n/** The configured brand's AI, never ours by literal (AGL-2153). */\nconst AI_NAME = aiAddonName()\n\n/** A close mark, drawn inline so the card ships no icon set. */\nconst ForgetIcon = () => (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" aria-hidden focusable=\"false\">\n <path\n fill=\"currentColor\"\n d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n />\n </svg>\n)\n\n/**\n * What Aglyn AI learned from this site's edits (AGL-3661), on Setup →\n * Business profile: the short preferences the assist edit route distilled\n * from the edits the owner applied, which every later AI job for the site\n * reads. The owner reads them here and forgets one, or all of them.\n *\n * Read and deleted on the client: the rules let a site's members read and\n * delete `aiMemory` and refuse them a create or an update, because a client\n * write would put words of its choosing into later prompts.\n */\nexport function AiSiteMemoryCard(props: ConsoleHostBusinessProfileZoneProps) {\n const { hostId } = props\n const firestore = useFirestore()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n const [busy, setBusy] = useState(false)\n const { data, status } = useFirestoreCollection<Record<string, unknown> & { $id: string }>(\n () => query(collection(firestore, 'hosts', hostId, AI_SITE_MEMORY_SUBCOLLECTION), limit(AI_SITE_MEMORY_MAX * 2)),\n [firestore, hostId],\n { idField: '$id' },\n )\n const preferences = useMemo(\n () =>\n data\n .map((row) => aiSitePreferenceOf(row.$id, row))\n .filter((row): row is AiSitePreference => row !== null)\n .sort((a, b) => b.count - a.count || b.lastSeenAtMs - a.lastSeenAtMs),\n [data],\n )\n\n const forget = useCallback(\n async (preference: AiSitePreference) => {\n setBusy(true)\n try {\n await deleteDoc(doc(firestore, 'hosts', hostId, AI_SITE_MEMORY_SUBCOLLECTION, preference.id))\n enqueueSnackbar(`${AI_NAME} will no longer use that preference`, { variant: 'success' })\n } catch (error) {\n console.error('ai memory forget failed', error)\n enqueueSnackbar('That preference was not removed. Try again.', { variant: 'error' })\n } finally {\n setBusy(false)\n }\n },\n [enqueueSnackbar, firestore, hostId],\n )\n\n const forgetAll = useCallback(async () => {\n const confirmed = await confirm({\n title: `Forget everything ${AI_NAME} learned here?`,\n description:\n `Later AI jobs for this site stop using these preferences. ${AI_NAME} learns again from the edits you apply next.`,\n confirmationText: 'Forget all',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n setBusy(true)\n try {\n const batch = writeBatch(firestore)\n for (const preference of preferences) {\n batch.delete(doc(firestore, 'hosts', hostId, AI_SITE_MEMORY_SUBCOLLECTION, preference.id))\n }\n await batch.commit()\n enqueueSnackbar(`${AI_NAME} forgot what it learned on this site`, { variant: 'success' })\n } catch (error) {\n console.error('ai memory clear failed', error)\n enqueueSnackbar('The preferences were not cleared. Try again.', { variant: 'error' })\n } finally {\n setBusy(false)\n }\n }, [confirm, enqueueSnackbar, firestore, hostId, preferences])\n\n return (\n <CardDisplay\n header={`What ${AI_NAME} learned`}\n subheader=\"Short preferences from the edits you applied with Assist. Every AI job for this site reads them.\"\n help={pluginDocsHelp('aiBusinessProfile', {\n anchor: '#what-aglyn-ai-learned',\n excerpt: `Preferences ${AI_NAME} took from the edits you applied. Forget one, or all, at any time.`,\n })}\n actions={\n preferences.length ? (\n <Button color=\"error\" disabled={busy} onClick={() => void forgetAll()}>\n {'Forget all'}\n </Button>\n ) : undefined\n }\n contentGutterX\n contentGutterY\n >\n {preferences.length ? (\n <Stack divider={<Divider flexItem />} data-testid=\"ai-site-memory\">\n {preferences.map((preference) => (\n <Stack key={preference.id} direction=\"row\" spacing={2} sx={{ alignItems: 'center', py: 1 }}>\n <Stack sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"body2\">{preference.text}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {preference.count === 1 ? 'Seen in 1 applied edit' : `Seen in ${preference.count} applied edits`}\n </Typography>\n </Stack>\n <Tooltip title=\"Forget this\">\n <span>\n <IconButton\n size=\"small\"\n aria-label={`Forget “${preference.text}”`}\n disabled={busy}\n onClick={() => void forget(preference)}\n >\n <ForgetIcon />\n </IconButton>\n </span>\n </Tooltip>\n </Stack>\n ))}\n </Stack>\n ) : (\n <EmptyStateComponent\n compact\n label={status === 'loading' ? 'Loading…' : 'Nothing learned yet'}\n description={\n status === 'loading'\n ? undefined\n : 'When you apply an Assist edit that shows a preference, such as shorter copy or no emoji, it appears here.'\n }\n />\n )}\n </CardDisplay>\n )\n}\nAiSiteMemoryCard.displayName = 'AiSiteMemoryCard'\n\nexport default AiSiteMemoryCard\n"],"names":["aiAddonName","pluginDocsHelp","CardDisplay","useConfirmationContext","EmptyStateComponent","useSnackbar","useFirestore","useFirestoreCollection","Button","Divider","IconButton","Stack","Tooltip","Typography","collection","deleteDoc","doc","limit","query","writeBatch","useCallback","useMemo","useState","AI_SITE_MEMORY_MAX","AI_SITE_MEMORY_SUBCOLLECTION","aiSitePreferenceOf","AI_NAME","ForgetIcon","svg","width","height","viewBox","aria-hidden","focusable","path","fill","d","AiSiteMemoryCard","props","hostId","firestore","enqueueSnackbar","confirm","busy","setBusy","data","status","idField","preferences","map","row","$id","filter","sort","a","b","count","lastSeenAtMs","forget","preference","id","variant","error","console","forgetAll","confirmed","title","description","confirmationText","confirmationButtonProps","color","then","catch","batch","delete","commit","header","subheader","help","anchor","excerpt","actions","length","disabled","onClick","undefined","contentGutterX","contentGutterY","divider","flexItem","data-testid","direction","spacing","sx","alignItems","py","flex","minWidth","text","span","size","aria-label","compact","label","displayName"],"mappings":"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"}
|
|
@@ -19,8 +19,9 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
19
19
|
import { lockdownRefusalText, parseLockdownRefusal, PLATFORM_BRAND_NAME } from "@aglyn/aglyn";
|
|
20
20
|
import { trackEvent } from "@aglyn/aglyn/app-utils/analytics-events";
|
|
21
21
|
import { ICON_VARIANT_CLOSE } from "@aglyn/shared-data-enums";
|
|
22
|
-
import {
|
|
22
|
+
import { mdiAccount, mdiBookOpenPageVariant, mdiBriefcaseOutline, mdiCalendarHeart, mdiCamera, mdiClockOutline, mdiContentCut, mdiCreation, mdiDumbbell, mdiHandHeart, mdiHeartPulse, mdiHomeCity, mdiMusic, mdiPaletteOutline, mdiRocketLaunch, mdiScaleBalance, mdiSchool, mdiShopping, mdiSilverwareForkKnife, mdiViewGridOutline, mdiWrench, mdiYoga, mdiInformationOutline, mdiPageLayoutHeaderFooter } from "@aglyn/shared-data-mdi";
|
|
23
23
|
import { MdiIcon } from "@aglyn/shared-ui-jsx";
|
|
24
|
+
import { OptionCardGrid } from "@aglyn/shared-ui-jsx/components/option-card-grid.component";
|
|
24
25
|
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
25
26
|
import { useUser } from "@aglyn/tenant-feature-instance";
|
|
26
27
|
import { Alert, AppBar, Box, Button, Card, CardActionArea, Chip, CircularProgress, Container, Dialog, DialogActions, DialogContent, IconButton, MenuItem, Stack, Step, StepLabel, Stepper, TextField, Toolbar, Tooltip, Typography } from "@mui/material";
|
|
@@ -29,8 +30,34 @@ import { useRouter } from "next/navigation";
|
|
|
29
30
|
import { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
30
31
|
import { AI_JOB_AUTO_CONFIRM_INPUT, AI_SITE_FREE_PAGES, AI_SITE_FREE_PAGES_NOTE, AI_SITE_SUBMISSION_CHOICES, aiFreeSiteCreditEstimate, aiSiteCreditEstimate, aiSitePagesBand } from "../model/ai-site-job.js";
|
|
31
32
|
import { FREE_AI_TASTE_CREDITS_PER_MONTH } from "../plan-entitlements.js";
|
|
32
|
-
import { AI_SITE_START_ANSWERS,
|
|
33
|
+
import { AI_SITE_START_ANSWERS, AI_SITE_START_TYPES, aiSiteStartBrief, aiSiteStartKind, aiSiteStartInputs, aiSiteStartRefusal } from "../model/ai-site-start.js";
|
|
34
|
+
import { AI_SITE_KINDS } from "../model/ai-site-kinds.js";
|
|
35
|
+
/** The icon each kind of site's card shows. */ const AI_SITE_KIND_ICONS = {
|
|
36
|
+
business: mdiBriefcaseOutline.path,
|
|
37
|
+
trades: mdiWrench.path,
|
|
38
|
+
professional: mdiScaleBalance.path,
|
|
39
|
+
wellness: mdiHeartPulse.path,
|
|
40
|
+
restaurant: mdiSilverwareForkKnife.path,
|
|
41
|
+
store: mdiShopping.path,
|
|
42
|
+
portfolio: mdiViewGridOutline.path,
|
|
43
|
+
studio: mdiPaletteOutline.path,
|
|
44
|
+
photography: mdiCamera.path,
|
|
45
|
+
blog: mdiBookOpenPageVariant.path,
|
|
46
|
+
events: mdiCalendarHeart.path,
|
|
47
|
+
fitness: mdiDumbbell.path,
|
|
48
|
+
yoga: mdiYoga.path,
|
|
49
|
+
beauty: mdiContentCut.path,
|
|
50
|
+
realestate: mdiHomeCity.path,
|
|
51
|
+
education: mdiSchool.path,
|
|
52
|
+
nonprofit: mdiHandHeart.path,
|
|
53
|
+
music: mdiMusic.path,
|
|
54
|
+
personal: mdiAccount.path,
|
|
55
|
+
landing: mdiRocketLaunch.path,
|
|
56
|
+
'coming-soon': mdiClockOutline.path
|
|
57
|
+
};
|
|
33
58
|
import { AiJobFollow } from "./ai-job-follow.component.js";
|
|
59
|
+
import { AiModelSelector } from "./ai-model-selector.component.js";
|
|
60
|
+
import { useAiModelChoice } from "./use-ai-model-choice.js";
|
|
34
61
|
import { aiSiteBuildHref } from "./ai-job-links.js";
|
|
35
62
|
import { publishAiJob } from "./ai-jobs-store.js";
|
|
36
63
|
/** Labels the dialog for a reader, from its own heading. */ const TITLE_ID = 'ai-site-start-title';
|
|
@@ -154,6 +181,7 @@ import { publishAiJob } from "./ai-jobs-store.js";
|
|
|
154
181
|
}
|
|
155
182
|
export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leave, initialAnswers = null }) {
|
|
156
183
|
var _ref;
|
|
184
|
+
var _modelChoice_options_options_find, _modelChoice_options;
|
|
157
185
|
const { data: user } = useUser();
|
|
158
186
|
const router = useRouter();
|
|
159
187
|
// Held in a ref so a request reads WHO is signed in, never the identity of
|
|
@@ -207,6 +235,27 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
207
235
|
freeTaste
|
|
208
236
|
});
|
|
209
237
|
const band = aiSitePagesBand(freeTaste);
|
|
238
|
+
// On a paid plan the person picks the model that builds the site (AGL-3660),
|
|
239
|
+
// Auto by default, from the models their plan allows; every step of the job
|
|
240
|
+
// runs on it. A Free workspace builds on the default and is offered none.
|
|
241
|
+
const modelChoice = useAiModelChoice({
|
|
242
|
+
orgId,
|
|
243
|
+
hostId,
|
|
244
|
+
surface: 'jobs',
|
|
245
|
+
kind: 'job.page'
|
|
246
|
+
});
|
|
247
|
+
// A pick remembered from before needs its cost to estimate by; Auto does not,
|
|
248
|
+
// and the list is otherwise read when the picker opens.
|
|
249
|
+
const { load: loadModels, model: rememberedModel } = modelChoice;
|
|
250
|
+
useEffect(()=>{
|
|
251
|
+
if (!freeTaste && step === 'describe' && rememberedModel) loadModels();
|
|
252
|
+
}, [
|
|
253
|
+
freeTaste,
|
|
254
|
+
step,
|
|
255
|
+
rememberedModel,
|
|
256
|
+
loadModels
|
|
257
|
+
]);
|
|
258
|
+
const pickedModel = freeTaste ? null : modelChoice.model;
|
|
210
259
|
const plan = useCallback(async ()=>{
|
|
211
260
|
if (!orgId || aiSiteStartRefusal(answers, {
|
|
212
261
|
freeTaste
|
|
@@ -220,7 +269,7 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
220
269
|
headers: {
|
|
221
270
|
'Content-Type': 'application/json'
|
|
222
271
|
},
|
|
223
|
-
body: JSON.stringify({
|
|
272
|
+
body: JSON.stringify(_extends({
|
|
224
273
|
orgId,
|
|
225
274
|
hostId,
|
|
226
275
|
kind: 'site',
|
|
@@ -230,7 +279,9 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
230
279
|
inputs: _extends({}, aiSiteStartInputs(answers), {
|
|
231
280
|
[AI_JOB_AUTO_CONFIRM_INPUT]: true
|
|
232
281
|
})
|
|
233
|
-
}
|
|
282
|
+
}, pickedModel ? {
|
|
283
|
+
model: pickedModel
|
|
284
|
+
} : {}))
|
|
234
285
|
});
|
|
235
286
|
const payload = await response.json().catch(()=>null);
|
|
236
287
|
if (!response.ok) {
|
|
@@ -270,7 +321,8 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
270
321
|
orgSlug,
|
|
271
322
|
host,
|
|
272
323
|
leave,
|
|
273
|
-
router
|
|
324
|
+
router,
|
|
325
|
+
pickedModel
|
|
274
326
|
]);
|
|
275
327
|
const chooseStarter = useCallback(()=>{
|
|
276
328
|
setStartingStarter(true);
|
|
@@ -291,9 +343,11 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
291
343
|
// Before a job is started every way out is the blank site, which writes the
|
|
292
344
|
// starter (AGL-3594); after, it only closes — the job builds the site.
|
|
293
345
|
const exit = started ? leave != null ? leave : startBlank : startBlank;
|
|
294
|
-
|
|
346
|
+
// The chosen model's cost against Auto's, as the model list states it.
|
|
347
|
+
const modelMultiplier = pickedModel && ((_modelChoice_options = modelChoice.options) == null ? void 0 : (_modelChoice_options_options_find = _modelChoice_options.options.find((option)=>option.id === pickedModel)) == null ? void 0 : _modelChoice_options_options_find.multiplier) || 1;
|
|
348
|
+
const estimate = freeTaste ? aiFreeSiteCreditEstimate(answers.pages) : Math.round(aiSiteCreditEstimate(answers.pages, {
|
|
295
349
|
welcomeEmail: answers.welcomeEmail
|
|
296
|
-
});
|
|
350
|
+
}) * modelMultiplier);
|
|
297
351
|
const estimateText = freeTaste ? `Up to about ${estimate.toLocaleString('en-US')} of the ${FREE_AI_TASTE_CREDITS_PER_MONTH} AI credits your Free workspace has each month` : `About ${estimate.toLocaleString('en-US')} credits, estimated`;
|
|
298
352
|
const choosing = step === 'choose' && !started;
|
|
299
353
|
return /*#__PURE__*/ _jsxs(Dialog, {
|
|
@@ -522,83 +576,28 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
522
576
|
/*#__PURE__*/ _jsxs(Stack, {
|
|
523
577
|
spacing: 2,
|
|
524
578
|
component: "section",
|
|
525
|
-
"aria-label": "
|
|
579
|
+
"aria-label": "Style",
|
|
526
580
|
children: [
|
|
527
581
|
/*#__PURE__*/ _jsx(SectionLabel, {
|
|
528
|
-
children: '
|
|
582
|
+
children: 'Style'
|
|
529
583
|
}),
|
|
530
584
|
/*#__PURE__*/ _jsx(Typography, {
|
|
531
585
|
variant: "body2",
|
|
532
586
|
color: "text.secondary",
|
|
533
|
-
children: '
|
|
587
|
+
children: answers.kind ? 'This decides how your site looks and which pages it usually has.' : 'Picked from your answer above. Choose another to change how your site looks and which pages it usually has.'
|
|
534
588
|
}),
|
|
535
|
-
/*#__PURE__*/ _jsx(
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
variant: "outlined",
|
|
548
|
-
sx: (theme)=>({
|
|
549
|
-
borderRadius: 2,
|
|
550
|
-
borderColor: selected ? 'primary.main' : 'divider',
|
|
551
|
-
bgcolor: selected ? alpha(theme.palette.primary.main, 0.08) : 'transparent'
|
|
552
|
-
}),
|
|
553
|
-
children: /*#__PURE__*/ _jsx(CardActionArea, {
|
|
554
|
-
"aria-pressed": selected,
|
|
555
|
-
"aria-label": `${example.label} — ${example.blurb}`,
|
|
556
|
-
onClick: ()=>answer({
|
|
557
|
-
example: selected ? null : example.id
|
|
558
|
-
}),
|
|
559
|
-
sx: {
|
|
560
|
-
p: 2,
|
|
561
|
-
height: '100%'
|
|
562
|
-
},
|
|
563
|
-
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
564
|
-
direction: "row",
|
|
565
|
-
spacing: 1.5,
|
|
566
|
-
sx: {
|
|
567
|
-
alignItems: 'flex-start'
|
|
568
|
-
},
|
|
569
|
-
children: [
|
|
570
|
-
/*#__PURE__*/ _jsxs(Box, {
|
|
571
|
-
sx: {
|
|
572
|
-
flex: 1,
|
|
573
|
-
minWidth: 0
|
|
574
|
-
},
|
|
575
|
-
children: [
|
|
576
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
577
|
-
variant: "subtitle2",
|
|
578
|
-
children: example.label
|
|
579
|
-
}),
|
|
580
|
-
/*#__PURE__*/ _jsx(Typography, {
|
|
581
|
-
variant: "body2",
|
|
582
|
-
color: "text.secondary",
|
|
583
|
-
children: example.blurb
|
|
584
|
-
})
|
|
585
|
-
]
|
|
586
|
-
}),
|
|
587
|
-
selected && /*#__PURE__*/ _jsx(Box, {
|
|
588
|
-
sx: {
|
|
589
|
-
color: 'primary.main',
|
|
590
|
-
display: 'flex'
|
|
591
|
-
},
|
|
592
|
-
"aria-hidden": true,
|
|
593
|
-
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
594
|
-
path: mdiCheckCircle.path
|
|
595
|
-
})
|
|
596
|
-
})
|
|
597
|
-
]
|
|
598
|
-
})
|
|
599
|
-
})
|
|
600
|
-
}, example.id);
|
|
601
|
-
})
|
|
589
|
+
/*#__PURE__*/ _jsx(OptionCardGrid, {
|
|
590
|
+
label: "Style of site",
|
|
591
|
+
options: AI_SITE_KINDS.map((kind)=>({
|
|
592
|
+
id: kind.id,
|
|
593
|
+
title: kind.label,
|
|
594
|
+
description: kind.blurb,
|
|
595
|
+
icon: AI_SITE_KIND_ICONS[kind.id]
|
|
596
|
+
})),
|
|
597
|
+
value: aiSiteStartKind(answers).id,
|
|
598
|
+
onChange: (kind)=>answer({
|
|
599
|
+
kind
|
|
600
|
+
})
|
|
602
601
|
})
|
|
603
602
|
]
|
|
604
603
|
}),
|
|
@@ -728,6 +727,10 @@ export function AiSiteStartCard({ hostId, orgId, orgSlug, host, startBlank, leav
|
|
|
728
727
|
color: "text.secondary",
|
|
729
728
|
children: refusal
|
|
730
729
|
}),
|
|
730
|
+
!freeTaste && /*#__PURE__*/ _jsx(AiModelSelector, {
|
|
731
|
+
choice: modelChoice,
|
|
732
|
+
disabled: busy
|
|
733
|
+
}),
|
|
731
734
|
/*#__PURE__*/ _jsx(Button, {
|
|
732
735
|
onClick: ()=>setStep('choose'),
|
|
733
736
|
children: 'Back'
|