feat(refactor): premium zed-style chat UI, collapsible reasoning, and comprehensive strict type sweeps

This commit is contained in:
2026-05-21 17:05:42 -07:00
parent 180aa9b311
commit 8049a7f1ab
35 changed files with 5144 additions and 5789 deletions

View File

@@ -5,6 +5,8 @@ exports.streamGeminiChat = streamGeminiChat;
const genai_1 = require("@google/genai");
const GEMINI_API_KEY = process.env.GOOGLE_API_KEY || "";
const GEMINI_MODEL = process.env.VIBN_CHAT_MODEL || "gemini-3.1-pro-preview";
// Add a clear visual log so we always know exactly which model is active in the terminal
console.log(`[GeminiChat Runner] Initialized — Model: ${GEMINI_MODEL}`);
if (!GEMINI_API_KEY) {
console.warn(`[GeminiChat] WARNING: GOOGLE_API_KEY is not set. Chat stream will fail with 403 Forbidden.`);
}
@@ -73,16 +75,13 @@ async function callGeminiChat(opts) {
if (opts.systemPrompt) {
config.systemInstruction = opts.systemPrompt;
}
if (opts.includeThoughts) {
config.thinkingConfig = { thinkingBudgetTokens: 1024 };
}
const fns = toGeminiFunctions(opts.tools ?? []);
if (fns)
config.tools = fns;
const response = await ai.models.generateContent({
model: GEMINI_MODEL,
contents: toGeminiContents(opts.messages),
config
config,
});
let text = "";
let thoughts = "";
@@ -108,7 +107,7 @@ async function callGeminiChat(opts) {
text,
thoughts,
toolCalls,
finishReason: response.candidates?.[0]?.finishReason
finishReason: response.candidates?.[0]?.finishReason,
};
}
catch (error) {
@@ -125,7 +124,6 @@ async function* streamGeminiChat(opts) {
const config = {
temperature: opts.temperature ?? 0.7,
maxOutputTokens: 8192,
thinkingConfig: { thinkingBudgetTokens: 1024 },
};
if (opts.systemPrompt) {
config.systemInstruction = opts.systemPrompt;
@@ -136,7 +134,7 @@ async function* streamGeminiChat(opts) {
const streamResult = await ai.models.generateContentStream({
model: GEMINI_MODEL,
contents: toGeminiContents(opts.messages),
config
config,
});
for await (const chunk of streamResult) {
const parts = chunk.candidates?.[0]?.content?.parts ?? [];

View File

@@ -18,6 +18,7 @@ Since you are running autonomously, you must take action immediately.
A turn ends when you have fully completed the task AND shipped the code.
- **For build/edit tasks:** The natural stopping point is starting the dev server via \`dev_server_start\`, verifying it works via \`browser_console\`, and calling the \`ship\` tool to deploy to production.
- **CRITICAL:** When you successfully finish a task from the Execution Plan, you MUST call \`plan_task_complete { taskId }\` to check it off the list before moving to the next task.
- If you run into a fatal error that you cannot fix after two attempts, write a brief summary of the blocker and stop.
# Hard rules — non-negotiable

View File

@@ -91,6 +91,34 @@ exports.VIBN_TOOL_DEFINITIONS = [
required: ["projectId"],
},
},
// ── Email ───────────────────────────────────────────────────────────────
{
name: "email_send",
description: "Send an email to a user. Use this to notify users of important events, send reports, or distribute content. You can optionally design the email using MJML syntax for beautifully responsive emails.",
parameters: {
type: "OBJECT",
properties: {
projectId: {
type: "STRING",
description: "The Vibn project ID sending the email.",
},
to: { type: "STRING", description: "The recipient's email address." },
subject: {
type: "STRING",
description: "The subject line of the email.",
},
text: {
type: "STRING",
description: "The plain-text fallback body of the email.",
},
mjml: {
type: "STRING",
description: "Optional MJML markup (<mjml><mj-body>...</mj-body></mjml>). If provided, it will be automatically compiled to HTML. Do NOT provide raw HTML, only use valid MJML syntax.",
},
},
required: ["projectId", "to", "subject", "text"],
},
},
// ── Market Research & GTM ───────────────────────────────────────────────
{
name: "market_categories_suggest",
@@ -1485,26 +1513,33 @@ After this returns, ALWAYS call apps_deploy { uuid } to regenerate the live Trae
},
},
{
name: "plan_decision_log",
description: "Log a decision the user has made. Call this PROACTIVELY whenever a non-trivial choice gets settled in conversation (database engine, auth approach, framework, pricing model, copy, branding…) — so it shows up in the Plan tab and you stop re-asking it next session. Don't ask permission; log it and move on.",
name: "plan_document_update",
description: "Overwrite the content of one of the Blueprint documents in the Plan tab. These documents define the specifications for the product. ALWAYS use this instead of `fs_write` when a user asks you to update the PRD, Spec, or Architecture plan.",
parameters: {
type: "OBJECT",
properties: {
projectId: { type: "STRING", description: "The Vibn project ID." },
title: {
projectId: { type: "STRING" },
docId: {
type: "STRING",
description: 'Short topic of the decision (e.g. "Database engine", "Auth provider").',
description: "The specific document to update.",
enum: [
"stories",
"acceptance",
"success",
"ui_design",
"tech_context",
"data_model",
"file_structure",
"tasks",
"checklist",
],
},
choice: {
content: {
type: "STRING",
description: 'What was chosen (e.g. "Postgres", "Stripe Checkout").',
},
why: {
type: "STRING",
description: "Optional 1-2 sentence reasoning. Strongly recommended.",
description: "The full markdown content for the document. This will completely overwrite the existing document.",
},
},
required: ["projectId", "title", "choice"],
required: ["projectId", "docId", "content"],
},
},
{