Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 1s
Monorepo Pipeline / 🧹 Lint (push) Failing after 35s
Monorepo Pipeline / 🧪 Test (push) Failing after 35s
Monorepo Pipeline / 🏗️ Build (push) Failing after 12s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Image Processor (push) Has been skipped
Monorepo Pipeline / 🐳 Build Directus (Base) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
100 lines
3.9 KiB
TypeScript
100 lines
3.9 KiB
TypeScript
// ============================================================================
|
|
// Step 03: Strategize — Briefing Summary + Design Vision (Gemini Pro)
|
|
// ============================================================================
|
|
|
|
import { llmJsonRequest } from "../llm-client.js";
|
|
import type { ConceptState, StepResult, PipelineConfig } from "../types.js";
|
|
import { DEFAULT_MODELS } from "../types.js";
|
|
|
|
export async function executeStrategize(
|
|
state: ConceptState,
|
|
config: PipelineConfig,
|
|
): Promise<StepResult> {
|
|
const models = { ...DEFAULT_MODELS, ...config.modelsOverride };
|
|
const startTime = Date.now();
|
|
|
|
if (!state.auditedFacts) {
|
|
return { success: false, error: "No audited facts from Step 02 available." };
|
|
}
|
|
|
|
const systemPrompt = `
|
|
You are a high-end Digital Architect. Your goal is to make the CUSTOMER feel 100% understood.
|
|
Analyze the BRIEFING and the EXISTING WEBSITE context.
|
|
|
|
### OBJECTIVE:
|
|
1. **briefingSummary**: Ein sachlicher, tiefgehender Überblick der Unternehmenslage.
|
|
- STIL: Keine Ich-Form. Keine Marketing-Floskeln. Nutze präzise Fachbegriffe. Sei prägnant.
|
|
- FORM: EXAKT ZWEI ABSÄTZE. Insgesamt ca. 6 Sätze.
|
|
- INHALT: Status Quo, was der Kunde will, welcher Sprung notwendig ist.
|
|
- ABSOLUTE REGEL: Keine Halluzinationen. Keine namentlichen Nennungen von Personen.
|
|
- RELAUNCH-REGEL: Wenn isRelaunch=true, NICHT sagen "keine digitale Präsenz". Es GIBT eine Seite.
|
|
- SORGLOS BETRIEB: MUSS erwähnt werden als Teil des Gesamtpakets.
|
|
|
|
2. **designVision**: Ein abstraktes, strategisches Konzept.
|
|
- STIL: Rein konzeptionell. Keine Umsetzungsschritte. Keine Ich-Form. Sei prägnant.
|
|
- FORM: EXAKT ZWEI ABSÄTZE. Insgesamt ca. 4 Sätze.
|
|
- DATENSCHUTZ: KEINERLEI namentliche Nennungen.
|
|
- FOKUS: Welche strategische Wirkung soll erzielt werden?
|
|
|
|
### RULES:
|
|
- NO "wir/unser". NO "Ich/Mein". Objective, fact-oriented narrative.
|
|
- NO marketing lingo. NO "innovativ", "revolutionär", "state-of-the-art".
|
|
- NO hallucinations about features not in the briefing.
|
|
- NO "SEO-Standards zur Fachkräftesicherung" or "B2B-Nutzerströme" — das ist Schwachsinn.
|
|
Use specific industry terms from the briefing (e.g. "Kabeltiefbau", "HDD-Bohrverfahren").
|
|
- LANGUAGE: Professional German. Simple but expert-level.
|
|
|
|
### OUTPUT FORMAT:
|
|
{
|
|
"briefingSummary": string,
|
|
"designVision": string
|
|
}
|
|
`;
|
|
|
|
const userPrompt = `
|
|
BRIEFING (TRUTH SOURCE):
|
|
${state.briefing}
|
|
|
|
EXISTING WEBSITE DATA:
|
|
- Services: ${state.siteProfile?.services?.join(", ") || "unbekannt"}
|
|
- Navigation: ${state.siteProfile?.navigation?.map((n) => n.label).join(", ") || "unbekannt"}
|
|
- Company: ${state.auditedFacts.companyName || "unbekannt"}
|
|
|
|
EXTRACTED & AUDITED FACTS:
|
|
${JSON.stringify(state.auditedFacts, null, 2)}
|
|
|
|
${state.siteAudit?.report ? `
|
|
TECHNICAL SITE AUDIT (IST-Analyse):
|
|
Health: ${state.siteAudit.report.overallHealth} (SEO: ${state.siteAudit.report.seoScore}, UX: ${state.siteAudit.report.uxScore}, Perf: ${state.siteAudit.report.performanceScore})
|
|
- Executive Summary: ${state.siteAudit.report.executiveSummary}
|
|
- Strengths: ${state.siteAudit.report.strengths.join(", ")}
|
|
- Critical Issues: ${state.siteAudit.report.criticalIssues.join(", ")}
|
|
- Quick Wins: ${state.siteAudit.report.quickWins.join(", ")}
|
|
` : ""}
|
|
`;
|
|
|
|
try {
|
|
const { data, usage } = await llmJsonRequest({
|
|
model: models.pro,
|
|
systemPrompt,
|
|
userPrompt,
|
|
apiKey: config.openrouterKey,
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
data,
|
|
usage: {
|
|
step: "03-strategize",
|
|
model: models.pro,
|
|
promptTokens: usage.promptTokens,
|
|
completionTokens: usage.completionTokens,
|
|
cost: usage.cost,
|
|
durationMs: Date.now() - startTime,
|
|
},
|
|
};
|
|
} catch (err) {
|
|
return { success: false, error: `Strategize step failed: ${(err as Error).message}` };
|
|
}
|
|
}
|