Commits

AI enters Settings: providers, SEO, and automatic articles

Configuration of AI providers, debugging of 500 and 429 errors, per-article SEO with

Today was AI day: provider configuration in the panel and two new phases. The site is one step away from fully semi-automatic writing.

AI Settings: providers, uses, and tone

New section at /admin/ajustes/ia with three tabs. In Providers there are preloaded presets (pre-configured setups for OpenAI, Mistral, Groq, OpenRouter, Gemini, Z.ai, Minimax, and Ollama), editable base URL, key masked when saved, and a "Load Models" button that detects what each model can do. In Uses you decide which model does what: create content, images, vision scanner, translation, or voice. And Tone stores the prompts (the instructions the models receive) for tone, audience, and article structure.

The 500s along the way

Debugging left three fixes. AIService wasn't saving the database connection, and the automatic alt texts for images were returning 500 (internal server error). The asset URL (the file, in this case) only existed in the schema, and the router, which distributes requests, was generating it incorrectly. And the most useful rule: test via HTTP, not only by calling the service. The 500s only appeared through the router path.

Minimax and the wrong domain

The Minimax key didn't work. The account belongs to the international platform (minimax.io) and the preset pointed to minimaxi.com, the Chinese one. I diagnosed it by testing the key against the provider's three domains without exposing it: correct response only on .io, with 8 models. As a bonus, provider errors now show the actual response instead of a generic 502 (a "service unavailable" that explains nothing).

Typed key, saved key

Fixing "send what's typed" broke the flow after reloading. The empty form was sending an empty key, and the backend (the server-side) preferred it over the saved one. Logic corrected: what's typed takes priority; what's missing is taken from what's saved.

The free tier and its 429s

Vision batches were smashing the free tier's request limit (the zero-payment plan): 429: too many requests in a row. Pause between calls and per-image errors inside the response. Gemini 2.5 Flash was burning through its token budget (the pieces of text the model processes) "thinking": thinking is enabled by default, and the descriptions came out truncated. Budget raised to 2,000, scanner moved to flash-lite, and limits pool separated. And Ollama Cloud returned 402 without credits: vision is reassigned to a free Gemini.

SEO per article

New columns for meta title, description, and social image. In the editor rail (the new editor arrived with Crepe out, BlockNote in) there are character counters and an SEO score out of 100, with a checklist of 10 checks. The AI assistant offers meta, summary, slug (the short article address), review, and rewrite with the Tone prompts I already had saved. The public page includes JSON-LD Article (structured data that search engines know how to read).

Create based on the competition

Full flow: keyword, competitors (with Tavily or pasted URLs), extraction of each page, AI analysis, and new article. Real test with "history of coffee" and Wikipedia: a 9,462-character draft, 8 sections, and complete SEO meta in 63 seconds. Mistral saturated the global quota of the free tier: content reassigned to MiniMax. It's the reverse path of From my text to the draft.

Featured image with AI

Each article can generate its featured image: the text is summarized, the prompt is composed with the style saved in Tone, and it's generated with the image model. The site publishes it and uses it as a fallback og:image (the image that appears when sharing the link). Curious detail: the scene came out in Chinese because Minimax defaults to Chinese. System prompt (the fixed instruction that goes with each call) forcing Spanish and solved.

Pending on my side: the Tavily key for automatic search mode.

Other diary entries