improved a lot of things
This commit is contained in:
@@ -36,7 +36,6 @@ export async function answerAgentQuestion(
|
||||
},
|
||||
],
|
||||
maxTokens: 1024,
|
||||
temperature: 0.7,
|
||||
});
|
||||
|
||||
let parsed: unknown;
|
||||
|
||||
@@ -34,7 +34,6 @@ export async function queryCrossArtboard(
|
||||
},
|
||||
],
|
||||
maxTokens: 1024,
|
||||
temperature: 0.3,
|
||||
});
|
||||
|
||||
// Returning empty results on parse failure is indistinguishable from "no match".
|
||||
@@ -49,5 +48,19 @@ export async function queryCrossArtboard(
|
||||
);
|
||||
}
|
||||
|
||||
// Runtime guard: ensure the parsed value has the expected shape before casting.
|
||||
// Without this, a malformed AI response (e.g. { results: null }) would let
|
||||
// callers hit a TypeError on `.results.map()` instead of a clear error message.
|
||||
if (
|
||||
typeof parsed !== 'object' ||
|
||||
parsed === null ||
|
||||
!Array.isArray((parsed as Record<string, unknown>)['results'])
|
||||
) {
|
||||
throw new Error(
|
||||
`Artboard query response missing "results" array. ` +
|
||||
`Raw response (first 300 chars): ${response.text.slice(0, 300)}`
|
||||
);
|
||||
}
|
||||
|
||||
return parsed as ArtboardQueryOutput;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,6 @@ export async function fillCompletionZone(
|
||||
system,
|
||||
messages: [{ role: 'user', content: userContent }],
|
||||
maxTokens: 4096,
|
||||
temperature: 0.3,
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
@@ -27,7 +27,6 @@ export async function generateDiffSummary(
|
||||
},
|
||||
],
|
||||
maxTokens: 128,
|
||||
temperature: 0.3,
|
||||
});
|
||||
|
||||
return { summary: response.text.trim() };
|
||||
|
||||
@@ -2,10 +2,12 @@ import type { AIGateway } from '../gateway.js';
|
||||
import { buildSystemPrompt } from '../prompts/system.js';
|
||||
|
||||
export interface DriftReportInput {
|
||||
/** Screenshot of the live app as base64 data URL */
|
||||
screenshotBase64: string;
|
||||
/** Active Design Language File as JSON string */
|
||||
dlfJson: string;
|
||||
/** Screenshot of the live app as base64 data URL (optional — text-only analysis if absent) */
|
||||
screenshotBase64?: string;
|
||||
/** Active Design Language File as JSON string (optional — generic advice if absent) */
|
||||
dlfJson?: string;
|
||||
/** Human-readable artboard metadata to give the model context (name, size, origin, etc.) */
|
||||
artboardContext?: string;
|
||||
}
|
||||
|
||||
export interface DriftViolation {
|
||||
@@ -29,32 +31,39 @@ export async function generateDriftReport(
|
||||
): Promise<DriftReportOutput> {
|
||||
const system = buildSystemPrompt({
|
||||
role: 'a design system compliance auditor',
|
||||
dlfJson: input.dlfJson,
|
||||
...(input.dlfJson !== undefined ? { dlfJson: input.dlfJson } : {}),
|
||||
});
|
||||
|
||||
type ContentBlock =
|
||||
| { type: 'image'; source: { type: 'base64'; media_type: 'image/png'; data: string } }
|
||||
| { type: 'text'; text: string };
|
||||
|
||||
const userContent: ContentBlock[] = [];
|
||||
|
||||
if (input.screenshotBase64) {
|
||||
userContent.push({
|
||||
type: 'image',
|
||||
source: {
|
||||
type: 'base64',
|
||||
media_type: 'image/png',
|
||||
data: input.screenshotBase64.replace(/^data:image\/\w+;base64,/, ''),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const analysisInstructions = input.screenshotBase64
|
||||
? 'Compare this screenshot against the design language file provided in your system context.'
|
||||
: `Analyse the following artboard for design system drift:\n\n${input.artboardContext ?? '(no artboard context provided)'}`;
|
||||
|
||||
userContent.push({
|
||||
type: 'text',
|
||||
text: `${analysisInstructions} Identify all design system drift violations.\n\nReturn a JSON object:\n{\n "violations": [{"component":"...", "property":"...", "currentValue":"...", "expectedValue":"...", "severity":"critical|warning", "description":"..."}],\n "summary": "...",\n "violationCount": N\n}\n\nRespond ONLY with valid JSON.`,
|
||||
});
|
||||
|
||||
const response = await gateway.complete({
|
||||
system,
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: [
|
||||
{
|
||||
type: 'image',
|
||||
source: {
|
||||
type: 'base64',
|
||||
media_type: 'image/png',
|
||||
data: input.screenshotBase64.replace(/^data:image\/\w+;base64,/, ''),
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Compare this screenshot against the design language file provided in your system context. Identify all design system drift violations.\n\nReturn a JSON object:\n{\n "violations": [{"component":"...", "property":"...", "currentValue":"...", "expectedValue":"...", "severity":"critical|warning", "description":"..."}],\n "summary": "...",\n "violationCount": N\n}\n\nRespond ONLY with valid JSON.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
messages: [{ role: 'user', content: userContent }],
|
||||
maxTokens: 4096,
|
||||
temperature: 0.3,
|
||||
});
|
||||
|
||||
// Returning empty violations on parse failure would be a false-negative in a
|
||||
|
||||
Reference in New Issue
Block a user