fix(studio): keep AI provider and model details private
This commit is contained in:
1 parent
5aec369054
commit
6d0c47fba7
5 files changed
+65
-51
No files matched your search
+16
-16
@@ -18,23 +18,21 @@ type FailureKind =
|
||||
| "response"
|
||||
| "request";
|
||||
const failureMessages: Record<FailureKind, string> = {
|
||||
auth: "APIMart rejected the server API key. Check APIMART_API_KEY and its permissions, then restart the app.",
|
||||
auth: "AI generation is unavailable due to a server configuration issue. Contact the site administrator.",
|
||||
quota:
|
||||
"APIMart reports insufficient credit or quota. Check the provider account balance and limits.",
|
||||
"AI generation has reached its service usage limit. Try again later or contact the site administrator.",
|
||||
model:
|
||||
"APIMart could not access the configured model. Check that this model is enabled for the server API key.",
|
||||
rate: "APIMart is rate limiting requests. Wait a minute and generate again.",
|
||||
unavailable:
|
||||
"APIMart is temporarily unavailable. Try generating again shortly.",
|
||||
network:
|
||||
"The server could not reach APIMart. Check the VM's outbound HTTPS connection and try again.",
|
||||
"AI generation is unavailable due to a server configuration issue. Contact the site administrator.",
|
||||
rate: "AI generation is rate limiting requests. Wait a minute and generate again.",
|
||||
unavailable: "AI generation is temporarily unavailable. Try again shortly.",
|
||||
network: "The server could not reach the AI service. Try again shortly.",
|
||||
truncated:
|
||||
"APIMart stopped before completing all design alternatives. Try a shorter brief or generate again.",
|
||||
filtered: "APIMart declined this generation. Revise the brief and try again.",
|
||||
response:
|
||||
"APIMart returned an empty or unreadable completion. Try generating again.",
|
||||
"AI generation stopped before completing all design alternatives. Try a shorter brief or generate again.",
|
||||
filtered:
|
||||
"This generation could not be completed. Revise the brief and try again.",
|
||||
response: "AI generation returned an empty or unreadable result. Try again.",
|
||||
request:
|
||||
"APIMart rejected the completion request. Check the provider's model configuration.",
|
||||
"AI generation could not process this request. Try again or contact the site administrator.",
|
||||
};
|
||||
class APIMartFailure extends Error {
|
||||
constructor(
|
||||
@@ -202,8 +200,7 @@ function synchronousStudioAI(
|
||||
return json({ error: "Same-origin requests only." }, 403);
|
||||
if (url.pathname.endsWith("/generation") && request.method === "GET")
|
||||
return json({
|
||||
provider: "APIMart",
|
||||
model,
|
||||
provider: "AI",
|
||||
templateVersion: 1,
|
||||
delivery: "polling",
|
||||
maxAttempts: 2,
|
||||
@@ -291,7 +288,7 @@ function synchronousStudioAI(
|
||||
code: "WRN-STUDIO-PROPOSAL",
|
||||
path: "$",
|
||||
message:
|
||||
"APIMart returned a design that did not meet the schema after both provider requests were used. Generate again. Your draft and previous alternatives are unchanged.",
|
||||
"AI generation returned a design that did not meet the schema after both attempts were used. Generate again. Your draft and previous alternatives are unchanged.",
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -317,6 +314,9 @@ function synchronousStudioAI(
|
||||
},
|
||||
];
|
||||
}
|
||||
// Public responses retain useful provenance without exposing infrastructure choices.
|
||||
result.provenance.provider = "AI";
|
||||
delete result.provenance.model;
|
||||
return json(result);
|
||||
} catch (error) {
|
||||
const message =
|
||||
|
||||
+2
-13
@@ -18,19 +18,8 @@ export const studioHelpScript = `(() => {
|
||||
});
|
||||
})();`;
|
||||
|
||||
export function addStudioGuide(
|
||||
html: string,
|
||||
configured: boolean,
|
||||
model = "gpt-5-mini",
|
||||
) {
|
||||
const safeModel = model.replace(
|
||||
/[&<>"']/g,
|
||||
(char) =>
|
||||
({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[
|
||||
char
|
||||
]!,
|
||||
);
|
||||
const guide = `<details open class="help"><summary><strong>How to use Design Studio</strong></summary><ol><li><strong>Build manually.</strong> Open Manual design to choose colors, fonts, corner radii, spacing and shadows. Switch light/dark modes, select Update preview to save settings, then export. No AI is required.</li><li><strong>Describe your website for AI.</strong> Open Guided design, enter your product and audience, then choose colors, shapes and spacing with Next.</li><li><strong>Generate and compare.</strong> Click Generate three directions. The first valid alternative appears in the large preview. Review another to compare, then choose Use reviewed proposal to save it. Show current draft returns without accepting.</li><li><strong>Refine it.</strong> Try “make buttons square and use blue as the primary color” under Edit with words. Lock decisions you want to keep.</li><li><strong>Use it in your app.</strong> Open Review & apply and export Theme config or Compiled CSS. This website previews and exports designs; it does not change your deployed app automatically.</li></ol><p>${configured ? `APIMart AI is enabled with ${safeModel}. Generation sends your brief and current design to APIMart only when you request it.` : "AI is not configured. Local presets and supported rule-based edits still work. Set APIMART_API_KEY and APIMART_MODEL in the server .env and restart to enable AI."}</p></details>`;
|
||||
export function addStudioGuide(html: string, configured: boolean) {
|
||||
const guide = `<details open class="help"><summary><strong>How to use Design Studio</strong></summary><ol><li><strong>Build manually.</strong> Open Manual design to choose colors, fonts, corner radii, spacing and shadows. Switch light/dark modes, select Update preview to save settings, then export. No AI is required.</li><li><strong>Describe your website for AI.</strong> Open Guided design, enter your product and audience, then choose colors, shapes and spacing with Next.</li><li><strong>Generate and compare.</strong> Click Generate three directions. The first valid alternative appears in the large preview. Review another to compare, then choose Use reviewed proposal to save it. Show current draft returns without accepting.</li><li><strong>Refine it.</strong> Try “make buttons square and use blue as the primary color” under Edit with words. Lock decisions you want to keep.</li><li><strong>Use it in your app.</strong> Open Review & apply and export Theme config or Compiled CSS. This website previews and exports designs; it does not change your deployed app automatically.</li></ol><p>${configured ? "AI design assistance is available. Your brief and current design are sent for processing only when you request generation." : "AI design assistance is currently unavailable. You can still use Manual design, presets and supported rule-based edits."}</p></details>`;
|
||||
return html
|
||||
.replace(
|
||||
'<script type="module"',
|
||||
|
||||
@@ -58,7 +58,6 @@ const designStudio: Middleware = async (ctx, next) => {
|
||||
addStudioGuide(
|
||||
await response.text(),
|
||||
!!process.env.APIMART_API_KEY?.trim(),
|
||||
process.env.APIMART_MODEL?.trim() || APIMART_MODEL,
|
||||
),
|
||||
{ status: response.status, headers },
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user