@agent-native/core 0.84.22 → 0.84.24
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +14 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/model-config.ts +1 -1
- package/corpus/core/src/cli/skills.ts +17 -3
- package/corpus/core/src/client/AssistantChat.tsx +45 -12
- package/corpus/core/src/client/active-run-state.ts +22 -0
- package/corpus/core/src/client/chat/message-components.tsx +2 -1
- package/corpus/core/src/client/chat/tool-call-display.tsx +18 -2
- package/corpus/core/src/client/sse-event-processor.ts +157 -40
- package/corpus/core/src/notifications/index.ts +1 -0
- package/corpus/core/src/notifications/registry.ts +13 -1
- package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +15 -13
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +18 -1
- package/corpus/templates/analytics/server/db/schema.ts +1 -1
- package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +4 -1
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +76 -7
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +30 -1
- package/corpus/templates/clips/actions/finalize-recording.ts +84 -4
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +256 -0
- package/corpus/templates/clips/actions/reprocess-recording.ts +160 -0
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
- package/corpus/templates/clips/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +1 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +31 -3
- package/corpus/templates/clips/changelog/2026-07-01-clip-embeds-now-render-as-a-clean-video-only-player-without-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-shared-clips-now-start-playing-and-scrub-instantly-instead-o.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/chrome-extension/src/github-preview-content.ts +2 -2
- package/corpus/templates/clips/chrome-extension/src/github-preview.ts +41 -31
- package/corpus/templates/clips/server/lib/video-remux.ts +222 -0
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +75 -19
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +11 -1
- package/corpus/templates/design/changelog/2026-07-01-design-chat-no-longer-shows-an-empty-state-selection-chip-in-the-composer.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/videos/.agents/skills/frontend-design/SKILL.md +2 -0
- package/dist/agent/model-config.js +1 -1
- package/dist/agent/model-config.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +17 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +2 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +37 -15
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/active-run-state.d.ts +2 -0
- package/dist/client/active-run-state.d.ts.map +1 -1
- package/dist/client/active-run-state.js +17 -0
- package/dist/client/active-run-state.js.map +1 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +3 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +3 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +8 -8
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +1 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +136 -35
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +1 -1
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/registry.d.ts +5 -0
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +4 -1
- package/dist/notifications/registry.js.map +1 -1
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
- package/package.json +1 -1
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make recorded video seekable so browsers can start playback immediately and
|
|
3
|
+
* scrub without re-buffering the whole file.
|
|
4
|
+
*
|
|
5
|
+
* Two problems this fixes, both produced by `MediaRecorder` output:
|
|
6
|
+
* - MP4: the `moov` metadata atom is written AFTER `mdat`, so a player must
|
|
7
|
+
* download the entire file before it can start / seek. We relocate it with
|
|
8
|
+
* the pure-TypeScript {@link applyFaststart} (no ffmpeg needed).
|
|
9
|
+
* - WebM: MediaRecorder emits a "live" stream with no Cues (seek index) and an
|
|
10
|
+
* unknown Segment duration, so Chrome refuses to honor `currentTime = X`
|
|
11
|
+
* seeks and has to scan/download to move around. A cheap `ffmpeg -c copy`
|
|
12
|
+
* remux rewrites the container with a SeekHead + Cues index and a real
|
|
13
|
+
* duration — no re-encode, so it's fast and lossless.
|
|
14
|
+
*
|
|
15
|
+
* Everything here is best-effort: on any failure (ffmpeg missing, bad input,
|
|
16
|
+
* timeout) we return the ORIGINAL bytes with `changed: false`, so callers never
|
|
17
|
+
* regress relative to uploading the raw recording.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { spawn } from "node:child_process";
|
|
21
|
+
import { existsSync } from "node:fs";
|
|
22
|
+
import { mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
23
|
+
import { createRequire } from "node:module";
|
|
24
|
+
import { tmpdir } from "node:os";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
|
|
27
|
+
import { applyFaststart, hasPlayableMp4Metadata } from "./faststart.js";
|
|
28
|
+
|
|
29
|
+
const REMUX_TIMEOUT_MS = 120_000;
|
|
30
|
+
const STDERR_LIMIT = 16 * 1024;
|
|
31
|
+
const MAX_CONCURRENT_REMUXES = 2;
|
|
32
|
+
// EBML magic that every valid Matroska/WebM file starts with.
|
|
33
|
+
const EBML_MAGIC = [0x1a, 0x45, 0xdf, 0xa3];
|
|
34
|
+
|
|
35
|
+
const requireFromThisFile = createRequire(import.meta.url);
|
|
36
|
+
let cachedFfmpegStaticPath: string | null | undefined;
|
|
37
|
+
let activeRemuxes = 0;
|
|
38
|
+
const remuxWaiters: Array<() => void> = [];
|
|
39
|
+
|
|
40
|
+
export type VideoFormat = "webm" | "mp4";
|
|
41
|
+
|
|
42
|
+
export interface SeekableResult {
|
|
43
|
+
/** The seekable bytes, or the original bytes when nothing changed. */
|
|
44
|
+
bytes: Uint8Array;
|
|
45
|
+
/** True when the returned bytes differ from the input. */
|
|
46
|
+
changed: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function ffmpegCommand(): string {
|
|
50
|
+
if (process.env.FFMPEG_PATH) return process.env.FFMPEG_PATH;
|
|
51
|
+
return resolveFfmpegStaticPath() ?? "ffmpeg";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function resolveFfmpegStaticPath(): string | null {
|
|
55
|
+
if (cachedFfmpegStaticPath !== undefined) return cachedFfmpegStaticPath;
|
|
56
|
+
try {
|
|
57
|
+
const resolved = requireFromThisFile("ffmpeg-static");
|
|
58
|
+
cachedFfmpegStaticPath =
|
|
59
|
+
typeof resolved === "string" && resolved && existsSync(resolved)
|
|
60
|
+
? resolved
|
|
61
|
+
: null;
|
|
62
|
+
} catch {
|
|
63
|
+
cachedFfmpegStaticPath = null;
|
|
64
|
+
}
|
|
65
|
+
return cachedFfmpegStaticPath;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Whether a server-side ffmpeg binary is resolvable. */
|
|
69
|
+
export function isFfmpegAvailable(): boolean {
|
|
70
|
+
return Boolean(process.env.FFMPEG_PATH) || resolveFfmpegStaticPath() !== null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function startsWithMagic(bytes: Uint8Array, magic: number[]): boolean {
|
|
74
|
+
if (bytes.byteLength < magic.length) return false;
|
|
75
|
+
for (let i = 0; i < magic.length; i++) {
|
|
76
|
+
if (bytes[i] !== magic[i]) return false;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function runFfmpeg(args: string[]): Promise<void> {
|
|
82
|
+
await new Promise<void>((resolve, reject) => {
|
|
83
|
+
const child = spawn(ffmpegCommand(), args, {
|
|
84
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
85
|
+
});
|
|
86
|
+
let stderr = "";
|
|
87
|
+
const timeout = setTimeout(() => {
|
|
88
|
+
child.kill("SIGKILL");
|
|
89
|
+
reject(new Error(`ffmpeg remux timed out\n${stderr}`));
|
|
90
|
+
}, REMUX_TIMEOUT_MS);
|
|
91
|
+
|
|
92
|
+
child.stderr?.on("data", (chunk: Buffer) => {
|
|
93
|
+
stderr = (stderr + chunk.toString("utf8")).slice(-STDERR_LIMIT);
|
|
94
|
+
});
|
|
95
|
+
child.on("error", (err) => {
|
|
96
|
+
clearTimeout(timeout);
|
|
97
|
+
reject(new Error(`${err.message}\n${stderr}`));
|
|
98
|
+
});
|
|
99
|
+
child.on("close", (code) => {
|
|
100
|
+
clearTimeout(timeout);
|
|
101
|
+
if (code === 0) {
|
|
102
|
+
resolve();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
reject(new Error(`ffmpeg exited with code ${code}\n${stderr}`));
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function withRemuxSlot<T>(fn: () => Promise<T>): Promise<T> {
|
|
111
|
+
if (activeRemuxes >= MAX_CONCURRENT_REMUXES) {
|
|
112
|
+
await new Promise<void>((resolve) => remuxWaiters.push(resolve));
|
|
113
|
+
}
|
|
114
|
+
activeRemuxes += 1;
|
|
115
|
+
try {
|
|
116
|
+
return await fn();
|
|
117
|
+
} finally {
|
|
118
|
+
activeRemuxes = Math.max(0, activeRemuxes - 1);
|
|
119
|
+
remuxWaiters.shift()?.();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Rewrite a WebM/Matroska file with a SeekHead + Cues index and a real
|
|
125
|
+
* duration via a lossless `ffmpeg -c copy` remux. Returns the original bytes
|
|
126
|
+
* unchanged when ffmpeg is unavailable, the input isn't WebM, or anything
|
|
127
|
+
* goes wrong.
|
|
128
|
+
*/
|
|
129
|
+
export async function remuxWebmToSeekable(
|
|
130
|
+
mediaBytes: Uint8Array,
|
|
131
|
+
): Promise<SeekableResult> {
|
|
132
|
+
const unchanged: SeekableResult = { bytes: mediaBytes, changed: false };
|
|
133
|
+
|
|
134
|
+
if (mediaBytes.byteLength === 0) return unchanged;
|
|
135
|
+
if (!startsWithMagic(mediaBytes, EBML_MAGIC)) return unchanged;
|
|
136
|
+
if (!isFfmpegAvailable()) return unchanged;
|
|
137
|
+
|
|
138
|
+
const dir = await mkdtemp(join(tmpdir(), "clips-remux-"));
|
|
139
|
+
const inputPath = join(dir, "input.webm");
|
|
140
|
+
const outputPath = join(dir, "output.webm");
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
await writeFile(inputPath, mediaBytes);
|
|
144
|
+
await withRemuxSlot(() =>
|
|
145
|
+
runFfmpeg([
|
|
146
|
+
"-hide_banner",
|
|
147
|
+
"-loglevel",
|
|
148
|
+
"error",
|
|
149
|
+
"-nostdin",
|
|
150
|
+
"-y",
|
|
151
|
+
// Regenerate presentation timestamps so a live MediaRecorder stream
|
|
152
|
+
// gets a coherent, seekable timeline in the remuxed output.
|
|
153
|
+
"-fflags",
|
|
154
|
+
"+genpts",
|
|
155
|
+
"-i",
|
|
156
|
+
inputPath,
|
|
157
|
+
// Stream-copy every track: no re-encode, so this stays fast + lossless.
|
|
158
|
+
"-map",
|
|
159
|
+
"0",
|
|
160
|
+
"-c",
|
|
161
|
+
"copy",
|
|
162
|
+
"-f",
|
|
163
|
+
"webm",
|
|
164
|
+
outputPath,
|
|
165
|
+
]),
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const info = await stat(outputPath).catch(() => null);
|
|
169
|
+
if (!info || info.size === 0) return unchanged;
|
|
170
|
+
|
|
171
|
+
const out = new Uint8Array(await readFile(outputPath));
|
|
172
|
+
// Validate the muxer actually produced a WebM before trusting it.
|
|
173
|
+
if (!startsWithMagic(out, EBML_MAGIC)) return unchanged;
|
|
174
|
+
|
|
175
|
+
return { bytes: out, changed: true };
|
|
176
|
+
} catch (err) {
|
|
177
|
+
console.warn("[video-remux] webm remux failed, keeping original", {
|
|
178
|
+
err: err instanceof Error ? err.message : String(err),
|
|
179
|
+
});
|
|
180
|
+
return unchanged;
|
|
181
|
+
} finally {
|
|
182
|
+
await rm(dir, { recursive: true, force: true }).catch(() => {});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Make an MP4 start-playable by moving its `moov` atom ahead of `mdat`. Pure
|
|
188
|
+
* TypeScript — no ffmpeg. Returns the original bytes when already faststarted
|
|
189
|
+
* or when the result would fail metadata validation.
|
|
190
|
+
*/
|
|
191
|
+
export function faststartMp4(mediaBytes: Uint8Array): SeekableResult {
|
|
192
|
+
if (mediaBytes.byteLength === 0) return { bytes: mediaBytes, changed: false };
|
|
193
|
+
try {
|
|
194
|
+
const out = applyFaststart(mediaBytes);
|
|
195
|
+
if (out === mediaBytes) return { bytes: mediaBytes, changed: false };
|
|
196
|
+
if (!hasPlayableMp4Metadata(out)) {
|
|
197
|
+
return { bytes: mediaBytes, changed: false };
|
|
198
|
+
}
|
|
199
|
+
return { bytes: out, changed: true };
|
|
200
|
+
} catch (err) {
|
|
201
|
+
console.warn("[video-remux] mp4 faststart failed, keeping original", {
|
|
202
|
+
err: err instanceof Error ? err.message : String(err),
|
|
203
|
+
});
|
|
204
|
+
return { bytes: mediaBytes, changed: false };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Make recorded media seekable based on its container format. Dispatches to
|
|
210
|
+
* {@link faststartMp4} for MP4 and {@link remuxWebmToSeekable} for WebM.
|
|
211
|
+
* Always resolves; unknown formats and failures return the input unchanged.
|
|
212
|
+
*/
|
|
213
|
+
export async function makeSeekable(input: {
|
|
214
|
+
mediaBytes: Uint8Array;
|
|
215
|
+
videoFormat: VideoFormat;
|
|
216
|
+
}): Promise<SeekableResult> {
|
|
217
|
+
if (input.videoFormat === "mp4") return faststartMp4(input.mediaBytes);
|
|
218
|
+
if (input.videoFormat === "webm") {
|
|
219
|
+
return remuxWebmToSeekable(input.mediaBytes);
|
|
220
|
+
}
|
|
221
|
+
return { bytes: input.mediaBytes, changed: false };
|
|
222
|
+
}
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -18,22 +18,62 @@ Every generated design uses:
|
|
|
18
18
|
- **Google Fonts** — for distinctive typography (never Inter/Roboto/Arial)
|
|
19
19
|
- **CSS Custom Properties** — for theming and tweaks panel integration
|
|
20
20
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
## Why the workflow exists — it is the anti-slop engine
|
|
22
|
+
|
|
23
|
+
Generic output ("AI slop") is a *workflow* failure, not a lack of talent. When one
|
|
24
|
+
prompt has to set the taste, explore the options, and emit final code all at once,
|
|
25
|
+
the safest answer is the statistical average of the training data: Inter, an
|
|
26
|
+
indigo→violet gradient, a centered hero, three rounded icon cards. Design beats
|
|
27
|
+
this by splitting those jobs across the tools — use them in order, don't collapse
|
|
28
|
+
them:
|
|
29
|
+
|
|
30
|
+
1. **Direction** — `show-design-questions` (or a stated thesis) sets taste on purpose.
|
|
31
|
+
2. **Exploration** — `present-design-variants` compares genuinely different directions
|
|
32
|
+
before committing to one. **This step kills sameness; never skip it for open-ended work.**
|
|
33
|
+
3. **Spec** — a linked design system and the `:root` token block capture the chosen look as reusable rules.
|
|
34
|
+
4. **Code** — `generate-design` / `edit-design` execute a decision already made instead of guessing.
|
|
35
|
+
|
|
36
|
+
Jumping straight to code is how you get slop. Let the phases (below) do the work.
|
|
37
|
+
|
|
38
|
+
## Aesthetic quality bar — beat distributional convergence
|
|
39
|
+
|
|
40
|
+
You sample toward the "on-distribution" center by default; refuse it. **Every
|
|
41
|
+
"don't" here carries a "do"** — a banned default plus where to go instead —
|
|
42
|
+
because banning Inter alone just makes you reach for Roboto next. Use a banned
|
|
43
|
+
item only if the user explicitly asks.
|
|
44
|
+
|
|
45
|
+
- **Fonts.** Don't: Inter, Roboto, Arial, Open Sans, system-ui. Do: a distinctive
|
|
46
|
+
Google Font pairing matched to the chosen aesthetic (see the table) — editorial
|
|
47
|
+
serif, grotesk display + mono, or one variable font pushed across weight extremes.
|
|
48
|
+
- **Color.** Don't: the indigo/violet slop palette (`#6366F1`, `#8B5CF6`,
|
|
49
|
+
`#A855F7`), a purple gradient on white, or everything in default grays. Do:
|
|
50
|
+
anchor on one non-default family — clay/ochre/terracotta, ink/bone/mustard,
|
|
51
|
+
charcoal/lime, oxblood/cream, navy/copper, warm paper (`#FBF7F0`) over pure
|
|
52
|
+
white — with one decisive accent used sparingly for hierarchy, not decoration.
|
|
53
|
+
- **Layout.** Don't: centered hero + one CTA + a row of three icon cards,
|
|
54
|
+
rounded-everything, `0.1`-opacity drop shadows, blanket glassmorphism, or the
|
|
55
|
+
badge-above-headline cliché. Do: asymmetric 60/40 or 70/30 splits, uneven
|
|
56
|
+
visual weight, one clear focal point, and flat confident surfaces.
|
|
57
|
+
- **Background.** Don't: a single flat fill. Do: layered gradients, a geometric
|
|
58
|
+
pattern, grain, or a contextual texture that matches the theme.
|
|
59
|
+
- **Copy & voice.** Don't: lorem ipsum or buzzword filler ("empower", "seamless",
|
|
60
|
+
"leverage", "revolutionize", "in today's fast-paced world"). Do: realistic
|
|
61
|
+
domain content in a specific voice — copy is design material.
|
|
62
|
+
|
|
63
|
+
**Second-order convergence is real.** Even your "creative" picks converge (Space
|
|
64
|
+
Grotesk everywhere; teal accent + blinking dot + left accent bars). Vary
|
|
65
|
+
deliberately across generations so two designs never share a fingerprint.
|
|
66
|
+
|
|
67
|
+
**Principles to quote back while building:** color creates hierarchy, not
|
|
68
|
+
decoration · density over decoration · earn every animation · commit to one point
|
|
69
|
+
of view. **Match code to the vision** — maximalist themes want elaborate motion
|
|
70
|
+
and effects; minimal themes want restraint and precise spacing. Elegance is
|
|
71
|
+
executing one vision fully.
|
|
72
|
+
|
|
73
|
+
**References beat adjectives, but only with a reason.** "Linear: the quiet
|
|
74
|
+
confidence of its spacing" or "Stripe: dense but never crowded" points somewhere
|
|
75
|
+
specific; "Linear" alone collapses back to the average, and replying to your own
|
|
76
|
+
output with "make it cleaner / more premium" means you're negotiating with vibes.
|
|
37
77
|
|
|
38
78
|
## Prompt the design in four layers
|
|
39
79
|
|
|
@@ -70,6 +110,23 @@ Pick a preset by `projectType`:
|
|
|
70
110
|
`:root` CSS variable. Never hardcode `text-white` / `bg-black` / hex literals
|
|
71
111
|
in the markup — that's what keeps brand + multi-screen consistency automatic.
|
|
72
112
|
|
|
113
|
+
## Building on existing code, screens, or a design system
|
|
114
|
+
|
|
115
|
+
When a design system, tokens, current screens, or a connected codebase already
|
|
116
|
+
exist, the slop risk flips: the failure is ignoring the brand and reverting to
|
|
117
|
+
defaults. The banned-defaults list above still applies, plus:
|
|
118
|
+
|
|
119
|
+
- **Inspect before inventing.** Read the linked design system, the current
|
|
120
|
+
`:root` tokens, and existing screens (or the connected localhost/repo) first.
|
|
121
|
+
Derive the type scale, palette, radius, density, and component language from
|
|
122
|
+
what is actually there — don't restate a generic direction.
|
|
123
|
+
- **Treat every reversion as a missing spec entry.** If output drifts to a
|
|
124
|
+
default (Inter, pill buttons, a stock radius) despite the brand, don't just
|
|
125
|
+
re-prompt — pin the explicit value into `:root` so it can't drift again.
|
|
126
|
+
- **Consistency is not sameness.** Tokens alone make every screen "the same in
|
|
127
|
+
your colors". Keep structure and layout genuinely varied per screen while the
|
|
128
|
+
palette, type, and components stay on-brand.
|
|
129
|
+
|
|
73
130
|
## Generation Workflow — the canonical 4-phase flow
|
|
74
131
|
|
|
75
132
|
This flow mirrors Claude Design's UX: ask → show variants → user picks → refine. Don't skip phases for new designs.
|
|
@@ -502,9 +559,8 @@ regeneration is slow, expensive, and regresses unrelated parts.
|
|
|
502
559
|
|
|
503
560
|
## What NOT to Do
|
|
504
561
|
|
|
505
|
-
-
|
|
506
|
-
|
|
507
|
-
blinking-dot + three-column-hero cliché — see the Aesthetic Quality Bar.
|
|
562
|
+
- For aesthetics (fonts, palette, layout, backgrounds, copy), see the Aesthetic
|
|
563
|
+
quality bar above — every banned default there is out unless the user asks.
|
|
508
564
|
- Never link prototype screens with real/relative URLs — use Alpine state,
|
|
509
565
|
`data-screen`, or `#` anchors (see Multi-screen prototypes & navigation).
|
|
510
566
|
- Never hardcode colors — always reference CSS custom properties (no raw
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -360,6 +360,16 @@ export function isScreenRootElementInfo(info: ElementInfo | null | undefined) {
|
|
|
360
360
|
return tagName === "BODY" || tagName === "HTML";
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
+
export function shouldMirrorSelectedElementToAgentChat(
|
|
364
|
+
info: ElementInfo | null | undefined,
|
|
365
|
+
): info is ElementInfo {
|
|
366
|
+
if (!info || isScreenRootElementInfo(info)) return false;
|
|
367
|
+
const text = info.textContent?.replace(/\s+/g, " ").trim();
|
|
368
|
+
if (!text) return true;
|
|
369
|
+
const labelText = text.replace(/^[^A-Za-z0-9]+/, "").toLowerCase();
|
|
370
|
+
return !labelText.startsWith("nothing here yet");
|
|
371
|
+
}
|
|
372
|
+
|
|
363
373
|
export function shouldIgnoreOverviewLayerCreationEcho(args: {
|
|
364
374
|
pendingLayerId: string | null | undefined;
|
|
365
375
|
pendingScreenId: string | null | undefined;
|
|
@@ -9162,7 +9172,7 @@ export default function DesignEditor() {
|
|
|
9162
9172
|
|
|
9163
9173
|
useEffect(() => {
|
|
9164
9174
|
const key = "design:selected-element";
|
|
9165
|
-
if (!id || !selectedElement) {
|
|
9175
|
+
if (!id || !shouldMirrorSelectedElementToAgentChat(selectedElement)) {
|
|
9166
9176
|
removeAgentChatContextItem(key);
|
|
9167
9177
|
return;
|
|
9168
9178
|
}
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -103,7 +103,7 @@ export function getContextWindowForModel(modelId) {
|
|
|
103
103
|
return 1_048_576;
|
|
104
104
|
return DEFAULT_CONTEXT_WINDOW;
|
|
105
105
|
}
|
|
106
|
-
const ENABLE_CLAUDE_SONNET_5 =
|
|
106
|
+
const ENABLE_CLAUDE_SONNET_5 = true;
|
|
107
107
|
export const CLAUDE_SONNET_MODEL_ID = ENABLE_CLAUDE_SONNET_5
|
|
108
108
|
? "claude-sonnet-5"
|
|
109
109
|
: "claude-sonnet-4-6";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-config.js","sourceRoot":"","sources":["../../src/agent/model-config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Central model catalog for built-in agent engines.\n *\n * To bump the framework's managed default, update the Anthropic/OpenAI\n * constants below. Builder gateway and OpenRouter IDs are derived here so the\n * usual default bump stays in one file.\n */\n\n// ---------------------------------------------------------------------------\n// Per-model context window table (input token limit)\n//\n// Sources (June 2026):\n// Anthropic https://platform.claude.com/docs/en/about-claude/models/overview\n// OpenAI https://developers.openai.com/api/docs/models/gpt-5.5\n// https://developers.openai.com/api/docs/models/gpt-5.4\n// Google https://ai.google.dev/gemini-api/docs/models\n// OpenRouter https://openrouter.ai/api/v1/models\n//\n// Family defaults (used when a model id isn't listed explicitly):\n// claude-* → 200_000 (Haiku 4.5 and earlier models)\n// gpt-5* → 1_050_000 (GPT-5.4/5.5 flagship context)\n// gemini-2* / gemini-3* → 1_048_576\n// everything else → 128_000 (safe conservative floor)\n//\n// Note: Fable 5, Sonnet 5, Sonnet 4.6, and Opus 4.6/4.7/4.8 support 1M via the API\n// at standard prices.\n// ---------------------------------------------------------------------------\n\nconst MODEL_CONTEXT_WINDOWS: Record<string, number> = {\n // ── Anthropic / Claude (via Builder gateway or Anthropic direct) ──────────\n \"claude-fable-5\": 1_000_000,\n \"claude-opus-4-8\": 1_000_000,\n \"claude-opus-4-7\": 1_000_000,\n \"claude-sonnet-5\": 1_000_000,\n \"claude-sonnet-4-6\": 1_000_000,\n \"claude-haiku-4-5\": 200_000,\n \"claude-haiku-4-5-20251001\": 200_000,\n\n // ── Builder gateway OpenAI IDs (dot→dash) ────────────────────────────────\n \"gpt-5-5\": 1_050_000,\n \"gpt-5-4\": 1_050_000,\n \"gpt-5-4-mini\": 400_000,\n\n // ── Gemini (Builder gateway IDs) ─────────────────────────────────────────\n \"gemini-3-1-pro\": 1_048_576,\n \"gemini-3-5-flash\": 1_048_576,\n \"gemini-3-1-flash-lite\": 1_048_576,\n\n // ── OpenRouter model IDs ──────────────────────────────────────────────────\n \"anthropic/claude-fable-5\": 1_000_000,\n \"anthropic/claude-opus-4.8\": 1_000_000,\n \"anthropic/claude-opus-4.7\": 1_000_000,\n \"anthropic/claude-sonnet-5\": 1_000_000,\n \"anthropic/claude-sonnet-4.6\": 1_000_000,\n \"openai/gpt-5.5\": 1_050_000,\n \"openai/gpt-5.4\": 1_050_000,\n \"google/gemini-2.5-flash\": 1_048_576,\n \"z-ai/glm-5.2\": 1_048_576,\n\n // ── AI-SDK native OpenAI IDs ──────────────────────────────────────────────\n \"gpt-5.5\": 1_050_000,\n \"gpt-5.4\": 1_050_000,\n \"gpt-5.4-mini\": 400_000,\n\n // ── AI-SDK native Google IDs ──────────────────────────────────────────────\n \"gemini-3.5-flash\": 1_048_576,\n \"gemini-3.1-pro-preview\": 1_048_576,\n \"gemini-2.5-flash\": 1_048_576,\n \"gemini-2.5-pro\": 1_048_576,\n};\n\n/** Conservative safe default when a model is not in the table. */\nconst DEFAULT_CONTEXT_WINDOW = 128_000;\n\n/**\n * Return the known input-token context window for the given model ID.\n *\n * Uses an exact-match table first, then falls back to family-prefix heuristics,\n * then a conservative 128 K default. Never throws — always returns a positive\n * integer.\n */\nexport function getContextWindowForModel(modelId: string): number {\n if (!modelId) return DEFAULT_CONTEXT_WINDOW;\n\n const exact = MODEL_CONTEXT_WINDOWS[modelId];\n if (exact !== undefined) return exact;\n\n // Family heuristics for unlisted model IDs\n const id = modelId.toLowerCase();\n\n // Anthropic Fable 5, Opus 4.x, Sonnet 5, and Sonnet 4.6 = 1M\n if (\n id === \"claude-fable-5\" ||\n id.includes(\"claude-fable-5\") ||\n id.startsWith(\"claude-opus-4\") ||\n id.includes(\"claude-sonnet-5\") ||\n id.includes(\"claude-sonnet-4-6\") ||\n id.includes(\"claude-sonnet-4.6\")\n )\n return 1_000_000;\n\n // All other Claude models — default 200K\n if (id.startsWith(\"claude-\")) return 200_000;\n\n // GPT-5.x family — 1.05M\n if (id.startsWith(\"gpt-5\") || id.startsWith(\"openai/gpt-5\")) return 1_050_000;\n\n // Gemini 2.x / 3.x — 1M\n if (\n id.startsWith(\"gemini-2\") ||\n id.startsWith(\"gemini-3\") ||\n id.includes(\"/gemini-2\") ||\n id.includes(\"/gemini-3\")\n )\n return 1_048_576;\n\n // Z.ai GLM 5.x on OpenRouter — 1M context.\n if (id.startsWith(\"glm-5\") || id.includes(\"/glm-5\")) return 1_048_576;\n\n return DEFAULT_CONTEXT_WINDOW;\n}\n\nconst ENABLE_CLAUDE_SONNET_5 = false;\n\nexport const CLAUDE_SONNET_MODEL_ID = ENABLE_CLAUDE_SONNET_5\n ? \"claude-sonnet-5\"\n : \"claude-sonnet-4-6\";\nexport const CLAUDE_SONNET_MODEL_LABEL = ENABLE_CLAUDE_SONNET_5\n ? \"Claude Sonnet 5\"\n : \"Claude Sonnet 4.6\";\n\nconst OPENROUTER_CLAUDE_SONNET_MODEL_ID = ENABLE_CLAUDE_SONNET_5\n ? \"anthropic/claude-sonnet-5\"\n : \"anthropic/claude-sonnet-4.6\";\n\nconst ANTHROPIC_DEFAULT_MODEL_ID = CLAUDE_SONNET_MODEL_ID;\n\nfunction builderGatewayModelId(model: string): string {\n return model.replace(/\\./g, \"-\");\n}\n\nfunction openRouterModelId(provider: string, model: string): string {\n return `${provider}/${model}`;\n}\n\nconst FRAMEWORK_DEFAULT_OPENAI_MODEL = \"gpt-5.5\";\nconst FRAMEWORK_DEFAULT_BUILDER_MODEL = ANTHROPIC_DEFAULT_MODEL_ID;\nconst FRAMEWORK_DEFAULT_BUILDER_OPENAI_MODEL = builderGatewayModelId(\n FRAMEWORK_DEFAULT_OPENAI_MODEL,\n);\nconst FRAMEWORK_DEFAULT_OPENROUTER_MODEL = openRouterModelId(\n \"openai\",\n FRAMEWORK_DEFAULT_OPENAI_MODEL,\n);\n\nexport const AGENT_MODEL_CONFIG = {\n builder: {\n defaultModel: FRAMEWORK_DEFAULT_BUILDER_MODEL,\n supportedModels: [\n \"auto\",\n \"claude-opus-4-8\",\n CLAUDE_SONNET_MODEL_ID,\n \"claude-haiku-4-5\",\n FRAMEWORK_DEFAULT_BUILDER_OPENAI_MODEL,\n \"gpt-5-4\",\n \"gpt-5-4-mini\",\n \"gemini-3-1-pro\",\n \"gemini-3-5-flash\",\n \"gemini-3-1-flash-lite\",\n \"grok-code-fast\",\n \"qwen3-coder\",\n ],\n },\n anthropic: {\n defaultModel: ANTHROPIC_DEFAULT_MODEL_ID,\n supportedModels: [\n \"claude-fable-5\",\n \"claude-opus-4-8\",\n CLAUDE_SONNET_MODEL_ID,\n \"claude-haiku-4-5-20251001\",\n ],\n },\n aiSdk: {\n anthropic: {\n defaultModel: ANTHROPIC_DEFAULT_MODEL_ID,\n supportedModels: [\n \"claude-fable-5\",\n \"claude-opus-4-8\",\n CLAUDE_SONNET_MODEL_ID,\n \"claude-haiku-4-5-20251001\",\n ],\n },\n openai: {\n defaultModel: FRAMEWORK_DEFAULT_OPENAI_MODEL,\n supportedModels: [\n FRAMEWORK_DEFAULT_OPENAI_MODEL,\n \"gpt-5.4\",\n \"gpt-5.4-mini\",\n ],\n },\n openrouter: {\n defaultModel: FRAMEWORK_DEFAULT_OPENROUTER_MODEL,\n supportedModels: [\n \"anthropic/claude-fable-5\",\n \"anthropic/claude-opus-4.8\",\n OPENROUTER_CLAUDE_SONNET_MODEL_ID,\n FRAMEWORK_DEFAULT_OPENROUTER_MODEL,\n \"openai/gpt-5.4\",\n // Current stable Gemini on OpenRouter (2.5 Flash is GA)\n \"google/gemini-2.5-flash\",\n \"z-ai/glm-5.2\",\n ],\n },\n google: {\n defaultModel: \"gemini-3.5-flash\",\n supportedModels: [\"gemini-3.5-flash\", \"gemini-3.1-pro-preview\"],\n },\n groq: {\n // llama-3.1-70b-versatile and mixtral-8x7b-32768 were decommissioned\n // (errors since Jan 2025 and Mar 2025 respectively). Replace with current\n // Groq production models.\n defaultModel: \"llama-3.3-70b-versatile\",\n supportedModels: [\n \"llama-3.3-70b-versatile\",\n \"llama3-8b-8192\",\n \"llama-3.1-8b-instant\",\n ],\n },\n mistral: {\n defaultModel: \"mistral-large-latest\",\n supportedModels: [\n \"mistral-large-latest\",\n \"mistral-medium-latest\",\n \"mistral-small-latest\",\n ],\n },\n cohere: {\n // command-r-plus (unversioned) is an alias that may lag; the stable\n // dated release is command-r-plus-08-2024.\n defaultModel: \"command-r-plus-08-2024\",\n supportedModels: [\n \"command-r-plus-08-2024\",\n \"command-r-plus\",\n \"command-r\",\n ],\n },\n ollama: {\n defaultModel: \"llama3.1\",\n supportedModels: [\"llama3.1\", \"llama3.2\", \"mistral\", \"codestral\"],\n },\n },\n} as const;\n\nexport const BUILDER_MODEL_CONFIG = AGENT_MODEL_CONFIG.builder;\nexport const ANTHROPIC_MODEL_CONFIG = AGENT_MODEL_CONFIG.anthropic;\nexport const AI_SDK_MODEL_CONFIG = AGENT_MODEL_CONFIG.aiSdk;\n\nexport type AISDKProvider = keyof typeof AI_SDK_MODEL_CONFIG;\n\nexport const DEFAULT_MODEL = BUILDER_MODEL_CONFIG.defaultModel;\nexport const DEFAULT_OPENAI_MODEL = AI_SDK_MODEL_CONFIG.openai.defaultModel;\nexport const DEFAULT_ANTHROPIC_MODEL = ANTHROPIC_MODEL_CONFIG.defaultModel;\n"]}
|
|
1
|
+
{"version":3,"file":"model-config.js","sourceRoot":"","sources":["../../src/agent/model-config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,8EAA8E;AAC9E,qDAAqD;AACrD,EAAE;AACF,uBAAuB;AACvB,+EAA+E;AAC/E,oEAAoE;AACpE,oEAAoE;AACpE,2DAA2D;AAC3D,kDAAkD;AAClD,EAAE;AACF,kEAAkE;AAClE,6DAA6D;AAC7D,8DAA8D;AAC9D,qCAAqC;AACrC,wDAAwD;AACxD,EAAE;AACF,mFAAmF;AACnF,sBAAsB;AACtB,8EAA8E;AAE9E,MAAM,qBAAqB,GAA2B;IACpD,6EAA6E;IAC7E,gBAAgB,EAAE,SAAS;IAC3B,iBAAiB,EAAE,SAAS;IAC5B,iBAAiB,EAAE,SAAS;IAC5B,iBAAiB,EAAE,SAAS;IAC5B,mBAAmB,EAAE,SAAS;IAC9B,kBAAkB,EAAE,OAAO;IAC3B,2BAA2B,EAAE,OAAO;IAEpC,4EAA4E;IAC5E,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,cAAc,EAAE,OAAO;IAEvB,4EAA4E;IAC5E,gBAAgB,EAAE,SAAS;IAC3B,kBAAkB,EAAE,SAAS;IAC7B,uBAAuB,EAAE,SAAS;IAElC,6EAA6E;IAC7E,0BAA0B,EAAE,SAAS;IACrC,2BAA2B,EAAE,SAAS;IACtC,2BAA2B,EAAE,SAAS;IACtC,2BAA2B,EAAE,SAAS;IACtC,6BAA6B,EAAE,SAAS;IACxC,gBAAgB,EAAE,SAAS;IAC3B,gBAAgB,EAAE,SAAS;IAC3B,yBAAyB,EAAE,SAAS;IACpC,cAAc,EAAE,SAAS;IAEzB,6EAA6E;IAC7E,SAAS,EAAE,SAAS;IACpB,SAAS,EAAE,SAAS;IACpB,cAAc,EAAE,OAAO;IAEvB,6EAA6E;IAC7E,kBAAkB,EAAE,SAAS;IAC7B,wBAAwB,EAAE,SAAS;IACnC,kBAAkB,EAAE,SAAS;IAC7B,gBAAgB,EAAE,SAAS;CAC5B,CAAC;AAEF,kEAAkE;AAClE,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,IAAI,CAAC,OAAO;QAAE,OAAO,sBAAsB,CAAC;IAE5C,MAAM,KAAK,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEtC,2CAA2C;IAC3C,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEjC,6DAA6D;IAC7D,IACE,EAAE,KAAK,gBAAgB;QACvB,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAC7B,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC;QAC9B,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAC9B,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAChC,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAEhC,OAAO,SAAS,CAAC;IAEnB,yCAAyC;IACzC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,OAAO,CAAC;IAE7C,yBAAyB;IACzB,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC;QAAE,OAAO,SAAS,CAAC;IAE9E,wBAAwB;IACxB,IACE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QACzB,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QACzB,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;QACxB,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;QAExB,OAAO,SAAS,CAAC;IAEnB,2CAA2C;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAEtE,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAED,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAEpC,MAAM,CAAC,MAAM,sBAAsB,GAAG,sBAAsB;IAC1D,CAAC,CAAC,iBAAiB;IACnB,CAAC,CAAC,mBAAmB,CAAC;AACxB,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB;IAC7D,CAAC,CAAC,iBAAiB;IACnB,CAAC,CAAC,mBAAmB,CAAC;AAExB,MAAM,iCAAiC,GAAG,sBAAsB;IAC9D,CAAC,CAAC,2BAA2B;IAC7B,CAAC,CAAC,6BAA6B,CAAC;AAElC,MAAM,0BAA0B,GAAG,sBAAsB,CAAC;AAE1D,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB,EAAE,KAAa;IACxD,OAAO,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,8BAA8B,GAAG,SAAS,CAAC;AACjD,MAAM,+BAA+B,GAAG,0BAA0B,CAAC;AACnE,MAAM,sCAAsC,GAAG,qBAAqB,CAClE,8BAA8B,CAC/B,CAAC;AACF,MAAM,kCAAkC,GAAG,iBAAiB,CAC1D,QAAQ,EACR,8BAA8B,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE;QACP,YAAY,EAAE,+BAA+B;QAC7C,eAAe,EAAE;YACf,MAAM;YACN,iBAAiB;YACjB,sBAAsB;YACtB,kBAAkB;YAClB,sCAAsC;YACtC,SAAS;YACT,cAAc;YACd,gBAAgB;YAChB,kBAAkB;YAClB,uBAAuB;YACvB,gBAAgB;YAChB,aAAa;SACd;KACF;IACD,SAAS,EAAE;QACT,YAAY,EAAE,0BAA0B;QACxC,eAAe,EAAE;YACf,gBAAgB;YAChB,iBAAiB;YACjB,sBAAsB;YACtB,2BAA2B;SAC5B;KACF;IACD,KAAK,EAAE;QACL,SAAS,EAAE;YACT,YAAY,EAAE,0BAA0B;YACxC,eAAe,EAAE;gBACf,gBAAgB;gBAChB,iBAAiB;gBACjB,sBAAsB;gBACtB,2BAA2B;aAC5B;SACF;QACD,MAAM,EAAE;YACN,YAAY,EAAE,8BAA8B;YAC5C,eAAe,EAAE;gBACf,8BAA8B;gBAC9B,SAAS;gBACT,cAAc;aACf;SACF;QACD,UAAU,EAAE;YACV,YAAY,EAAE,kCAAkC;YAChD,eAAe,EAAE;gBACf,0BAA0B;gBAC1B,2BAA2B;gBAC3B,iCAAiC;gBACjC,kCAAkC;gBAClC,gBAAgB;gBAChB,wDAAwD;gBACxD,yBAAyB;gBACzB,cAAc;aACf;SACF;QACD,MAAM,EAAE;YACN,YAAY,EAAE,kBAAkB;YAChC,eAAe,EAAE,CAAC,kBAAkB,EAAE,wBAAwB,CAAC;SAChE;QACD,IAAI,EAAE;YACJ,qEAAqE;YACrE,0EAA0E;YAC1E,0BAA0B;YAC1B,YAAY,EAAE,yBAAyB;YACvC,eAAe,EAAE;gBACf,yBAAyB;gBACzB,gBAAgB;gBAChB,sBAAsB;aACvB;SACF;QACD,OAAO,EAAE;YACP,YAAY,EAAE,sBAAsB;YACpC,eAAe,EAAE;gBACf,sBAAsB;gBACtB,uBAAuB;gBACvB,sBAAsB;aACvB;SACF;QACD,MAAM,EAAE;YACN,oEAAoE;YACpE,2CAA2C;YAC3C,YAAY,EAAE,wBAAwB;YACtC,eAAe,EAAE;gBACf,wBAAwB;gBACxB,gBAAgB;gBAChB,WAAW;aACZ;SACF;QACD,MAAM,EAAE;YACN,YAAY,EAAE,UAAU;YACxB,eAAe,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC;SAClE;KACF;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,OAAO,CAAC;AAC/D,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAAkB,CAAC,SAAS,CAAC;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,KAAK,CAAC;AAI5D,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAC,YAAY,CAAC;AAC/D,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,MAAM,CAAC,YAAY,CAAC;AAC5E,MAAM,CAAC,MAAM,uBAAuB,GAAG,sBAAsB,CAAC,YAAY,CAAC","sourcesContent":["/**\n * Central model catalog for built-in agent engines.\n *\n * To bump the framework's managed default, update the Anthropic/OpenAI\n * constants below. Builder gateway and OpenRouter IDs are derived here so the\n * usual default bump stays in one file.\n */\n\n// ---------------------------------------------------------------------------\n// Per-model context window table (input token limit)\n//\n// Sources (June 2026):\n// Anthropic https://platform.claude.com/docs/en/about-claude/models/overview\n// OpenAI https://developers.openai.com/api/docs/models/gpt-5.5\n// https://developers.openai.com/api/docs/models/gpt-5.4\n// Google https://ai.google.dev/gemini-api/docs/models\n// OpenRouter https://openrouter.ai/api/v1/models\n//\n// Family defaults (used when a model id isn't listed explicitly):\n// claude-* → 200_000 (Haiku 4.5 and earlier models)\n// gpt-5* → 1_050_000 (GPT-5.4/5.5 flagship context)\n// gemini-2* / gemini-3* → 1_048_576\n// everything else → 128_000 (safe conservative floor)\n//\n// Note: Fable 5, Sonnet 5, Sonnet 4.6, and Opus 4.6/4.7/4.8 support 1M via the API\n// at standard prices.\n// ---------------------------------------------------------------------------\n\nconst MODEL_CONTEXT_WINDOWS: Record<string, number> = {\n // ── Anthropic / Claude (via Builder gateway or Anthropic direct) ──────────\n \"claude-fable-5\": 1_000_000,\n \"claude-opus-4-8\": 1_000_000,\n \"claude-opus-4-7\": 1_000_000,\n \"claude-sonnet-5\": 1_000_000,\n \"claude-sonnet-4-6\": 1_000_000,\n \"claude-haiku-4-5\": 200_000,\n \"claude-haiku-4-5-20251001\": 200_000,\n\n // ── Builder gateway OpenAI IDs (dot→dash) ────────────────────────────────\n \"gpt-5-5\": 1_050_000,\n \"gpt-5-4\": 1_050_000,\n \"gpt-5-4-mini\": 400_000,\n\n // ── Gemini (Builder gateway IDs) ─────────────────────────────────────────\n \"gemini-3-1-pro\": 1_048_576,\n \"gemini-3-5-flash\": 1_048_576,\n \"gemini-3-1-flash-lite\": 1_048_576,\n\n // ── OpenRouter model IDs ──────────────────────────────────────────────────\n \"anthropic/claude-fable-5\": 1_000_000,\n \"anthropic/claude-opus-4.8\": 1_000_000,\n \"anthropic/claude-opus-4.7\": 1_000_000,\n \"anthropic/claude-sonnet-5\": 1_000_000,\n \"anthropic/claude-sonnet-4.6\": 1_000_000,\n \"openai/gpt-5.5\": 1_050_000,\n \"openai/gpt-5.4\": 1_050_000,\n \"google/gemini-2.5-flash\": 1_048_576,\n \"z-ai/glm-5.2\": 1_048_576,\n\n // ── AI-SDK native OpenAI IDs ──────────────────────────────────────────────\n \"gpt-5.5\": 1_050_000,\n \"gpt-5.4\": 1_050_000,\n \"gpt-5.4-mini\": 400_000,\n\n // ── AI-SDK native Google IDs ──────────────────────────────────────────────\n \"gemini-3.5-flash\": 1_048_576,\n \"gemini-3.1-pro-preview\": 1_048_576,\n \"gemini-2.5-flash\": 1_048_576,\n \"gemini-2.5-pro\": 1_048_576,\n};\n\n/** Conservative safe default when a model is not in the table. */\nconst DEFAULT_CONTEXT_WINDOW = 128_000;\n\n/**\n * Return the known input-token context window for the given model ID.\n *\n * Uses an exact-match table first, then falls back to family-prefix heuristics,\n * then a conservative 128 K default. Never throws — always returns a positive\n * integer.\n */\nexport function getContextWindowForModel(modelId: string): number {\n if (!modelId) return DEFAULT_CONTEXT_WINDOW;\n\n const exact = MODEL_CONTEXT_WINDOWS[modelId];\n if (exact !== undefined) return exact;\n\n // Family heuristics for unlisted model IDs\n const id = modelId.toLowerCase();\n\n // Anthropic Fable 5, Opus 4.x, Sonnet 5, and Sonnet 4.6 = 1M\n if (\n id === \"claude-fable-5\" ||\n id.includes(\"claude-fable-5\") ||\n id.startsWith(\"claude-opus-4\") ||\n id.includes(\"claude-sonnet-5\") ||\n id.includes(\"claude-sonnet-4-6\") ||\n id.includes(\"claude-sonnet-4.6\")\n )\n return 1_000_000;\n\n // All other Claude models — default 200K\n if (id.startsWith(\"claude-\")) return 200_000;\n\n // GPT-5.x family — 1.05M\n if (id.startsWith(\"gpt-5\") || id.startsWith(\"openai/gpt-5\")) return 1_050_000;\n\n // Gemini 2.x / 3.x — 1M\n if (\n id.startsWith(\"gemini-2\") ||\n id.startsWith(\"gemini-3\") ||\n id.includes(\"/gemini-2\") ||\n id.includes(\"/gemini-3\")\n )\n return 1_048_576;\n\n // Z.ai GLM 5.x on OpenRouter — 1M context.\n if (id.startsWith(\"glm-5\") || id.includes(\"/glm-5\")) return 1_048_576;\n\n return DEFAULT_CONTEXT_WINDOW;\n}\n\nconst ENABLE_CLAUDE_SONNET_5 = true;\n\nexport const CLAUDE_SONNET_MODEL_ID = ENABLE_CLAUDE_SONNET_5\n ? \"claude-sonnet-5\"\n : \"claude-sonnet-4-6\";\nexport const CLAUDE_SONNET_MODEL_LABEL = ENABLE_CLAUDE_SONNET_5\n ? \"Claude Sonnet 5\"\n : \"Claude Sonnet 4.6\";\n\nconst OPENROUTER_CLAUDE_SONNET_MODEL_ID = ENABLE_CLAUDE_SONNET_5\n ? \"anthropic/claude-sonnet-5\"\n : \"anthropic/claude-sonnet-4.6\";\n\nconst ANTHROPIC_DEFAULT_MODEL_ID = CLAUDE_SONNET_MODEL_ID;\n\nfunction builderGatewayModelId(model: string): string {\n return model.replace(/\\./g, \"-\");\n}\n\nfunction openRouterModelId(provider: string, model: string): string {\n return `${provider}/${model}`;\n}\n\nconst FRAMEWORK_DEFAULT_OPENAI_MODEL = \"gpt-5.5\";\nconst FRAMEWORK_DEFAULT_BUILDER_MODEL = ANTHROPIC_DEFAULT_MODEL_ID;\nconst FRAMEWORK_DEFAULT_BUILDER_OPENAI_MODEL = builderGatewayModelId(\n FRAMEWORK_DEFAULT_OPENAI_MODEL,\n);\nconst FRAMEWORK_DEFAULT_OPENROUTER_MODEL = openRouterModelId(\n \"openai\",\n FRAMEWORK_DEFAULT_OPENAI_MODEL,\n);\n\nexport const AGENT_MODEL_CONFIG = {\n builder: {\n defaultModel: FRAMEWORK_DEFAULT_BUILDER_MODEL,\n supportedModels: [\n \"auto\",\n \"claude-opus-4-8\",\n CLAUDE_SONNET_MODEL_ID,\n \"claude-haiku-4-5\",\n FRAMEWORK_DEFAULT_BUILDER_OPENAI_MODEL,\n \"gpt-5-4\",\n \"gpt-5-4-mini\",\n \"gemini-3-1-pro\",\n \"gemini-3-5-flash\",\n \"gemini-3-1-flash-lite\",\n \"grok-code-fast\",\n \"qwen3-coder\",\n ],\n },\n anthropic: {\n defaultModel: ANTHROPIC_DEFAULT_MODEL_ID,\n supportedModels: [\n \"claude-fable-5\",\n \"claude-opus-4-8\",\n CLAUDE_SONNET_MODEL_ID,\n \"claude-haiku-4-5-20251001\",\n ],\n },\n aiSdk: {\n anthropic: {\n defaultModel: ANTHROPIC_DEFAULT_MODEL_ID,\n supportedModels: [\n \"claude-fable-5\",\n \"claude-opus-4-8\",\n CLAUDE_SONNET_MODEL_ID,\n \"claude-haiku-4-5-20251001\",\n ],\n },\n openai: {\n defaultModel: FRAMEWORK_DEFAULT_OPENAI_MODEL,\n supportedModels: [\n FRAMEWORK_DEFAULT_OPENAI_MODEL,\n \"gpt-5.4\",\n \"gpt-5.4-mini\",\n ],\n },\n openrouter: {\n defaultModel: FRAMEWORK_DEFAULT_OPENROUTER_MODEL,\n supportedModels: [\n \"anthropic/claude-fable-5\",\n \"anthropic/claude-opus-4.8\",\n OPENROUTER_CLAUDE_SONNET_MODEL_ID,\n FRAMEWORK_DEFAULT_OPENROUTER_MODEL,\n \"openai/gpt-5.4\",\n // Current stable Gemini on OpenRouter (2.5 Flash is GA)\n \"google/gemini-2.5-flash\",\n \"z-ai/glm-5.2\",\n ],\n },\n google: {\n defaultModel: \"gemini-3.5-flash\",\n supportedModels: [\"gemini-3.5-flash\", \"gemini-3.1-pro-preview\"],\n },\n groq: {\n // llama-3.1-70b-versatile and mixtral-8x7b-32768 were decommissioned\n // (errors since Jan 2025 and Mar 2025 respectively). Replace with current\n // Groq production models.\n defaultModel: \"llama-3.3-70b-versatile\",\n supportedModels: [\n \"llama-3.3-70b-versatile\",\n \"llama3-8b-8192\",\n \"llama-3.1-8b-instant\",\n ],\n },\n mistral: {\n defaultModel: \"mistral-large-latest\",\n supportedModels: [\n \"mistral-large-latest\",\n \"mistral-medium-latest\",\n \"mistral-small-latest\",\n ],\n },\n cohere: {\n // command-r-plus (unversioned) is an alias that may lag; the stable\n // dated release is command-r-plus-08-2024.\n defaultModel: \"command-r-plus-08-2024\",\n supportedModels: [\n \"command-r-plus-08-2024\",\n \"command-r-plus\",\n \"command-r\",\n ],\n },\n ollama: {\n defaultModel: \"llama3.1\",\n supportedModels: [\"llama3.1\", \"llama3.2\", \"mistral\", \"codestral\"],\n },\n },\n} as const;\n\nexport const BUILDER_MODEL_CONFIG = AGENT_MODEL_CONFIG.builder;\nexport const ANTHROPIC_MODEL_CONFIG = AGENT_MODEL_CONFIG.anthropic;\nexport const AI_SDK_MODEL_CONFIG = AGENT_MODEL_CONFIG.aiSdk;\n\nexport type AISDKProvider = keyof typeof AI_SDK_MODEL_CONFIG;\n\nexport const DEFAULT_MODEL = BUILDER_MODEL_CONFIG.defaultModel;\nexport const DEFAULT_OPENAI_MODEL = AI_SDK_MODEL_CONFIG.openai.defaultModel;\nexport const DEFAULT_ANTHROPIC_MODEL = ANTHROPIC_MODEL_CONFIG.defaultModel;\n"]}
|
package/dist/cli/skills.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAKL,KAAK,gBAAgB,EAEtB,MAAM,gBAAgB,CAAC;AAUxB,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGjE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/skills.js
CHANGED
|
@@ -343,14 +343,28 @@ iteration, or a human-in-the-loop choice among design directions.
|
|
|
343
343
|
|
|
344
344
|
## Design Quality Bar
|
|
345
345
|
|
|
346
|
+
Generic "AI slop" comes from letting one prompt set taste, explore, and emit code
|
|
347
|
+
at once — so the model returns the training-average (Inter, an indigo/violet
|
|
348
|
+
gradient, a centered hero, three rounded cards). The variant flow above exists to
|
|
349
|
+
separate those jobs; use it, and hold this bar:
|
|
350
|
+
|
|
346
351
|
- Before generating, name the concrete audience, the screen's primary job, and
|
|
347
352
|
the visual thesis. If the brief is vague, make a reasonable choice and state
|
|
348
353
|
it instead of producing a generic dashboard/landing-page default.
|
|
349
|
-
-
|
|
350
|
-
|
|
354
|
+
- Refuse the defaults, and pair every "don't" with a "do" (banning Inter alone
|
|
355
|
+
just makes you reach for Roboto). Avoid Inter/Roboto/system fonts, the
|
|
356
|
+
indigo/violet slop palette (\`#6366F1\`/\`#8B5CF6\`/\`#A855F7\`) and purple-on-white
|
|
357
|
+
gradients, and centered-hero + three-icon-card layouts; instead pick a
|
|
358
|
+
distinctive font pairing, one non-default palette family with a single decisive
|
|
359
|
+
accent, and an asymmetric layout with a clear focal point.
|
|
351
360
|
- Make each direction distinct in structure and behavior, not just palette.
|
|
352
361
|
Give every variant one memorable signature choice, then keep the surrounding
|
|
353
|
-
chrome disciplined.
|
|
362
|
+
chrome disciplined. Even your creative picks converge (Space Grotesk
|
|
363
|
+
everywhere) — vary deliberately so two directions never share a fingerprint.
|
|
364
|
+
- For existing products, inspect the current screen, design system, tokens, and
|
|
365
|
+
component language before inventing a new direction. Treat any drift back to a
|
|
366
|
+
default as a missing token to pin, and vary layout per screen so on-brand does
|
|
367
|
+
not become same-in-your-colors.
|
|
354
368
|
- Treat copy, data, and imagery as design material. Use realistic domain
|
|
355
369
|
content and first-party/generated assets when images matter; avoid lorem
|
|
356
370
|
ipsum, vague SaaS filler, and decorative placeholder boxes.
|