feat: Bob AI - #671
Conversation
- Only support open router for now
- Use cheap model for tool based edits
…itor controls directly
Also make them persistent
Now AI can ask for clarification and users will get preselected options provided by AI in the form of simple chips. Users can also send custom message for clarification
- Set detailed properties and descriptions for more deterministic results
- Also add Qwen 3.6 Plus option
A full-bleed page (e.g. an all-black design) set its background only on the root <div>, so everything the div didn't cover — the preview screenshot's 1280x720 canvas, a short page's tail, overscroll — fell through to the browser's default white. Preview cards showed white leaking around dark pages. get_context now extracts the root block's background (color, var(--token), or gradient) and the template paints html,body with it, so the page fills the viewport. None when the root sets no background (unchanged). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…'t white The prior fix set html/body background via a <style> rule, but CSS background propagation to the canvas meant a stylesheet rule on html didn't reach the overscroll area (getComputedStyle(html) stayed white on the live page) — so scrolling past the top of a dark page still rubber-banded white. Setting the background as an inline style on the <html> element itself bypasses the propagation quirk: html now computes the page colour and the overscroll canvas follows it. The <style> body rule stays for the body box. Verified on the published Frame page: html background went from white to rgb(13,13,13). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A form field the agent called 'Name' scrubs to 'name' — Frappe's reserved primary key — so DocType creation threw 'Fieldname name is restricted' on Apply. Now reserved fieldnames are remapped for the DocType (name -> name_field) while the form input keeps its own name attribute; the wiring script carries an input-name -> fieldname map so the guest submit still routes to the right field. No model round-trip, no data mismatch. Verified: a 'name' field creates as 'name_field', a guest submit with the mapped key lands a record, and the generated script maps name -> name_field. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…+ DOM-ready) The tool created the DocType/Web Form/script but the form never saved. Five real bugs, found by driving the live form end-to-end: - The script targeted an invented selector (.reservation-form) and required name attrs the agent never set. Now it FINDS the form (given selector, else the tightest container with a submit control + ~N inputs) and maps inputs to fields POSITIONALLY (preferring a matching name attr). No DOM pre-wiring. - The script loads in <head>, before the form is parsed — findForm() ran too early. Now it waits for DOMContentLoaded. - It only listened for the form 'submit' event; now it also binds the submit button's click (busy-flag dedupes). - Select fields rejected the insert (HTML <select> submits its option value, not the DocType's Select option label → validation 417). Dropdowns are now stored as Data, which accepts any chosen value. - attach_form_script's update path used db.set_value, which doesn't regenerate the served .js file; now it save()s so re-runs actually update the script. Prompt: list fields in FORM ORDER; form_selector is a best-effort hint. Verified: filling the live Stillpoint form + submit lands a record (200). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ted the page Live case (Groove Vault): after the user picked layout + typography, the agent ran its build turn — searched images, minted 5 design tokens, set page settings, added a script — then stopped with 'Added a script.' It never called generate_page, so the page has zero blocks. New one-shot corrective round: when a page turn minted design tokens but the page is still EMPTY and generate_page was never called, the model is told to call generate_page now with the full brief before finishing. Independent of the no-op guard, since this turn did mutate (tokens/scripts). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…he doctype
Live case (Groove Vault): the user asked 'where is all the booking submissions?'
— a READ — and the agent proposed creating a SECOND DocType ('Groove Vault
Listening Booth Reservation') even though the form already saves to 'Groove
Listening Booth Reservation'.
- connect_form now detects an already-wired form on the page (via its
'Save <doctype> submissions' script) and, unless force_new is set, declines
with the existing DocType's Desk link so the model answers the question rather
than creating a duplicate. force_new added for a genuinely separate form.
- Prompt: a question about where a form's submissions go / how to see entries is
a read — find the DocType and reply with /app/<slug>, never connect_form.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ace-*-7) The status indicator dot used bg-ink-green-5, which isn't a real utility, so it rendered invisible — leaving a gap that read as stray left padding before the label. Switched the dot to the solid bg-surface-*-7 status colours so it shows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Show a Font token as its friendly name in violet (like Text Color shows 'Ink Dark Blue') instead of the raw var(--uuid), with a specimen 'A' prefix rendered in the resolved family. Add a 'Save as Token' action to the dropdown so a plain family can be promoted to a Font token in place, alongside the existing Upload Font action. New FontInput/FontInputActions mirror ColorInput/NewBuilderToken; the Family control swaps its inline Autocomplete for FontInput. Autocomplete's ActionButton label/handler/icon become optional (component-only actions). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two bugs stranded cost display on US$ even when the site is INR: - format.ts read a non-reactive module var, so cost lines rendered before the currency resource resolved (slow on a cold FX-rate cache) stayed USD forever. Make it a reactive ref so they re-format on load. - usd_rate used @redis_cache, which memoizes None too — a single FX timeout poisoned the cache and forced USD for 24h. Cache only on success. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVQc23yyNmnviAMJ3mXbvC
Make watching Bob build feel alive, while keeping every status truthful.
- AIBuildOverlay: ambient canvas layer during a build (top aurora bloom
+ scanning beam + breathing frame) with a top-centre narration pill
and a one-shot completion flourish. Rendered inside .page-builder so
--toolbar-height resolves (teleporting to body collapsed the region).
- BobOrb: empty-state hero orb as a self-contained WebGL shader —
translucent, flowing blue-violet aurora; CSS fallback, reduced-motion
aware, GL context cleaned up on unmount.
- Live tool status: subscribe to ai_chat_tool_activity so a long
tool-calling round narrates real per-tool work ("Set --color-primary",
"Read block: Hero") instead of a frozen "Thinking…". Only real backend
signals drive the pill — no invented step labels.
- Removed the redundant header heartbeat dot and the pill's decorative
typing-dots ellipsis.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RVQc23yyNmnviAMJ3mXbvC
c566ff6 to
21914a6
Compare
Adds a Pexels-backed video search the agent can use for ambient hero loops and b-roll: picks a browser-friendly mp4 rendition (~1080p, never a 4K monster), returns url + poster pairs, and degrades gracefully to photos or CSS motion when no key is configured or nothing matches. The system prompt gains the motion-footage recipe (muted autoplay video block behind a scrim, copy as a sibling, photo/CSS motion as the lighter default), and the model picker gains the free OpenRouter Nemotron tier for zero-cost local testing.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #671 +/- ##
===========================================
+ Coverage 57.59% 63.34% +5.74%
===========================================
Files 35 45 +10
Lines 4271 4886 +615
===========================================
+ Hits 2460 3095 +635
+ Misses 1811 1791 -20 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Zen is an OpenAI-compatible gateway with native tool calling, so models selected as `opencode/<id>` are rewritten to litellm's openai provider against https://opencode.ai/zen/v1 — no request/response shim needed. Its key is read from site_config (`zen_api_key`) rather than Builder Settings, so the free Zen models and the paid OpenRouter models work side by side instead of one replacing the other. Cloudflare fronts Zen and rejects default httpx/urllib agents with error 1010, so the call pins a User-Agent header. Registers the three free Zen models in the picker at zero cost; priced at 0.0 so the lightweight clarify/plan rounds stay on the free model instead of falling back to paid Gemini via PROVIDER_SIMPLE. Co-Authored-By: Claude <noreply@anthropic.com>
Two failure modes seen on a real generated page:
The generator made the root a two-column grid and gave the short column a
fixed height: 100vh, so the page background showed through beneath it as
browser-white. The root now carries the page's dominant backgroundColor as
a backstop, stays a vertical stack of full-width sections, and the sticky
rail recipe spells out that 100vh without position: sticky leaves the rest
of its column exposed.
The model also hand-wrote a `:root { --x: ... }` design system into a CSS
page script and referenced it from block styles. Those custom properties
are invisible to the editor's style and token panels, so the page cannot be
retuned or rethemed from the UI. Styling rules now require Builder Tokens
or literal values baked onto the block, and reserve CSS/JS page scripts for
motion and interaction only.
Co-Authored-By: Claude <noreply@anthropic.com>
OpenCode Go is a low-cost coding subscription at /zen/go/v1, distinct from Zen's /zen/v1 but sharing the same workspace key. zen_route now handles both prefixes (opencode/ -> Zen, opencode-go/ -> Go) against the right base; the shared site_config `zen_api_key` covers both. Registers Kimi K2.7 Code and K2.6 in the picker (verified: native tool calling through Go). Moonshot's Kimi models reject any temperature other than 1 with a 400, so patch_params_for_provider coerces the agent tier's 0.7 for them. Co-Authored-By: Claude <noreply@anthropic.com>
The existing rule allowed "one em dash per message at most", which weaker models over-used, and the dashboard orchestrator prompt had no dash rule at all. Tighten it everywhere the user reads Bob (editor agent, orchestrator, generation, and the copy sub-prompt): no em or en dash when any other mark works (almost always), rewrite the clause instead, dash reserved for the rare break nothing else expresses. Also removed a literal em dash from the generation copy rule so the instruction models itself. Co-Authored-By: Claude <noreply@anthropic.com>
Empty hex inputs asked users to do colour theory: most can't, and whatever they typed became law, so a sky-blue background with a dark-red primary got built verbatim. Colour slots now carry a `value` — a preset palette the model curates from the brand's world — so the default path is a harmonious palette and editing stays one tap away. An untouched preset submits with a "(suggested)" marker so the model keeps creative latitude over its own defaults, while a slot the user picked or cleared stays law in exactly the role they named. The sanitizer only lets plain hex values through to the card, and the prompt now forbids presenting blank colour slots. Co-Authored-By: Claude <noreply@anthropic.com>
Kimi ended a details-gathering turn with a bulleted list and a literal "[actions: Continue]" instead of calling present_ui, leaving the user nothing to tap. Both safety nets missed it: CARD_TEXT_RE knew the replay vocabulary (input/choices/buttons/...) but not "actions" (the schema's kind name, which the model blended into bracket notation), and the bulleted- question detector's OPTION_MARKER_RE only matched decoration markers (fonts/palette/layout/image). Bracket-notation atom names never occur in natural prose, so both regexes now cover the full atom vocabulary, replay and schema alike. Verified against the exact failing message (both detectors fire) and against normal summaries with bullets, links, and colon lists (no false positives). Co-Authored-By: Claude <noreply@anthropic.com>
|
Hi @surajshetty3416 I don't know if you've considered making the AI options more configurable. 1- Being able to choose the models. Since they're hardcoded, you lose the option to try others, or to use new ones that are less expensive or more optimal until an update is released. There could obviously be recommended models. 2- Make it more open, like Flow, with more freedom to connect OpenRouter, OpenIA, Ollama, etc. 3- This is a bit of a long shot, but the option to connect it to a CLI (for those who use it locally to set up a website, etc.) |
# Conflicts: # builder/patches.txt # frontend/src/components/BlockPropertySections/TypographySection.ts # frontend/src/pages/PageBuilder.vue # frontend/src/stores/builderStore.ts # frontend/src/utils/colorOptions.ts # frontend/src/utils/fontManager.ts # yarn.lock
56cd4e9 to
ae4fc25
Compare
# Conflicts: # builder/builder/doctype/builder_page/builder_page.py # builder/builder/doctype/builder_token/builder_token.json # builder/builder/doctype/builder_token/builder_token.py # builder/builder/doctype/builder_token/test_builder_token.py # builder/builder/patches/rename_builder_variable_to_builder_token.py # builder/templates/generators/webpage.html # builder/utils.py # frontend/components.d.ts # frontend/src/components/BlockPropertySections/TypographySection.ts # frontend/src/components/BuilderLeftPanel.vue # frontend/src/components/Controls/FontInput.vue # frontend/src/components/DashboardSidebar.vue # frontend/src/components/Modals/NewBuilderToken.vue # frontend/src/components/Modals/TokenManager.vue # frontend/src/types/doctypes.ts # frontend/src/utils/builderBlockCopyPaste.ts # frontend/src/utils/colorOptions.ts # frontend/src/utils/fontManager.ts # frontend/src/utils/useBuilderToken.ts
Bob is an AI assistant that helps you with building complete website from scratch.