<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Gemini on KnightLi Blog</title>
        <link>https://knightli.com/en/tags/gemini/</link>
        <description>Recent content in Gemini on KnightLi Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Sun, 24 May 2026 08:43:24 +0800</lastBuildDate><atom:link href="https://knightli.com/en/tags/gemini/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Gemini 3.5 Flash positioning and strengths: why it fits high-frequency, multimodal, low-latency use cases</title>
        <link>https://knightli.com/en/2026/05/24/gemini-35-flash-positioning-advantages-low-latency-multimodal/</link>
        <pubDate>Sun, 24 May 2026 08:43:24 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/24/gemini-35-flash-positioning-advantages-low-latency-multimodal/</guid>
        <description>&lt;p&gt;The keywords for &lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; are not &amp;ldquo;the strongest,&amp;rdquo; but &amp;ldquo;high-frequency, fast, cost-efficient, and easy to integrate.&amp;rdquo; It is more like the workhorse model in the Gemini family: it may not be the model you use for the hardest reasoning tasks, but it is well suited for real production workloads such as Q&amp;amp;A, summarization, customer support, content processing, multimodal understanding, lightweight coding assistance, and automated workflows.&lt;/p&gt;
&lt;p&gt;The key to understanding Flash is not to treat it as a replacement for a Pro-class flagship model. It is better understood as a model tier optimized for throughput and response speed. For developers and enterprises, the real cost of many AI applications is not only the strongest single response, but the latency, stability, price, and context-handling ability across thousands or millions of daily requests.&lt;/p&gt;
&lt;h2 id=&#34;product-positioning&#34;&gt;Product positioning
&lt;/h2&gt;&lt;p&gt;The Gemini family usually separates models into different tiers. Flagship models handle more complex reasoning, planning, and difficult tasks. Flash models emphasize speed, cost, and large-scale invocation.&lt;/p&gt;
&lt;p&gt;The positioning of &lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; can be summarized as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More suitable than Pro for high-frequency calls.&lt;/li&gt;
&lt;li&gt;More capable than tiny lightweight models for complex input.&lt;/li&gt;
&lt;li&gt;Optimized for low latency and high throughput.&lt;/li&gt;
&lt;li&gt;Suitable for multimodal input and long-context processing.&lt;/li&gt;
&lt;li&gt;Better as the default model inside applications, not only as a model for rare difficult requests.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This type of model is best for tasks that run many times every day. Its value is not just answer quality in one call, but whether it can reliably process large amounts of text, images, audio, video, or structured information at manageable cost.&lt;/p&gt;
&lt;h2 id=&#34;why-flash-matters&#34;&gt;Why Flash matters
&lt;/h2&gt;&lt;p&gt;When AI products move into production, a practical issue appears: the strongest model is useful, but not every request deserves the strongest model.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A user asks an ordinary customer-support question.&lt;/li&gt;
&lt;li&gt;A system summarizes a meeting transcript.&lt;/li&gt;
&lt;li&gt;A backend classifies a batch of tickets.&lt;/li&gt;
&lt;li&gt;An app explains an uploaded image.&lt;/li&gt;
&lt;li&gt;An automation extracts fields from an email.&lt;/li&gt;
&lt;li&gt;An agent reads a set of documents before deciding the next step.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These tasks need models that are reliable, cheap, and fast, but they do not always require the full reasoning power of a flagship model. That is where Flash matters: it puts &amp;ldquo;strong enough&amp;rdquo; and &amp;ldquo;fast enough&amp;rdquo; in the same place.&lt;/p&gt;
&lt;p&gt;If an AI application serves many users, the default model cannot be chosen only by peak capability. Average request cost, response speed, concurrency, and failure rate matter just as much. Flash is an application-layer model for that reality.&lt;/p&gt;
&lt;h2 id=&#34;advantage-1-low-latency-and-high-throughput&#34;&gt;Advantage 1: low latency and high throughput
&lt;/h2&gt;&lt;p&gt;The most direct advantage of Flash is speed.&lt;/p&gt;
&lt;p&gt;For chat products, retrieval-augmented search, support bots, real-time writing assistance, and agent workflows, latency directly affects user experience. Users may not know model parameters or benchmark results, but they immediately feel whether the product keeps them waiting.&lt;/p&gt;
&lt;p&gt;Low latency brings several benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conversations feel more real-time.&lt;/li&gt;
&lt;li&gt;Multi-step tool calls do not slow down as much.&lt;/li&gt;
&lt;li&gt;Agents can make intermediate decisions more often.&lt;/li&gt;
&lt;li&gt;Backend batch processing finishes faster.&lt;/li&gt;
&lt;li&gt;Product teams can place AI features into more small workflows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This matters especially for agent applications. A model does not answer only once; it repeatedly judges, calls tools, reads context, and generates the next action. Lower single-call latency improves the whole chain.&lt;/p&gt;
&lt;h2 id=&#34;advantage-2-better-cost-for-scale&#34;&gt;Advantage 2: better cost for scale
&lt;/h2&gt;&lt;p&gt;Another core value of Flash is cost.&lt;/p&gt;
&lt;p&gt;When enterprises and developers put AI applications into production, they usually care about three questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How much does each call cost?&lt;/li&gt;
&lt;li&gt;How many calls happen per day?&lt;/li&gt;
&lt;li&gt;Are cost and latency controllable at peak concurrency?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a task runs hundreds of thousands of times per day, even a small per-call price gap becomes large over time. Flash-style models are designed so that most requests do not have to go directly to the most expensive and heaviest model.&lt;/p&gt;
&lt;p&gt;A common pattern is tiered routing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ordinary requests go to Flash by default.&lt;/li&gt;
&lt;li&gt;Difficult problems, complex planning, and long-chain reasoning escalate to Pro.&lt;/li&gt;
&lt;li&gt;Simple classification or fixed-format extraction can go to even lighter models.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This lets an AI system keep high-end capability while controlling everyday cost.&lt;/p&gt;
&lt;h2 id=&#34;advantage-3-multimodal-input-fits-real-applications&#34;&gt;Advantage 3: multimodal input fits real applications
&lt;/h2&gt;&lt;p&gt;The Gemini family has long emphasized multimodal capability. Flash is valuable because it is not only for text requests; it can also handle images, audio, video, documents, and related inputs.&lt;/p&gt;
&lt;p&gt;That matters in real products. Business data is often not pure text:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Users upload screenshots for support.&lt;/li&gt;
&lt;li&gt;Customer support needs to understand a photo of a problem.&lt;/li&gt;
&lt;li&gt;Education products process images of exercises.&lt;/li&gt;
&lt;li&gt;Content platforms analyze video clips.&lt;/li&gt;
&lt;li&gt;Office workflows read PDFs, spreadsheets, and presentations.&lt;/li&gt;
&lt;li&gt;E-commerce products analyze product images and user descriptions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If multimodal understanding depends only on expensive flagship models, many high-frequency scenarios are hard to scale. Flash brings multimodal understanding into a model tier better suited for large-scale invocation.&lt;/p&gt;
&lt;h2 id=&#34;advantage-4-long-context-makes-it-good-at-reading-material&#34;&gt;Advantage 4: long context makes it good at reading material
&lt;/h2&gt;&lt;p&gt;Long context is an important Gemini-family capability. For Flash, long context is not simply about stuffing everything into the prompt; it lets the model handle more information-organization tasks.&lt;/p&gt;
&lt;p&gt;Examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Summarizing long documents.&lt;/li&gt;
&lt;li&gt;Reading product manuals.&lt;/li&gt;
&lt;li&gt;Analyzing meeting notes.&lt;/li&gt;
&lt;li&gt;Organizing multi-page PDFs.&lt;/li&gt;
&lt;li&gt;Comparing contracts or proposals.&lt;/li&gt;
&lt;li&gt;Providing agents with large task backgrounds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Long context combined with lower cost is well suited for workflows that first read a lot of material and then produce actionable results. Flash does not need to solve extremely hard reasoning tasks every time. It can include more context in one pass, which is useful for office work, customer support, knowledge bases, and developer assistance.&lt;/p&gt;
&lt;h2 id=&#34;advantage-5-suitable-as-a-default-model&#34;&gt;Advantage 5: suitable as a default model
&lt;/h2&gt;&lt;p&gt;Many AI products need a &amp;ldquo;default model.&amp;rdquo; It does not have to be the most expensive or strongest, but it must satisfy several conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stable quality on most questions.&lt;/li&gt;
&lt;li&gt;Fast response.&lt;/li&gt;
&lt;li&gt;Manageable cost.&lt;/li&gt;
&lt;li&gt;Ability to handle multimodal input.&lt;/li&gt;
&lt;li&gt;Sufficient long-context support.&lt;/li&gt;
&lt;li&gt;Easy API and product integration.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is where &lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; has an advantage. It is suitable as the default entry point: handle most requests first, and route complex tasks to stronger models when needed.&lt;/p&gt;
&lt;p&gt;This pattern will become increasingly common. Future AI systems will not simply &amp;ldquo;choose one model&amp;rdquo;; they will use Flash as the workhorse, Pro as the escalation path, and smaller models for edge tasks.&lt;/p&gt;
&lt;h2 id=&#34;suitable-scenarios&#34;&gt;Suitable scenarios
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; is well suited for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Customer-support Q&amp;amp;A and answers after knowledge-base retrieval.&lt;/li&gt;
&lt;li&gt;Long-document summaries, report organization, and meeting notes.&lt;/li&gt;
&lt;li&gt;Multimodal understanding of images, screenshots, PDFs, and video clips.&lt;/li&gt;
&lt;li&gt;Real-time AI assistants inside apps.&lt;/li&gt;
&lt;li&gt;Content moderation, classification, and tag generation.&lt;/li&gt;
&lt;li&gt;Information extraction from emails, tickets, and forms.&lt;/li&gt;
&lt;li&gt;Intermediate decisions and context compression in agent workflows.&lt;/li&gt;
&lt;li&gt;Code explanation, lightweight fix suggestions, and documentation generation.&lt;/li&gt;
&lt;li&gt;Education products for exercise explanation and study assistance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These scenarios share the same traits: high request volume, sensitivity to user wait time, complex input types, and no need for flagship-level deep reasoning every time.&lt;/p&gt;
&lt;h2 id=&#34;where-flash-should-not-be-the-only-model&#34;&gt;Where Flash should not be the only model
&lt;/h2&gt;&lt;p&gt;Flash is not universal. It is optimized for high-frequency and low-latency use, but that does not mean every problem should use only Flash.&lt;/p&gt;
&lt;p&gt;The following scenarios still fit stronger Pro-class models better, or at least require tiered routing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complex mathematics and rigorous proofs.&lt;/li&gt;
&lt;li&gt;Long-chain planning and multi-step strategic reasoning.&lt;/li&gt;
&lt;li&gt;High-risk legal, medical, or financial judgment.&lt;/li&gt;
&lt;li&gt;Deep refactoring plans for large codebases.&lt;/li&gt;
&lt;li&gt;Complex agent tasks requiring high reliability.&lt;/li&gt;
&lt;li&gt;Professional reports with extremely low tolerance for hallucination.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A safer strategy is to let Flash handle, judge, and organize first; when task complexity rises, escalate to a stronger model.&lt;/p&gt;
&lt;h2 id=&#34;relationship-with-pro-class-models&#34;&gt;Relationship with Pro-class models
&lt;/h2&gt;&lt;p&gt;Flash and Pro should not be understood as &amp;ldquo;which one replaces the other.&amp;rdquo; They have different jobs.&lt;/p&gt;
&lt;p&gt;Flash is the everyday workhorse:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fast.&lt;/li&gt;
&lt;li&gt;Cost-friendly.&lt;/li&gt;
&lt;li&gt;Suitable for high concurrency.&lt;/li&gt;
&lt;li&gt;Good for multimodal and long-context applications.&lt;/li&gt;
&lt;li&gt;Suitable for default product flows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pro is the hard-task model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better for complex reasoning.&lt;/li&gt;
&lt;li&gt;Better for difficult planning.&lt;/li&gt;
&lt;li&gt;Better for high-value requests.&lt;/li&gt;
&lt;li&gt;Better for small numbers of important deep-analysis tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Good AI products usually combine the two instead of choosing only one.&lt;/p&gt;
&lt;h2 id=&#34;how-developers-should-use-it&#34;&gt;How developers should use it
&lt;/h2&gt;&lt;p&gt;If you want to integrate Gemini 3.5 Flash into a product, consider these patterns:&lt;/p&gt;
&lt;p&gt;First, use it as the default model. Most ordinary requests go to Flash first, giving both speed and cost control.&lt;/p&gt;
&lt;p&gt;Second, design model routing. When Flash identifies a task as complex, high-risk, or requiring deep reasoning, escalate to Pro.&lt;/p&gt;
&lt;p&gt;Third, use it for context compression. Before an agent executes a task, Flash can summarize documents, extract key facts, and generate structured context.&lt;/p&gt;
&lt;p&gt;Fourth, make multimodal input part of the normal workflow. Images, screenshots, PDFs, audio, and video should not only be edge features; they can become default input types.&lt;/p&gt;
&lt;p&gt;Fifth, evaluate with your own data. Do not rely only on official benchmarks. Test with your support questions, documents, code, images, and business workflows to decide which tasks Flash handles well and which need escalation.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;The core positioning of &lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; is a multimodal workhorse model for high-frequency real applications. Its advantage is not replacing Pro-class flagship models, but placing speed, cost, long context, and multimodal ability into a tier better suited for large-scale invocation.&lt;/p&gt;
&lt;p&gt;For developers, the most important part of Flash is not a single benchmark, but a product architecture shift: the default model can be faster, cheaper, and better at reading complex inputs; harder tasks can still escalate to stronger models. This keeps user experience good while controlling cost.&lt;/p&gt;
&lt;p&gt;If Pro is the heavy tool for difficult problems, Flash is the main tool running on the production line every day. In real AI products, the latter is often what users experience most.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google official blog: &lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-3-5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-3-5/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google DeepMind Gemini Flash: &lt;a class=&#34;link&#34; href=&#34;https://deepmind.google/en/models/gemini/flash/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://deepmind.google/en/models/gemini/flash/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;User-provided Zhihu discussion link: &lt;a class=&#34;link&#34; href=&#34;https://www.zhihu.com/question/2040529179641385344/answer/2040531897613285214&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.zhihu.com/question/2040529179641385344/answer/2040531897613285214&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>After Google I/O, Should You Subscribe to GPT or Gemini? A Comparison for Regular Users and Developers</title>
        <link>https://knightli.com/en/2026/05/21/gpt-vs-gemini-subscription-after-google-io-2026/</link>
        <pubDate>Thu, 21 May 2026 08:33:14 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/21/gpt-vs-gemini-subscription-after-google-io-2026/</guid>
        <description>&lt;p&gt;After Google I/O 2026, choosing an AI subscription has become more complicated.&lt;/p&gt;
&lt;p&gt;The old question was simpler: for writing, Q&amp;amp;A, coding, and file analysis, most people looked at ChatGPT first; if they were deeply tied to Google Search, Android, Gmail, Docs, or YouTube, they would then consider Gemini. That has changed. At I/O, Google put Gemini 3.5 Flash, Gemini Omni, Antigravity 2.0, Gemini API Managed Agents, Google AI Studio, and AI Ultra into one broader subscription story. Gemini is no longer just an optional alternative; it has become a serious competing ecosystem.&lt;/p&gt;
&lt;p&gt;This article does not compare abstract benchmark scores. It answers a practical question: should regular users, developers, content creators, and enterprise users subscribe to GPT / ChatGPT, or to Gemini / Google AI?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: AI subscription prices, quotas, regions, and model availability change quickly. This article was written on May 21, 2026. Before subscribing, always check the current OpenAI and Google pages.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;the-short-answer&#34;&gt;The Short Answer
&lt;/h2&gt;&lt;p&gt;If you only want one primary subscription, use this logic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Daily writing, Q&amp;amp;A, file analysis, office work, and mixed Chinese-English tasks: prioritize ChatGPT Plus.&lt;/li&gt;
&lt;li&gt;Heavy coding, Codex usage, complex reasoning, and project-level code tasks: prioritize ChatGPT Plus / Pro, then decide whether to upgrade based on quota.&lt;/li&gt;
&lt;li&gt;Deep use of the Google ecosystem, including Gmail, Docs, Drive, Android, and Search: prioritize Gemini / Google AI Pro.&lt;/li&gt;
&lt;li&gt;Video, AI imagery, Google Flow, YouTube Shorts, and Gemini Omni: prioritize Google AI Pro / Ultra.&lt;/li&gt;
&lt;li&gt;Antigravity, Gemini API Managed Agents, and workflows from AI Studio to Android: focus on Google AI Pro / Ultra.&lt;/li&gt;
&lt;li&gt;Enterprise teams: do not compare only personal plans; look at Business / Enterprise, Workspace, permissions, audit, and data boundaries.&lt;/li&gt;
&lt;li&gt;Limited budget: one paid primary subscription plus another platform&amp;rsquo;s free tier or pay-as-you-go API is usually better than two high-end subscriptions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In one sentence: GPT is still the stronger default productivity and coding assistant; after Google I/O, Gemini looks more like a system-level AI suite inside the Google ecosystem.&lt;/p&gt;
&lt;h2 id=&#34;what-changed-for-gemini-after-google-io&#34;&gt;What Changed for Gemini After Google I/O
&lt;/h2&gt;&lt;p&gt;Google I/O 2026 made Gemini&amp;rsquo;s value depend on much more than the Gemini App itself.&lt;/p&gt;
&lt;p&gt;Several changes matter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt;: Google positions it as a fast model for prompt-to-action workflows and real agent tasks.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini Omni&lt;/code&gt;: creates content from arbitrary input, currently starting with video, with multimodal creation and natural-language iterative editing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google Antigravity 2.0&lt;/code&gt;: an agent-first development platform for multi-agent orchestration and coding.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini API Managed Agents&lt;/code&gt;: lets developers create hosted agents that can reason, use tools, and execute code through the API.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google AI Studio&lt;/code&gt;: moves from a prompt playground toward mobile, Android native app generation, and Antigravity project export.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google AI Ultra&lt;/code&gt;: a new $100/month tier after I/O, aimed at developers, technical leads, knowledge workers, and advanced creators.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More importantly, Google moved Gemini App usage from traditional daily prompt limits toward a &lt;code&gt;compute-used&lt;/code&gt; model. Complex video, code, and long-context tasks consume more quota, while simple text tasks consume less. Quotas refresh every five hours until weekly limits are reached.&lt;/p&gt;
&lt;p&gt;That shows Google is trying to package Gemini subscriptions as an entry point for &amp;ldquo;model + app + creation + development tools + Google ecosystem.&amp;rdquo;&lt;/p&gt;
&lt;h2 id=&#34;who-is-chatgpt--gpt-best-for-now&#34;&gt;Who Is ChatGPT / GPT Best For Now?
&lt;/h2&gt;&lt;p&gt;ChatGPT remains very strong, especially for people who treat AI as a daily workhorse.&lt;/p&gt;
&lt;p&gt;According to OpenAI&amp;rsquo;s current pricing page and help documentation, ChatGPT Free includes basic capabilities such as GPT-5.5 Instant. Plus provides GPT-5.5 Thinking, higher message and upload limits, stronger image generation, deep research, agent mode, projects, tasks, custom GPTs, and expanded Codex usage. Pro provides higher limits, GPT-5.5 Pro, higher Codex usage, and the largest deep research and agent mode capacity.&lt;/p&gt;
&lt;p&gt;ChatGPT is especially suitable for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing, summarizing, translation, and editing.&lt;/li&gt;
&lt;li&gt;Complex Q&amp;amp;A and structured analysis.&lt;/li&gt;
&lt;li&gt;File upload, spreadsheet analysis, and research reports.&lt;/li&gt;
&lt;li&gt;Coding Q&amp;amp;A, code review, and refactoring advice.&lt;/li&gt;
&lt;li&gt;Using Codex for repository-level tasks.&lt;/li&gt;
&lt;li&gt;Multilingual content production.&lt;/li&gt;
&lt;li&gt;Users who care about model quality and response stability but are not deeply tied to Google products.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For regular users, ChatGPT Plus is still the safest primary subscription. It covers a wide range of work, has a low learning curve, and handles Chinese and English tasks evenly.&lt;/p&gt;
&lt;p&gt;For developers, the key part of ChatGPT is not only chat, but Codex. OpenAI&amp;rsquo;s help documentation says Codex can be used with eligible ChatGPT plans, with usage limits varying by plan. If you use Codex heavily for code edits, PRs, refactoring, or test fixes, you need to include Codex quota in your subscription decision.&lt;/p&gt;
&lt;h2 id=&#34;who-is-gemini--google-ai-best-for-now&#34;&gt;Who Is Gemini / Google AI Best For Now?
&lt;/h2&gt;&lt;p&gt;After Google I/O, Gemini&amp;rsquo;s advantage is clearer: it is more deeply bound to the Google ecosystem.&lt;/p&gt;
&lt;p&gt;Google AI subscriptions are no longer only model quota inside the Gemini App. They also include Gemini Omni, Google Flow, Antigravity, AI Studio, some YouTube Premium / Lite benefits, and Workspace / Android / Search ecosystem capabilities. Google also expanded AI Ultra into a $100 and higher-tier subscription line, emphasizing developers, technical leads, knowledge workers, and advanced creators.&lt;/p&gt;
&lt;p&gt;Gemini is especially suitable if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You deeply use Gmail, Docs, Drive, Sheets, Slides, and Android.&lt;/li&gt;
&lt;li&gt;You want AI inside Google Search, YouTube, and Workspace.&lt;/li&gt;
&lt;li&gt;You care about Gemini Omni, Google Flow, video generation, and video editing.&lt;/li&gt;
&lt;li&gt;You want to try Antigravity, Gemini API Managed Agents, and AI Studio mobile.&lt;/li&gt;
&lt;li&gt;You need ultra-long-context document understanding.&lt;/li&gt;
&lt;li&gt;You build Google ecosystem apps, Android native apps, or Workspace automation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google&amp;rsquo;s help page says Gemini Apps context windows increase with subscription level: 32K without an AI plan, 128K with AI Plus, and 1 million with AI Pro and AI Ultra. AI Pro / Ultra also provides higher usage limits, more features, and some early access capabilities.&lt;/p&gt;
&lt;p&gt;If your work already lives in the Google ecosystem, Gemini&amp;rsquo;s value becomes much larger. Otherwise, subscribing to Gemini only as &amp;ldquo;another chatbot&amp;rdquo; may not be more cost-effective than ChatGPT.&lt;/p&gt;
&lt;h2 id=&#34;how-regular-users-should-choose&#34;&gt;How Regular Users Should Choose
&lt;/h2&gt;&lt;p&gt;The easiest trap for regular users is subscribing to multiple platforms just because a new model was announced.&lt;/p&gt;
&lt;p&gt;A more rational choice starts with your main use case.&lt;/p&gt;
&lt;p&gt;If you mainly do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writing.&lt;/li&gt;
&lt;li&gt;Research.&lt;/li&gt;
&lt;li&gt;Summaries.&lt;/li&gt;
&lt;li&gt;Reading PDFs.&lt;/li&gt;
&lt;li&gt;Email.&lt;/li&gt;
&lt;li&gt;Resume editing.&lt;/li&gt;
&lt;li&gt;Language learning.&lt;/li&gt;
&lt;li&gt;Daily Q&amp;amp;A.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Choose ChatGPT Plus first. It is more general-purpose, has clearer task boundaries, and does not require deep ecosystem lock-in.&lt;/p&gt;
&lt;p&gt;If you mainly do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Heavy Gmail / Docs / Drive / YouTube / Android use.&lt;/li&gt;
&lt;li&gt;Want AI directly inside Google&amp;rsquo;s ecosystem.&lt;/li&gt;
&lt;li&gt;Want to try Gemini App, Daily Brief, Google Search AI, and YouTube content Q&amp;amp;A.&lt;/li&gt;
&lt;li&gt;Need long-context reading of Google documents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Choose Google AI Pro first.&lt;/p&gt;
&lt;p&gt;If you are a light user, start with the free tiers on both platforms and pay only after you clearly hit limits. Do not subscribe to a high-end plan just because you might use it someday.&lt;/p&gt;
&lt;h2 id=&#34;how-developers-should-choose&#34;&gt;How Developers Should Choose
&lt;/h2&gt;&lt;p&gt;Developers fall into two broad groups.&lt;/p&gt;
&lt;p&gt;The first group mainly asks coding questions, fixes bugs, writes scripts, and reads repositories. For them, start with ChatGPT Plus / Pro + Codex.&lt;/p&gt;
&lt;p&gt;Reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Codex is tied to the ChatGPT account.&lt;/li&gt;
&lt;li&gt;ChatGPT is stable for code explanation, refactoring, tests, and error analysis.&lt;/li&gt;
&lt;li&gt;Plus already covers many daily development tasks.&lt;/li&gt;
&lt;li&gt;Pro is better for high-frequency, long-running, complex repository tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second group builds around the Google ecosystem, agent platforms, Android, Workspace, or Gemini API. For them, start with Google AI Pro / Ultra.&lt;/p&gt;
&lt;p&gt;Reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini 3.5 Flash is a key post-I/O model for agent workflows.&lt;/li&gt;
&lt;li&gt;Antigravity 2.0 is Google&amp;rsquo;s agent-first development platform.&lt;/li&gt;
&lt;li&gt;Managed Agents can create tool-using agents with isolated Linux environments through the API.&lt;/li&gt;
&lt;li&gt;AI Studio connects more naturally with Android, Workspace, and Antigravity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For full-stack developers, the most practical combination is usually:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT Plus as the main tool for daily code and documentation.&lt;/li&gt;
&lt;li&gt;Gemini free tier or AI Pro for Google ecosystem tasks, long context, and new video / agent capabilities.&lt;/li&gt;
&lt;li&gt;Use APIs pay-as-you-go, and do not treat a personal subscription as a production API budget.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-content-creators-should-choose&#34;&gt;How Content Creators Should Choose
&lt;/h2&gt;&lt;p&gt;For content creators, the answer depends on what you create.&lt;/p&gt;
&lt;p&gt;If you mainly do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Copywriting.&lt;/li&gt;
&lt;li&gt;Headlines.&lt;/li&gt;
&lt;li&gt;Scripts.&lt;/li&gt;
&lt;li&gt;Articles.&lt;/li&gt;
&lt;li&gt;Image-and-text content.&lt;/li&gt;
&lt;li&gt;Research organization.&lt;/li&gt;
&lt;li&gt;Multilingual rewriting.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ChatGPT Plus is still very reliable.&lt;/p&gt;
&lt;p&gt;If you mainly do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Video generation.&lt;/li&gt;
&lt;li&gt;Short-video ideas.&lt;/li&gt;
&lt;li&gt;AI imagery.&lt;/li&gt;
&lt;li&gt;YouTube Shorts.&lt;/li&gt;
&lt;li&gt;Google Flow workflows.&lt;/li&gt;
&lt;li&gt;Multimodal asset assembly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gemini / Google AI Pro or Ultra deserves more attention. After I/O, Gemini Omni and Google Flow are Google&amp;rsquo;s core offerings for creation.&lt;/p&gt;
&lt;p&gt;If your budget is limited, subscribe to one text-first primary tool, then use the other platform&amp;rsquo;s free tier or a short-term subscription to test video capabilities. Video model quotas, queues, duration, resolution, and regional limits change quickly, so do not plan long-term production around them too early.&lt;/p&gt;
&lt;h2 id=&#34;how-enterprises-and-teams-should-choose&#34;&gt;How Enterprises and Teams Should Choose
&lt;/h2&gt;&lt;p&gt;Enterprises should not choose like individual users.&lt;/p&gt;
&lt;p&gt;What enterprises really need to examine is not &amp;ldquo;which model is stronger this week,&amp;rdquo; but:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Whether data is used for training.&lt;/li&gt;
&lt;li&gt;Whether SSO, MFA, and RBAC are available.&lt;/li&gt;
&lt;li&gt;Whether audit logs exist.&lt;/li&gt;
&lt;li&gt;Whether internal knowledge connections are supported.&lt;/li&gt;
&lt;li&gt;Whether plugins, connectors, and agent permissions can be controlled.&lt;/li&gt;
&lt;li&gt;Whether the product meets compliance requirements.&lt;/li&gt;
&lt;li&gt;Whether it integrates with the existing office suite.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If a company already heavily uses Google Workspace, Gemini enterprise plans are naturally worth evaluating. If the team has already built processes around ChatGPT, Codex, OpenAI API, and internal toolchains, OpenAI Business / Enterprise is the more natural fit.&lt;/p&gt;
&lt;p&gt;Engineering teams also need to separately evaluate Codex, Antigravity, Gemini API Managed Agents, MCP, CI/CD, code permissions, repository access, and audit.&lt;/p&gt;
&lt;h2 id=&#34;when-you-need-pro--ultra&#34;&gt;When You Need Pro / Ultra
&lt;/h2&gt;&lt;p&gt;Many people do not actually need a high-end tier.&lt;/p&gt;
&lt;p&gt;Typical signs that you need ChatGPT Pro:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You use ChatGPT for long periods every day.&lt;/li&gt;
&lt;li&gt;Plus limits are often insufficient.&lt;/li&gt;
&lt;li&gt;You use Codex heavily.&lt;/li&gt;
&lt;li&gt;You often run deep research, agent mode, and complex reasoning.&lt;/li&gt;
&lt;li&gt;You need higher-end models such as GPT-5.5 Pro.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Typical signs that you need Google AI Ultra:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You use Gemini, Flow, and Antigravity frequently.&lt;/li&gt;
&lt;li&gt;You need higher Gemini / Antigravity usage limits.&lt;/li&gt;
&lt;li&gt;You create videos, AI imagery, or long-context research.&lt;/li&gt;
&lt;li&gt;You deeply depend on the Google ecosystem and early access to new features.&lt;/li&gt;
&lt;li&gt;You need Gemini Spark, Project Genie, or higher-tier subscription benefits.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you only ask a few questions a day or occasionally write articles or edit code, Plus / Pro or AI Pro / Ultra may not be necessary.&lt;/p&gt;
&lt;h2 id=&#34;the-most-cost-effective-subscription-strategy&#34;&gt;The Most Cost-Effective Subscription Strategy
&lt;/h2&gt;&lt;p&gt;This combination is usually better:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose one paid primary subscription first.&lt;/li&gt;
&lt;li&gt;Use the other platform&amp;rsquo;s free tier.&lt;/li&gt;
&lt;li&gt;Pay for API only when you actually need API usage.&lt;/li&gt;
&lt;li&gt;Turn high-consumption features such as video, agents, and deep research on and off monthly instead of subscribing all year blindly.&lt;/li&gt;
&lt;li&gt;Review once a month: did you really use the quota?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Common combinations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;General office work: ChatGPT Plus + Gemini free tier.&lt;/li&gt;
&lt;li&gt;Google ecosystem users: Google AI Pro + ChatGPT free tier.&lt;/li&gt;
&lt;li&gt;Developers: ChatGPT Plus/Pro + Gemini API/AI Studio as needed.&lt;/li&gt;
&lt;li&gt;Video creators: Google AI Pro/Ultra + ChatGPT free tier or Plus.&lt;/li&gt;
&lt;li&gt;Enterprise teams: do not piece together personal plans; evaluate Business / Enterprise / Workspace plans directly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;checklist-before-subscribing&#34;&gt;Checklist Before Subscribing
&lt;/h2&gt;&lt;p&gt;Before paying, confirm these points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Is the plan available in your region?&lt;/li&gt;
&lt;li&gt;Is the model you need included in the plan?&lt;/li&gt;
&lt;li&gt;Are Codex, Antigravity, Flow, and Omni actually available?&lt;/li&gt;
&lt;li&gt;Do video features have region, age, queue, or resolution limits?&lt;/li&gt;
&lt;li&gt;Is API usage included in the subscription, or billed separately?&lt;/li&gt;
&lt;li&gt;Do file upload, context window, agent mode, and deep research have limits?&lt;/li&gt;
&lt;li&gt;Do the privacy settings meet your project requirements?&lt;/li&gt;
&lt;li&gt;Do you already have Google One, Workspace, ChatGPT Business, or school / company benefits?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Be especially careful: a personal subscription does not mean free API usage, unlimited commercial use, or enterprise compliance.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;After Google I/O, Gemini is much more competitive, especially in video, multimodality, the Google ecosystem, Android, AI Studio, and Antigravity. But ChatGPT remains the steadier general-purpose choice, especially for daily writing, complex Q&amp;amp;A, file analysis, coding assistance, and Codex workflows.&lt;/p&gt;
&lt;p&gt;The simplest judgment is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you do not know which to choose: start with ChatGPT Plus.&lt;/li&gt;
&lt;li&gt;If you are a deep Google user: choose Google AI Pro.&lt;/li&gt;
&lt;li&gt;If you are a heavy developer: compare Codex and Antigravity against your actual workflow.&lt;/li&gt;
&lt;li&gt;If you are a video creator: look first at Gemini Omni, Flow, and Google AI Pro / Ultra.&lt;/li&gt;
&lt;li&gt;If you are an enterprise user: choose by compliance, permissions, audit, and existing office ecosystem, not model hype.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More AI subscriptions are not automatically better. The more economical path is to define one primary workflow, then use other platforms as supplements instead of opening a long-term subscription after every product keynote.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://chatgpt.com/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI: ChatGPT Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11369540-using-codex-with-your-chatgpt-plan&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Help: Using Codex with your ChatGPT plan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/products-and-platforms/products/google-one/google-ai-subscriptions/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: Everything new in Google AI subscriptions from I/O 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-developer-highlights/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: I/O 2026 developer highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://support.google.com/gemini/answer/16275805&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Help: Gemini Apps limits and upgrades for Google AI subscribers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Google I/O 2026 Summary: Gemini 3.5, Omni, Antigravity, and System-Level Agents</title>
        <link>https://knightli.com/en/2026/05/21/google-io-2026-gemini-agentic-ai-summary/</link>
        <pubDate>Thu, 21 May 2026 00:07:06 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/21/google-io-2026-gemini-agentic-ai-summary/</guid>
        <description>&lt;p&gt;The main line of Google I/O 2026 is clear: Google is moving Gemini from &amp;ldquo;model&amp;rdquo; and &amp;ldquo;chat assistant&amp;rdquo; into a fuller Agent ecosystem. It is not only answering questions. It is entering Search, Android, developer tools, video creation, shopping, Workspace, hardware, and enterprise platforms to help users complete longer task chains.&lt;/p&gt;
&lt;p&gt;This article summarizes the main Google I/O 2026 announcements from official releases and a developer perspective. For real development, always follow the official Google, Android Developers, and Gemini API documentation.&lt;/p&gt;
&lt;h2 id=&#34;one-sentence-summary&#34;&gt;One-Sentence Summary
&lt;/h2&gt;&lt;p&gt;The keyword for Google I/O 2026 is &lt;code&gt;agentic Gemini era&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Google announced or strengthened several lines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt;: speed, action capability, and Agent workflows.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini Omni&lt;/code&gt;: creating content from any input, starting with video creation and editing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini app&lt;/code&gt;: moving from chat assistant to proactive, always-on, task-capable personal Agent.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google Antigravity 2.0&lt;/code&gt;: evolving from an AI coding tool into an Agent-first development platform.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini API Managed Agents&lt;/code&gt;: creating hosted Agents through APIs that can reason, use tools, and execute code.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google AI Studio&lt;/code&gt;: expanding to mobile, native Android support, and project export to Antigravity.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Search&lt;/code&gt;, &lt;code&gt;Shopping&lt;/code&gt;, &lt;code&gt;YouTube&lt;/code&gt;, &lt;code&gt;Workspace&lt;/code&gt;, and &lt;code&gt;Android&lt;/code&gt;: all gaining stronger Gemini and Agent capabilities.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, Google is no longer only showing &amp;ldquo;how smart the model is.&amp;rdquo; It is showing how models enter products, tools, and systems to actually execute tasks for users.&lt;/p&gt;
&lt;h2 id=&#34;gemini-35-flash-from-prompt-to-action&#34;&gt;Gemini 3.5 Flash: From Prompt to Action
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 is Google&amp;rsquo;s new model family at I/O 2026, with &lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; as the first public focus.&lt;/p&gt;
&lt;p&gt;Google does not position it as simply a &amp;ldquo;faster chat model,&amp;rdquo; but as a high-speed engine for real Agent workflows. Google&amp;rsquo;s developer article describes 3.5 Flash as combining frontier intelligence and high speed to support the shift from prompt to action.&lt;/p&gt;
&lt;p&gt;Its main significance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Optimized for Agent and coding scenarios.&lt;/li&gt;
&lt;li&gt;Supports longer task chains and tool use.&lt;/li&gt;
&lt;li&gt;Available through Antigravity, Gemini API, Google AI Studio, Android Studio, Gemini Enterprise, and other entry points.&lt;/li&gt;
&lt;li&gt;Better suited for applications that need fast responses, multi-turn execution, and frequent tool calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For developers, Gemini 3.5 Flash is not just another model option. It is one of the default engines for Google&amp;rsquo;s new Agent toolchain.&lt;/p&gt;
&lt;h2 id=&#34;gemini-omni-video-and-world-model-capabilities&#34;&gt;Gemini Omni: Video and World-Model Capabilities
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Gemini Omni&lt;/code&gt; is another core I/O 2026 announcement. Google describes it as creating content from any input, with the current focus starting from video.&lt;/p&gt;
&lt;p&gt;Its highlights fall into three areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multimodal input: text, images, video, audio, and more can be used as references.&lt;/li&gt;
&lt;li&gt;Video editing: users can modify video over multiple turns with natural language instead of stopping after one generation.&lt;/li&gt;
&lt;li&gt;World understanding: it emphasizes consistency in physics, scenes, actions, narrative, and audiovisual output.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This means AI video tools are moving from &amp;ldquo;enter one prompt to generate a clip&amp;rdquo; toward &amp;ldquo;revise step by step as if talking to an editor.&amp;rdquo; For creators, the real value is not one-shot generation, but a controllable, traceable, and iterative editing process.&lt;/p&gt;
&lt;h2 id=&#34;gemini-app-from-chat-assistant-to-always-on-personal-agent&#34;&gt;Gemini App: From Chat Assistant to Always-On Personal Agent
&lt;/h2&gt;&lt;p&gt;Google is also pushing Gemini app in a more Agent-like direction. Official posts describe Gemini app as becoming more proactive, offering daily briefs and always-on assistance.&lt;/p&gt;
&lt;p&gt;Key points include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; entering Gemini app.&lt;/li&gt;
&lt;li&gt;A new UI and more dynamic interaction.&lt;/li&gt;
&lt;li&gt;Personal AI Agent concepts such as &lt;code&gt;Gemini Spark&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Proactive daily briefs that organize what users need to know each day.&lt;/li&gt;
&lt;li&gt;More emphasis on 24/7 background assistance instead of waiting for the user to start every chat.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the part that affects ordinary users most. Gemini used to feel more like a &amp;ldquo;you ask, I answer&amp;rdquo; assistant. After I/O 2026, Google wants it to feel more like a personal Agent that follows up on tasks, proactively reminds users, and works across products.&lt;/p&gt;
&lt;h2 id=&#34;antigravity-20-developer-tools-become-agent-first&#34;&gt;Antigravity 2.0: Developer Tools Become Agent-First
&lt;/h2&gt;&lt;p&gt;One of the most important developer-side announcements is &lt;code&gt;Google Antigravity 2.0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Google positions Antigravity as an agent-first development platform. After I/O 2026, it is not only helping developers write code. It is meant to help developers move from ideas and prototypes to Agent orchestration and production delivery.&lt;/p&gt;
&lt;p&gt;Core changes listed by Google include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Antigravity 2.0 standalone desktop app.&lt;/li&gt;
&lt;li&gt;Multi-Agent parallel orchestration.&lt;/li&gt;
&lt;li&gt;Dynamic subagents.&lt;/li&gt;
&lt;li&gt;Background scheduled tasks.&lt;/li&gt;
&lt;li&gt;Integration with Google AI Studio, Android, Firebase, and related ecosystems.&lt;/li&gt;
&lt;li&gt;Antigravity CLI for terminal users.&lt;/li&gt;
&lt;li&gt;Antigravity SDK for custom Agent behavior and deployment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This shows that AI coding tools are entering the next stage after &amp;ldquo;code completion / conversational generation&amp;rdquo;: developers will manage multiple executable Agents, not just one chat window.&lt;/p&gt;
&lt;h2 id=&#34;gemini-api-managed-agents-hosting-agents-as-api-capabilities&#34;&gt;Gemini API Managed Agents: Hosting Agents as API Capabilities
&lt;/h2&gt;&lt;p&gt;Google also introduced &lt;code&gt;Managed Agents in the Gemini API&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;According to the official description, these Agents can be created with a single API call. They can reason, use tools, and execute code in an isolated Linux environment, supported by the Antigravity agent harness.&lt;/p&gt;
&lt;p&gt;This matters to developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You do not need to build the full Agent runtime yourself.&lt;/li&gt;
&lt;li&gt;You can get a persistent, isolated execution environment.&lt;/li&gt;
&lt;li&gt;Multi-turn interactions can preserve files and state.&lt;/li&gt;
&lt;li&gt;Agents can be extended with markdown skills, custom instructions, and templates.&lt;/li&gt;
&lt;li&gt;They are available through Interactions API and Google AI Studio.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If this line matures, Agent platforms will increasingly look like cloud services: developers will not only call models, but call Agents with state, tools, execution environments, and security boundaries.&lt;/p&gt;
&lt;h2 id=&#34;google-ai-studio-from-prompt-playground-to-app-generation-entry-point&#34;&gt;Google AI Studio: From Prompt Playground to App Generation Entry Point
&lt;/h2&gt;&lt;p&gt;At I/O 2026, Google AI Studio also moves further.&lt;/p&gt;
&lt;p&gt;Key changes include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google AI Studio mobile app for capturing ideas and generating prototypes on mobile.&lt;/li&gt;
&lt;li&gt;Workspace API integration, making it easier for Agents to access Google Workspace.&lt;/li&gt;
&lt;li&gt;Project export to Antigravity, carrying context into local development and production work.&lt;/li&gt;
&lt;li&gt;Native Android support, allowing users to build Android apps from prompts.&lt;/li&gt;
&lt;li&gt;Google Play Console integration to publish apps to test tracks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This turns AI Studio from &amp;ldquo;a place to tune prompts and test models&amp;rdquo; into an entry point from idea to app. Its relationship with Antigravity is clearer too: AI Studio is good for fast ideation and generation, while Antigravity is better for continued development, orchestration, debugging, and delivery.&lt;/p&gt;
&lt;h2 id=&#34;android-and-appfunctions-key-interfaces-for-mobile-agents&#34;&gt;Android and AppFunctions: Key Interfaces for Mobile Agents
&lt;/h2&gt;&lt;p&gt;Android system-level Agents are worth watching on their own, but they need to be understood through accurate interfaces and product boundaries.&lt;/p&gt;
&lt;p&gt;The most important current piece is Android&amp;rsquo;s official &lt;code&gt;AppFunctions&lt;/code&gt;. The official documentation describes AppFunctions as an Android platform API with Jetpack libraries that lets apps expose their capabilities to agents, assistants, and other authorized callers. It also simplifies Android MCP integration.&lt;/p&gt;
&lt;p&gt;Its significance is that mobile automation no longer has to rely only on screenshots, OCR, simulated taps, and UI control positioning.&lt;/p&gt;
&lt;p&gt;Traditional mobile automation looks like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recognize the screen.&lt;/li&gt;
&lt;li&gt;Find the button.&lt;/li&gt;
&lt;li&gt;Simulate a tap.&lt;/li&gt;
&lt;li&gt;Wait for the page to change.&lt;/li&gt;
&lt;li&gt;Retry after errors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The AppFunctions direction is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apps declare what they can do.&lt;/li&gt;
&lt;li&gt;Agents call those capabilities with authorization.&lt;/li&gt;
&lt;li&gt;The system handles permissions, call boundaries, and security constraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will affect Android app design. Future apps will not only need human-facing UIs, but also core capabilities designed as Agent-callable interfaces.&lt;/p&gt;
&lt;h2 id=&#34;search-shopping-and-content-products-are-becoming-agentic-too&#34;&gt;Search, Shopping, and Content Products Are Becoming Agentic Too
&lt;/h2&gt;&lt;p&gt;Google I/O 2026 changes are not limited to models and developer tools. Search and consumer products are changing at the same time.&lt;/p&gt;
&lt;p&gt;Official I/O summaries mention:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search entering a new AI Search stage.&lt;/li&gt;
&lt;li&gt;Information agents appearing in Search.&lt;/li&gt;
&lt;li&gt;Gemini Spark and Daily Brief entering Gemini app.&lt;/li&gt;
&lt;li&gt;Universal Cart making shopping carts smarter.&lt;/li&gt;
&lt;li&gt;Ask YouTube enabling conversational queries and navigation over video content.&lt;/li&gt;
&lt;li&gt;Gemini capabilities expanding to more products and form factors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These announcements show that Google&amp;rsquo;s Agent direction is not a single product. It is spreading horizontally across search, video, shopping, productivity, mobile, and hardware scenarios.&lt;/p&gt;
&lt;h2 id=&#34;practical-impact-for-developers&#34;&gt;Practical Impact for Developers
&lt;/h2&gt;&lt;p&gt;The biggest impact of Google I/O 2026 for developers is not &amp;ldquo;another model.&amp;rdquo; It is that the development target is changing.&lt;/p&gt;
&lt;p&gt;Developers used to mainly build:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apps.&lt;/li&gt;
&lt;li&gt;Websites.&lt;/li&gt;
&lt;li&gt;APIs.&lt;/li&gt;
&lt;li&gt;Plugins.&lt;/li&gt;
&lt;li&gt;Automation scripts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, they will also build:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;App capabilities callable by Agents.&lt;/li&gt;
&lt;li&gt;Multi-Agent workflows.&lt;/li&gt;
&lt;li&gt;Stateful tool execution environments.&lt;/li&gt;
&lt;li&gt;Auditable automation flows.&lt;/li&gt;
&lt;li&gt;Human-in-the-loop confirmation mechanisms.&lt;/li&gt;
&lt;li&gt;Integrations with MCP, AppFunctions, Workspace API, Playwright, Firebase, and other tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Software will increasingly look like a set of capabilities, not only a set of interfaces. Products that expose their capabilities clearly, reliably, and safely to Agents will be more likely to enter users&amp;rsquo; automation task chains.&lt;/p&gt;
&lt;h2 id=&#34;impact-on-mobile-automation&#34;&gt;Impact on Mobile Automation
&lt;/h2&gt;&lt;p&gt;Mobile automation will gradually move from &amp;ldquo;GUI first&amp;rdquo; to &amp;ldquo;API first, GUI as fallback.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;In the short term, screenshot recognition, OCR, simulated taps, and browser automation still matter because many older apps have no standard interface.&lt;/p&gt;
&lt;p&gt;In the long term, if Android AppFunctions, MCP, and system-level permission models mature, stable task execution will lean toward:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First calling capabilities declared by apps.&lt;/li&gt;
&lt;li&gt;Then calling system interfaces when needed.&lt;/li&gt;
&lt;li&gt;Then using GUI automation as a fallback.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will change RPA, mobile Agents, testing tools, and app ecosystems. Apps that expose capabilities are easier for system-level Agents to call. Apps that do not may still only be operated by the old &amp;ldquo;look at screen, tap screen&amp;rdquo; approach.&lt;/p&gt;
&lt;h2 id=&#34;security-permissions-and-auditing-become-hard-requirements&#34;&gt;Security, Permissions, and Auditing Become Hard Requirements
&lt;/h2&gt;&lt;p&gt;The stronger Agents become, the higher the risk.&lt;/p&gt;
&lt;p&gt;If an Agent can execute tasks across apps, make payments, change settings, access files, and read context, it needs clear security boundaries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Permission levels.&lt;/li&gt;
&lt;li&gt;Explicit user authorization.&lt;/li&gt;
&lt;li&gt;Secondary confirmation for sensitive actions.&lt;/li&gt;
&lt;li&gt;Sandbox isolation.&lt;/li&gt;
&lt;li&gt;Operation logs.&lt;/li&gt;
&lt;li&gt;Reversibility and rollback.&lt;/li&gt;
&lt;li&gt;Enterprise auditing and compliance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is why Google emphasizes isolated environments for hosted Agents, permission requirements for AppFunctions, enterprise platforms, and controlled deployment. The future of Agents is not &amp;ldquo;do anything without limits,&amp;rdquo; but executable, traceable, and governable behavior inside security boundaries.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;The main content of Google I/O 2026 can be summarized in one sentence: Google is turning Gemini into an Agent platform spanning models, apps, systems, developer tools, and hardware.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; provides speed and action capability. &lt;code&gt;Gemini Omni&lt;/code&gt; pushes multimodal creation toward video and world understanding. &lt;code&gt;Gemini app&lt;/code&gt; becomes a proactive personal assistant. &lt;code&gt;Antigravity 2.0&lt;/code&gt; and &lt;code&gt;Managed Agents&lt;/code&gt; push developer tools toward Agent-native development. &lt;code&gt;AppFunctions&lt;/code&gt; lets Android apps begin exposing capabilities to intelligent agents.&lt;/p&gt;
&lt;p&gt;For developers, the next thing to watch is not only model parameters, but how to structure application capabilities, connect to Agent toolchains, design permissions and auditing, and make products safely and reliably callable in a system-level Agent ecosystem.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-collection/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: Google I/O 2026 news and announcements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-developer-highlights/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: I/O 2026 developer highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/products/gemini-app/next-evolution-gemini-app/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: The Gemini app becomes more agentic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.android.com/ai/appfunctions?hl=zh-cn&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Android Developers: AppFunctions overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>How to Use Gemini 3.5 Flash and Gemini Omni for Free: Entry Points for Users and Developers</title>
        <link>https://knightli.com/en/2026/05/20/gemini-3-5-flash-omni-free-access/</link>
        <pubDate>Wed, 20 May 2026 23:13:35 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/20/gemini-3-5-flash-omni-free-access/</guid>
        <description>&lt;p&gt;After Google released Gemini 3.5 Flash and Gemini Omni, the practical question is not the benchmark score, but how ordinary users and developers can actually use them, which entry points are free, and which ones are only low-friction trials.&lt;/p&gt;
&lt;p&gt;The short version:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For chat, writing, image understanding, and everyday Q&amp;amp;A: use Gemini app first.&lt;/li&gt;
&lt;li&gt;To test Gemini 3.5 Flash parameters, prompts, and multimodal input: use Google AI Studio.&lt;/li&gt;
&lt;li&gt;To call Gemini 3.5 Flash from code: create an API key in AI Studio.&lt;/li&gt;
&lt;li&gt;To try it from the terminal for free: look at Gemini CLI.&lt;/li&gt;
&lt;li&gt;To try Gemini Omni video editing: start with Gemini app and Google Flow.&lt;/li&gt;
&lt;li&gt;For real production use: do not rely on free quotas; move to a paid API or Vertex AI.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: free quotas, regional availability, subscription tiers, and model menus change over time. This article was written on May 20, 2026. Before official use, always check Google&amp;rsquo;s current pages.&lt;/p&gt;
&lt;h2 id=&#34;free-gemini-35-flash-method-1-gemini-app&#34;&gt;Free Gemini 3.5 Flash Method 1: Gemini App
&lt;/h2&gt;&lt;p&gt;The simplest entry point is Gemini app:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://gemini.google.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://gemini.google.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The basic flow is straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open Gemini.&lt;/li&gt;
&lt;li&gt;Sign in with a Google account.&lt;/li&gt;
&lt;li&gt;Look for &lt;code&gt;3.5 Flash&lt;/code&gt; in the model selector.&lt;/li&gt;
&lt;li&gt;Start chatting.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This entry point is best for ordinary users. You can use it for writing, summarization, image understanding, file analysis, everyday Q&amp;amp;A, and simple planning. According to public reports, Gemini 3.5 Flash has been made available to users globally and can be selected from Gemini&amp;rsquo;s model dropdown.&lt;/p&gt;
&lt;p&gt;The limits are also clear: free users usually face daily message, regional, and feature limits. If you exceed the limit, you need to wait for the quota to refresh or upgrade your subscription.&lt;/p&gt;
&lt;h2 id=&#34;free-gemini-35-flash-method-2-google-ai-studio&#34;&gt;Free Gemini 3.5 Flash Method 2: Google AI Studio
&lt;/h2&gt;&lt;p&gt;If you want more than chat, and need to tune prompts, inspect parameters, or test structured output, Google AI Studio is a better fit:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://aistudio.google.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://aistudio.google.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Basic flow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sign in to Google AI Studio.&lt;/li&gt;
&lt;li&gt;Create a new prompt.&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;gemini-3.5-flash&lt;/code&gt; in the model dropdown.&lt;/li&gt;
&lt;li&gt;Enter the prompt and run it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;AI Studio gives you more control. You can adjust temperature, system instructions, structured output, and multi-image input, and you can export a working prompt into code or an API call.&lt;/p&gt;
&lt;p&gt;For developers, AI Studio is a free testing bench. Tune the prompt and input format here first, then move into API integration to avoid wasting quota.&lt;/p&gt;
&lt;h2 id=&#34;free-gemini-35-flash-method-3-free-api-key&#34;&gt;Free Gemini 3.5 Flash Method 3: Free API Key
&lt;/h2&gt;&lt;p&gt;Developers care most about the API. AI Studio can create a Gemini API key for calling &lt;code&gt;gemini-3.5-flash&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Basic flow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open Google AI Studio.&lt;/li&gt;
&lt;li&gt;Find &lt;code&gt;Get API key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Select or create a project.&lt;/li&gt;
&lt;li&gt;Create an API key.&lt;/li&gt;
&lt;li&gt;Save the key to a local environment variable.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Python example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GEMINI_API_KEY&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-3.5-flash&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Explain in three sentences what Gemini 3.5 Flash is best suited for.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Node.js example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;GoogleGenAI&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;@google/genai&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ai&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;GoogleGenAI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;apiKey&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;GEMINI_API_KEY&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ai&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;generateContent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-3.5-flash&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Explain in three sentences what Gemini 3.5 Flash is best suited for.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;curl&lt;/code&gt; example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash:generateContent&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;x-goog-api-key: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$GEMINI_API_KEY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;contents&amp;#34;:[{&amp;#34;parts&amp;#34;:[{&amp;#34;text&amp;#34;:&amp;#34;Hello Gemini 3.5 Flash&amp;#34;}]}]}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Public information suggests that the AI Studio free tier usually gives Gemini Flash models a daily request allowance. The exact numbers can vary by time, region, and account status. Common claims include around 1,500 requests per day, per-minute request limits, and token limits. Do not bake those numbers into a production plan; check Google&amp;rsquo;s current pricing and limits pages before launch.&lt;/p&gt;
&lt;h2 id=&#34;free-gemini-35-flash-method-4-gemini-cli&#34;&gt;Free Gemini 3.5 Flash Method 4: Gemini CLI
&lt;/h2&gt;&lt;p&gt;If you like the command line, look at Gemini CLI. It is useful for temporary scripts, repository summaries, file reading, and quick Q&amp;amp;A in the terminal.&lt;/p&gt;
&lt;p&gt;Installation is usually:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g @google/gemini-cli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Then run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gemini
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The CLI is better suited to personal developer workflows than production integration. Production should still use API keys, service accounts, permission controls, and auditable calling patterns.&lt;/p&gt;
&lt;h2 id=&#34;free-or-low-friction-gemini-omni-access-gemini-app-and-google-flow&#34;&gt;Free or Low-Friction Gemini Omni Access: Gemini App and Google Flow
&lt;/h2&gt;&lt;p&gt;Gemini Omni is a multimodal model for video creation and editing. Its core capability is not ordinary text Q&amp;amp;A, but multi-turn video editing with natural language while referencing image, text, video, and audio inputs.&lt;/p&gt;
&lt;p&gt;The Google DeepMind page lists these entry points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini app.&lt;/li&gt;
&lt;li&gt;Google Flow.&lt;/li&gt;
&lt;li&gt;YouTube Shorts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The page also notes that a Google AI subscription is required, and that features vary by subscription tier and region. So &amp;ldquo;free access&amp;rdquo; to Gemini Omni should be understood more carefully: some entry points may let free users see or try part of the experience, but full video editing may require a subscription, regional availability, or product rollout access.&lt;/p&gt;
&lt;p&gt;If you only want to try it, use this order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open Gemini app first and check whether Gemini Omni or a related video editing entry is available.&lt;/li&gt;
&lt;li&gt;Then open Google Flow: &lt;a class=&#34;link&#34; href=&#34;https://flow.google/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://flow.google/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you make short-form content, watch for Omni-related editing features in YouTube Shorts.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If the entry point is not visible, it usually does not mean you did something wrong. Your account, region, subscription tier, or rollout group may simply not qualify yet.&lt;/p&gt;
&lt;h2 id=&#34;how-gemini-omni-is-best-used&#34;&gt;How Gemini Omni Is Best Used
&lt;/h2&gt;&lt;p&gt;Gemini Omni is more suitable for creators than for ordinary chat.&lt;/p&gt;
&lt;p&gt;You can try these directions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Upload or select a video and ask it to change the style.&lt;/li&gt;
&lt;li&gt;Make a specific action in the video more exaggerated.&lt;/li&gt;
&lt;li&gt;Use a reference image to replace an object or character in the scene.&lt;/li&gt;
&lt;li&gt;Modify camera, action, environment, and style over multiple turns.&lt;/li&gt;
&lt;li&gt;Combine sketches, reference images, audio, or video into a new output.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can write prompts as if giving instructions to an editor:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Keep the original person and room structure unchanged. Change the effect after touching the mirror into liquid ripples. The motion should feel natural, and the lighting should not change abruptly.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;For multi-turn editing, do not pack too many requirements into one request. A safer approach is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Change the main action first.&lt;/li&gt;
&lt;li&gt;Then change the style.&lt;/li&gt;
&lt;li&gt;Then adjust the camera angle.&lt;/li&gt;
&lt;li&gt;Finally tune sound, text, and rhythm.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This makes consistency easier to maintain and helps you identify which step caused a problem.&lt;/p&gt;
&lt;h2 id=&#34;common-pitfalls-when-using-free-access&#34;&gt;Common Pitfalls When Using Free Access
&lt;/h2&gt;&lt;p&gt;First, free quota is not production quota. A free API key is suitable for testing, personal tools, and prototypes, not for promising a stable service.&lt;/p&gt;
&lt;p&gt;Second, do not send sensitive data to free or third-party entry points. This includes private code, customer data, contracts, keys, financial spreadsheets, and internal documents.&lt;/p&gt;
&lt;p&gt;Third, check data-use settings. Free tiers may have different data-use policies, so review the settings in AI Studio or your Google account before use.&lt;/p&gt;
&lt;p&gt;Fourth, video capabilities are usually more restricted than text capabilities. Gemini Omni-style video editing may be limited by subscription, region, queueing, duration, resolution, and content safety policies.&lt;/p&gt;
&lt;p&gt;Fifth, be careful with third-party &amp;ldquo;unlimited free API&amp;rdquo; services. Many gateways rate-limit, forward requests, keep logs, or use opaque payment methods. Sensitive work should not go through these entry points.&lt;/p&gt;
&lt;h2 id=&#34;which-entry-point-should-you-choose&#34;&gt;Which Entry Point Should You Choose?
&lt;/h2&gt;&lt;p&gt;If you are an ordinary user:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini 3.5 Flash: use Gemini app.&lt;/li&gt;
&lt;li&gt;Gemini Omni: check Gemini app first, then Google Flow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are a creator:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Google Flow to try Omni video workflows.&lt;/li&gt;
&lt;li&gt;Use Gemini app for scripts, storyboards, prompts, and material descriptions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are a developer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use AI Studio to debug prompts.&lt;/li&gt;
&lt;li&gt;Use an API key to integrate &lt;code&gt;gemini-3.5-flash&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use Gemini CLI for personal terminal workflows.&lt;/li&gt;
&lt;li&gt;For production, consider Vertex AI or the paid API.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are an enterprise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do not rely on free quotas.&lt;/li&gt;
&lt;li&gt;Focus on permissions, logs, audits, data residency, compliance, and key management.&lt;/li&gt;
&lt;li&gt;For video generation and editing, add watermarking, content review, and copyright processes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 Flash has relatively clear free access paths: Gemini app, Google AI Studio, AI Studio API key, and Gemini CLI can all serve as low-friction entry points. It is suitable for chat, writing, coding, agent prototypes, and multimodal testing.&lt;/p&gt;
&lt;p&gt;Gemini Omni focuses on video editing and multimodal creation. Its main entry points are Gemini app, Google Flow, and YouTube Shorts, but full capabilities are more likely to depend on subscription and region. It is best for creators to start with trials and concept validation, not to plan around it as a stable production service from day one.&lt;/p&gt;
&lt;p&gt;The safest strategy is: test text and code tasks first with the Gemini 3.5 Flash free tier; validate video creation effects with Gemini Omni in Gemini app or Flow; when you need to launch something real, move to a formal setup with auditability, billing, and controlled permissions.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://deepmind.google/models/gemini/flash/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google DeepMind: Gemini 3.5 Flash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://deepmind.google/models/gemini-omni/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google DeepMind: Gemini Omni&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://apidog.com/blog/how-to-use-gemini-3-5-for-free/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apidog: How to Use Gemini 3.5 Flash for Free&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.freedidi.com/24249.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;freedidi original link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini 3.5 Is Here: Flash Leads as Google Focuses on Agents and Long-Running Tasks</title>
        <link>https://knightli.com/en/2026/05/20/google-gemini-3-5-flash-agent-coding/</link>
        <pubDate>Wed, 20 May 2026 22:51:31 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/20/google-gemini-3-5-flash-agent-coding/</guid>
        <description>&lt;p&gt;Google officially released the Gemini 3.5 series on May 20, 2026. The first model available is Gemini 3.5 Flash. Its positioning is not just chat, but agents, code generation, and long-running complex task execution.&lt;/p&gt;
&lt;p&gt;The message is clear: Google wants Gemini 3.5 to answer questions, but also to plan, execute, check results, and keep work moving across multi-step workflows.&lt;/p&gt;
&lt;h2 id=&#34;gemini-35-flash-comes-first&#34;&gt;Gemini 3.5 Flash Comes First
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 Flash is already available to several groups:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;General users can try it in the Gemini app and AI Mode in Google Search.&lt;/li&gt;
&lt;li&gt;Developers can use it through Google Antigravity, Google AI Studio, and the Gemini API in Android Studio.&lt;/li&gt;
&lt;li&gt;Enterprise users can access it through Gemini Enterprise Agent Platform and Gemini Enterprise.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google also said Gemini 3.5 Pro is still in development, already being used internally at Google, and expected to launch next month.&lt;/p&gt;
&lt;p&gt;This means the 3.5 series will continue the Flash and Pro split: Flash emphasizes speed, cost, and scalable execution, while Pro will likely target more complex and higher-capability use cases.&lt;/p&gt;
&lt;h2 id=&#34;the-focus-is-agents-and-coding&#34;&gt;The Focus Is Agents and Coding
&lt;/h2&gt;&lt;p&gt;Google describes Gemini 3.5 Flash as one of its strongest models for agents and coding. The announcement says it beats some Gemini 3.1 Pro results on coding and agent benchmarks such as Terminal-Bench 2.1, GDPval-AA, MCP Atlas, and CharXiv Reasoning.&lt;/p&gt;
&lt;p&gt;Most users do not need to care about every benchmark number. The more important point is that Google is pushing model capability toward executable workflows: not only writing code, but also migrating old projects, developing complex apps, organizing financial reports, analyzing data, and running repeated tests.&lt;/p&gt;
&lt;p&gt;In the Antigravity development framework, Gemini 3.5 Flash can use multiple collaborating subagents to handle large tasks. Google showed examples such as reading the AlphaZero paper and building a playable game, converting legacy code to Next.js, and generating cityscapes and UI options in parallel.&lt;/p&gt;
&lt;p&gt;The direction is clear: AI coding tools are moving from &amp;ldquo;generate a piece of code&amp;rdquo; toward &amp;ldquo;coordinate multiple agents to complete a project.&amp;rdquo;&lt;/p&gt;
&lt;h2 id=&#34;stronger-multimodal-ui-and-graphics&#34;&gt;Stronger Multimodal UI and Graphics
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 Flash builds on Gemini 3&amp;rsquo;s multimodal foundation. Google says it can generate richer web UIs, interactive animations, and visual content.&lt;/p&gt;
&lt;p&gt;The announcement includes examples such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating interactive animations for research papers.&lt;/li&gt;
&lt;li&gt;Turning text descriptions into interactive hardware models.&lt;/li&gt;
&lt;li&gt;Generating a complete brand concept for a school fundraiser.&lt;/li&gt;
&lt;li&gt;Producing multiple UX options for a checkout flow in a short time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This matters for developers and product teams. The model is no longer only writing explanations. It can participate in frontend prototypes, interaction design, and visualization work.&lt;/p&gt;
&lt;h2 id=&#34;enterprise-use-automating-time-consuming-workflows&#34;&gt;Enterprise Use: Automating Time-Consuming Workflows
&lt;/h2&gt;&lt;p&gt;Google listed several partner examples. Shopify uses subagents to analyze complex data and forecast merchant growth. Macquarie Bank is testing 3.5 Flash on documents over 100 pages to accelerate account-opening workflows. Salesforce is integrating it into Agentforce. Ramp uses it to improve OCR for complex invoices. Xero uses AI agents for administrative workflows. Databricks uses automated workflows to monitor data anomalies and suggest fixes.&lt;/p&gt;
&lt;p&gt;These examples point to the same trend: enterprise adoption of large models is moving from one-off Q&amp;amp;A to workflow automation. Whether a model is inexpensive, fast, and stable over long tasks can matter more than whether one answer looks impressive.&lt;/p&gt;
&lt;h2 id=&#34;gemini-spark-a-personal-ai-agent&#34;&gt;Gemini Spark: A Personal AI Agent
&lt;/h2&gt;&lt;p&gt;Google also announced Gemini Spark, a personal AI agent powered by Gemini 3.5 Flash. Its goal is to run over long periods and proactively perform tasks under user guidance.&lt;/p&gt;
&lt;p&gt;Gemini Spark has started rolling out to trusted testers. Google plans to open a beta next week to Google AI Ultra subscribers in the United States.&lt;/p&gt;
&lt;p&gt;This is worth watching. Google Search, the Gemini app, Android, Workspace, and browser-related ecosystems already touch many parts of personal digital life. If a personal agent can connect with these entry points, its impact may be larger than a standalone chatbot.&lt;/p&gt;
&lt;h2 id=&#34;safety-moves-further-upstream&#34;&gt;Safety Moves Further Upstream
&lt;/h2&gt;&lt;p&gt;Google says Gemini 3.5 was developed under its Frontier Safety Framework, with strengthened protections for information security and CBRN-related risks. The announcement also mentions interpretability tools that help examine and understand model reasoning before responses are delivered.&lt;/p&gt;
&lt;p&gt;This shows that frontier model releases are no longer only a capability race. The more a model emphasizes agents, autonomous execution, and long-running tasks, the more important safety controls, false refusal rates, harmful-output prevention, and interpretability become.&lt;/p&gt;
&lt;h2 id=&#34;how-to-view-gemini-35&#34;&gt;How to View Gemini 3.5
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 Flash is not just another model launch. It looks more like Google&amp;rsquo;s bet on the next shape of AI products: models that can call tools, split tasks, coordinate execution, generate UIs, and enter personal and enterprise workflows.&lt;/p&gt;
&lt;p&gt;For developers, the important things to watch are the real experience in Google Antigravity, AI Studio, the Gemini API, and Android Studio. For enterprises, the question is whether it can reliably reduce manual work in real workflows, not just score well on benchmarks.&lt;/p&gt;
&lt;p&gt;Gemini 3.5 Pro is not publicly available yet. Once Pro ships, the differences between Flash and Pro in capability, price, speed, and context handling will decide which production scenarios each model fits best.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/intl/zh-tw/products/explore-get-answers/gemini-3-5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: Gemini 3.5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Google Gemini Spark Leak: A 24/7 Gemini Agent May Be Coming</title>
        <link>https://knightli.com/en/2026/05/17/google-gemini-spark-ai-agent-leak/</link>
        <pubDate>Sun, 17 May 2026 11:58:08 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/17/google-gemini-spark-ai-agent-leak/</guid>
        <description>&lt;p&gt;Google has not officially released &lt;code&gt;Gemini Spark&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Current information about it mainly comes from internal Gemini Web test screens, community screenshots, TestingCatalog reporting, and 36Kr / Xinzhiyuan&amp;rsquo;s summary of related leaks. The consistent picture is that &lt;code&gt;Gemini Spark BETA&lt;/code&gt; may be an always-on AI Agent that Google is preparing. Its positioning is no longer just a chat assistant, but an &amp;ldquo;everyday AI agent&amp;rdquo; that can handle email, online tasks, and multi-step workflows in the background.&lt;/p&gt;
&lt;p&gt;So the boundary should be clear first: this is a leak analysis, not an official Google announcement. All features, naming, and launch timing still need to be confirmed by Google.&lt;/p&gt;
&lt;h2 id=&#34;bottom-line&#34;&gt;Bottom line
&lt;/h2&gt;&lt;p&gt;Based on currently exposed information, Gemini Spark has three key points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It may be a 24-hour online Agent inside the Gemini system, not a normal chat model.&lt;/li&gt;
&lt;li&gt;It may use broader personal context, including Google apps, chat history, tasks, logged-in websites, and location.&lt;/li&gt;
&lt;li&gt;Its risks are as large as its appeal, because it may involve information sharing, remote browser data, purchases, and third-party service calls.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If Google really launches Spark, Gemini&amp;rsquo;s role will change from &amp;ldquo;AI that answers questions&amp;rdquo; to &amp;ldquo;AI that continuously handles tasks for you.&amp;rdquo;&lt;/p&gt;
&lt;h2 id=&#34;what-gemini-spark-is&#34;&gt;What Gemini Spark is
&lt;/h2&gt;&lt;p&gt;TestingCatalog reported on May 14, 2026 that Google is testing &lt;code&gt;Gemini Spark BETA&lt;/code&gt; inside Gemini Web. The exposed welcome text describes it as an everyday AI agent that can help users 24/7 with inbox, online tasks, and more multi-step work.&lt;/p&gt;
&lt;p&gt;The 36Kr / Xinzhiyuan article also says that after Spark was uncovered, the outside world saw a &amp;ldquo;full-time Agent&amp;rdquo; direction: it can stay on standby all day, process inboxes, execute online tasks, and may even involve purchases and information sharing.&lt;/p&gt;
&lt;p&gt;This means Spark is not simply a new model name. It looks more like a Gemini product-layer upgrade: bringing Gemini out of the conversation window and into users&amp;rsquo; email, web, calendar, tasks, and cross-app workflows.&lt;/p&gt;
&lt;h2 id=&#34;how-it-may-work&#34;&gt;How it may work
&lt;/h2&gt;&lt;p&gt;According to the hidden onboarding text disclosed by TestingCatalog, Gemini Spark may gather context from multiple sources, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connected Apps.&lt;/li&gt;
&lt;li&gt;skills.&lt;/li&gt;
&lt;li&gt;chats.&lt;/li&gt;
&lt;li&gt;tasks.&lt;/li&gt;
&lt;li&gt;Websites the user has logged into.&lt;/li&gt;
&lt;li&gt;Personal intelligence.&lt;/li&gt;
&lt;li&gt;location.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This information would help Spark understand what the user wants to complete and call the necessary context while executing tasks. The text also says that, to complete some actions, Gemini may share necessary information with third parties, such as names, contact details, files, preferences, and information the user may consider sensitive.&lt;/p&gt;
&lt;p&gt;If these descriptions prove accurate, Spark will work more like a context-aware agent system than a one-shot Q&amp;amp;A assistant. It will not only look at the current prompt, but may combine long-term preferences, connected apps, browser state, and task history.&lt;/p&gt;
&lt;h2 id=&#34;why-it-matters&#34;&gt;Why it matters
&lt;/h2&gt;&lt;p&gt;The key to Gemini Spark is not one more chat entry point. It is that Google has a natural ecosystem entry point.&lt;/p&gt;
&lt;p&gt;OpenAI and Anthropic can build powerful Agents, but they do not naturally own the full chain of Gmail, Calendar, Drive, Chrome, Android, and Workspace. If Google connects Spark into these products, users will not need to build many extra workflows before letting an Agent enter daily work.&lt;/p&gt;
&lt;p&gt;This may bring three changes.&lt;/p&gt;
&lt;p&gt;First, Gemini may move from passive Q&amp;amp;A to active execution. Users may no longer only ask &amp;ldquo;summarize this email&amp;rdquo;; they may ask it to continuously organize the inbox, track tasks, and take follow-up actions.&lt;/p&gt;
&lt;p&gt;Second, Agents will rely more on personal context. The more it understands your email, calendar, files, browser state, and preferences, the more useful the result may be.&lt;/p&gt;
&lt;p&gt;Third, permission boundaries will become more sensitive. Doing more also means users need to know more clearly when it can act, how far it can go, and whether confirmation is required.&lt;/p&gt;
&lt;h2 id=&#34;where-the-risks-are&#34;&gt;Where the risks are
&lt;/h2&gt;&lt;p&gt;Several details in the onboarding text disclosed by TestingCatalog are worth watching.&lt;/p&gt;
&lt;p&gt;First, Spark is experimental. Even if it launches, it should not be treated as a fully mature system that needs no supervision.&lt;/p&gt;
&lt;p&gt;Second, although the system is designed to ask for permission before sensitive operations, the text also warns that it may share information or complete purchases without asking.&lt;/p&gt;
&lt;p&gt;Third, to maintain session continuity, Gemini will save remote browser data, such as login details and remote code execution data. Users can clear these data in Settings and can also disable Connected Apps and Personal intelligence.&lt;/p&gt;
&lt;p&gt;Taken together, these points show that Spark&amp;rsquo;s product direction is aggressive: it wants to be an Agent that can truly execute tasks, not only generate suggestions. But the closer it gets to real execution, the more it needs strict permissioning, auditing, confirmation, and rollback mechanisms.&lt;/p&gt;
&lt;h2 id=&#34;relationship-with-remy-and-ai-ultra&#34;&gt;Relationship with Remy and AI Ultra
&lt;/h2&gt;&lt;p&gt;TestingCatalog says Spark may be a renamed version of the agentic Gemini upgrade previously codenamed &lt;code&gt;Remy&lt;/code&gt;, and may also relate to the Gemini Agent direction for Google AI Ultra subscribers.&lt;/p&gt;
&lt;p&gt;If this clue is correct, Spark may not be a brand-new project from nowhere. It may be Google repackaging previously higher-end or more closed Agent capabilities and preparing to bring them to a wider audience.&lt;/p&gt;
&lt;p&gt;36Kr / Xinzhiyuan also describes it as an upgrade from &amp;ldquo;Remy&amp;rdquo; to &amp;ldquo;Spark&amp;rdquo;: Gemini Agent is no longer just a feature, but is moving toward a 24/7 digital life manager.&lt;/p&gt;
&lt;p&gt;But this is still a judgment based on leaked information. Whether Google will use &lt;code&gt;Spark&lt;/code&gt; as the official name, whether it will be limited to AI Ultra, and whether a lighter subscription tier will appear all need official confirmation.&lt;/p&gt;
&lt;h2 id=&#34;mcp-skills-and-the-tool-ecosystem&#34;&gt;MCP, skills, and the tool ecosystem
&lt;/h2&gt;&lt;p&gt;The same batch of community screenshots also showed model selector entries such as &lt;code&gt;MCP Tool Testing&lt;/code&gt;. The 36Kr article suggests this may hint that the new Gemini will natively support MCP third-party tool integration, with Thinking mode also being rebuilt.&lt;/p&gt;
&lt;p&gt;This clue becomes more interesting when viewed together with Spark.&lt;/p&gt;
&lt;p&gt;If Spark were only a chat assistant, skills and MCP would matter less. But if Spark is a long-running Agent, it needs to reliably call tools, access web pages, execute tasks, read and write context, and deliver results to users.&lt;/p&gt;
&lt;p&gt;In other words, Spark may not be a single feature. It may be part of Google&amp;rsquo;s Agent tool ecosystem: the model handles understanding and planning, while skills / MCP / connected apps handle execution and expansion.&lt;/p&gt;
&lt;h2 id=&#34;what-it-means-for-ordinary-users&#34;&gt;What it means for ordinary users
&lt;/h2&gt;&lt;p&gt;If Gemini Spark really launches, ordinary users may see these direct changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Email is not only summarized, but can be categorized, followed up, and turned into tasks.&lt;/li&gt;
&lt;li&gt;Web tasks are not only suggested, but may be continuously executed in a remote browser.&lt;/li&gt;
&lt;li&gt;Calendar, location, preferences, and previous chats become long-term Agent context.&lt;/li&gt;
&lt;li&gt;Purchases, bookings, form filling, and similar actions may enter the AI execution range.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This sounds convenient, but users will need new habits: not only checking what the AI says, but also what it is preparing to do, what it has already done, whether it can be undone, and whether there is a record.&lt;/p&gt;
&lt;p&gt;Future AI Agent experience may depend not only on model intelligence, but also on clear permission prompts, inspectable task logs, and recovery from mistakes.&lt;/p&gt;
&lt;h2 id=&#34;what-it-means-for-developers-and-teams&#34;&gt;What it means for developers and teams
&lt;/h2&gt;&lt;p&gt;For developers, Spark matters because Google may be moving Agents from &amp;ldquo;demo products&amp;rdquo; toward real workflow platforms.&lt;/p&gt;
&lt;p&gt;If Spark can reliably connect Google apps, third-party tools, and browser state, developers will care about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Whether APIs or extension mechanisms are open.&lt;/li&gt;
&lt;li&gt;Whether MCP or skills can be connected by third parties.&lt;/li&gt;
&lt;li&gt;Whether enterprise admins can control permissions, data retention, and audits.&lt;/li&gt;
&lt;li&gt;Whether Agent execution failures have traceable logs.&lt;/li&gt;
&lt;li&gt;Whether sandboxing, approval flows, and sensitive-operation confirmation are supported.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For teams, Spark may first enter high-frequency scenarios such as Gmail, Calendar, Docs, Drive, and Chrome. It may not be suitable for fully automated high-risk work at the beginning, but it is a strong fit for inbox triage, meeting follow-up, document organization, market research, and lightweight operations tasks.&lt;/p&gt;
&lt;h2 id=&#34;how-to-read-it-now&#34;&gt;How to read it now
&lt;/h2&gt;&lt;p&gt;This story is best understood as &amp;ldquo;high-confidence direction, low-certainty details.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The high-confidence direction is that Google is pushing Gemini Agents to be more proactive, longer-running, and more deeply integrated with its ecosystem. The Gemini Web test text reported by TestingCatalog, community screenshots, and 36Kr&amp;rsquo;s summary of multiple leaks all point in the same direction.&lt;/p&gt;
&lt;p&gt;The low-certainty details are the official name, launch timing, permission rules, subscription tiers, supported regions, API availability, and whether it will really be called Gemini Spark.&lt;/p&gt;
&lt;p&gt;The safest view for now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do not treat Spark as an already released official product.&lt;/li&gt;
&lt;li&gt;Treat it as a strong signal for Google&amp;rsquo;s next AI Agent direction.&lt;/li&gt;
&lt;li&gt;Wait for official explanations around permissions, privacy, third-party data sharing, and remote browser data storage.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;If &lt;code&gt;Gemini Spark&lt;/code&gt; eventually launches, it may be a key step in Gemini&amp;rsquo;s move from chat assistant to always-on Agent. It is not just a model swap; it places Gemini into Google&amp;rsquo;s ecosystem of email, web, tasks, location, personal intelligence, and third-party services.&lt;/p&gt;
&lt;p&gt;Its potential is large: more proactive, closer to real workflows, and easier to distribute to many users through Google&amp;rsquo;s ecosystem. Its risks are just as large: once AI can share information, save browser state, make purchases, and call third-party services, permission boundaries must be extremely clear.&lt;/p&gt;
&lt;p&gt;So the most important question about Gemini Spark is not &amp;ldquo;how smart is it&amp;rdquo;, but how Google plans to make a 24-hour online AI Agent controllable, auditable, and trustworthy.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.testingcatalog.com/google-prepares-gemini-spark-ai-agent-ahead-of-i-o-launch/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;TestingCatalog: Google prepares Gemini Spark AI Agent ahead of I/O launch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://36kr.com/p/3810432812162816&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;36Kr: Gemini 3.5 Pro leaked, coding reportedly catches up with GPT-5.5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini 3.5 Pro Leak: Codenamed Cappuccino, Google Tries to Regain Momentum in Coding and Agents</title>
        <link>https://knightli.com/en/2026/05/17/gemini-35-pro-cappuccino-spark-leak/</link>
        <pubDate>Sun, 17 May 2026 11:47:27 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/17/gemini-35-pro-cappuccino-spark-leak/</guid>
        <description>&lt;p&gt;Google has not officially released &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What we can see so far mainly comes from developer community screenshots, anonymous benchmarks, leakers, and media reports. On May 15, 2026, 36Kr / Xinzhiyuan reported that a next-generation Gemini checkpoint may be internally codenamed &lt;code&gt;Cappuccino&lt;/code&gt;, and that related models have already surfaced in communities and benchmark platforms.&lt;/p&gt;
&lt;p&gt;This information should not be treated as an official launch, but it points in a clear direction: Google is trying to address two gaps at once, coding and reasoning on one side, and always-on AI agents on the other.&lt;/p&gt;
&lt;h2 id=&#34;bottom-line&#34;&gt;Bottom line
&lt;/h2&gt;&lt;p&gt;This leak can be read in three layers:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Pro&lt;/code&gt; has not been officially released, and &lt;code&gt;Cappuccino&lt;/code&gt; looks more like an internal checkpoint or candidate build.&lt;/li&gt;
&lt;li&gt;The leaked information suggests the new Gemini is improving in code generation, SVG / interactive web generation, and multimodal output.&lt;/li&gt;
&lt;li&gt;Google&amp;rsquo;s parallel test of &lt;code&gt;Gemini Spark&lt;/code&gt; may matter more than the model itself, because it points to a 24-hour personal AI agent.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In other words, this is not just a &amp;ldquo;model benchmark&amp;rdquo; story. It looks more like a product roadmap signal ahead of Google I/O: the model needs to catch up with GPT-5.5, while the agent layer needs to capture user workflows.&lt;/p&gt;
&lt;h2 id=&#34;what-cappuccino-is&#34;&gt;What Cappuccino is
&lt;/h2&gt;&lt;p&gt;The 36Kr article says a post from Lentils indicates that the &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt; checkpoint codenamed &lt;code&gt;Cappuccino&lt;/code&gt; has started to appear. The community had been discussing &lt;code&gt;Gemini 3.2&lt;/code&gt; only hours earlier, but the latest leak jumped directly to &lt;code&gt;3.5&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If that naming is ultimately accurate, Google may want to frame the next Gemini as a larger version jump rather than a routine point release.&lt;/p&gt;
&lt;p&gt;For now, &lt;code&gt;Cappuccino&lt;/code&gt; should still be treated as a leaked internal codename. It does not mean Google has publicly launched the final model, and it does not guarantee that the final release name will be &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;why-coding-is-the-focus&#34;&gt;Why coding is the focus
&lt;/h2&gt;&lt;p&gt;The most discussed part of the leak is the new Gemini&amp;rsquo;s coding ability.&lt;/p&gt;
&lt;p&gt;According to community screenshots and benchmark claims cited by 36Kr, the new model appears stronger at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generating SVG and visual components.&lt;/li&gt;
&lt;li&gt;Generating interactive web apps.&lt;/li&gt;
&lt;li&gt;Handling animation, 3D, adjustable control panels, and other complex frontend outputs.&lt;/li&gt;
&lt;li&gt;Improving logical reasoning and code generation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The article also cites Abacus.AI CEO Bindu Reddy as saying that &lt;code&gt;3.2 Flash&lt;/code&gt; is close to &lt;code&gt;GPT-5.5&lt;/code&gt; in coding and reasoning while being much cheaper. Other media sources reportedly believe the new Gemini roughly reaches the &lt;code&gt;GPT-5.5&lt;/code&gt; tier overall, but may not represent a qualitative leap.&lt;/p&gt;
&lt;p&gt;That is why the phrase &amp;ldquo;matches GPT-5.5&amp;rdquo; needs caution. It is more of a relative judgment from different leaks and anonymous tests than an official Google benchmark result.&lt;/p&gt;
&lt;h2 id=&#34;why-google-needs-to-catch-up-in-coding&#34;&gt;Why Google needs to catch up in coding
&lt;/h2&gt;&lt;p&gt;AI coding has moved from developer tooling into the center of foundation model competition.&lt;/p&gt;
&lt;p&gt;OpenAI has Codex, and Anthropic has Claude Code. They serve engineers, but they also bring product managers, designers, and operators into workflows where natural language can produce runnable products.&lt;/p&gt;
&lt;p&gt;By comparison, Google has Gemini and Antigravity, but it has not formed the same default entry point in developer mindshare. The 36Kr article also notes that Antigravity has not truly broken through externally, and that pricing, quota reminders, and experience stability have drawn community discussion.&lt;/p&gt;
&lt;p&gt;So if the new Gemini needs to prove itself, coding is the most direct battlefield. The question is not only whether it can write code, but whether it can reliably produce complete interfaces, understand complex requirements, call tools, fix errors, and fit into real development workflows.&lt;/p&gt;
&lt;h2 id=&#34;spark-may-matter-more-than-35-pro&#34;&gt;Spark may matter more than 3.5 Pro
&lt;/h2&gt;&lt;p&gt;In the same wave of leaks, &lt;code&gt;Gemini Spark BETA&lt;/code&gt; also surfaced.&lt;/p&gt;
&lt;p&gt;According to TestingCatalog and other sources, Spark is positioned like an always-on AI agent: it can process inboxes, execute online tasks, manage multi-step workflows, and connect context from Google apps, skill modules, chat history, scheduled tasks, logged-in websites, and location data.&lt;/p&gt;
&lt;p&gt;That means Spark is not a normal chat entry point. It may be a system that stays online, continuously reads context, and performs tasks for users.&lt;/p&gt;
&lt;p&gt;Its appeal is obvious: if Google can connect Gmail, Calendar, Chrome, Android, Workspace, and Gemini, Spark will have a distribution advantage that OpenAI and Anthropic cannot easily copy.&lt;/p&gt;
&lt;p&gt;The risk is just as obvious. The 36Kr article mentions wording around Spark saying it may share information or complete purchases without asking. Even if the system is designed to request permission before sensitive operations, this kind of agent still raises privacy, authorization-boundary, and accidental-action risks.&lt;/p&gt;
&lt;h2 id=&#34;what-this-means-for-ordinary-users&#34;&gt;What this means for ordinary users
&lt;/h2&gt;&lt;p&gt;If you are a regular Gemini user, the most important part of this leak is not the model name. It is three shifts.&lt;/p&gt;
&lt;p&gt;First, Google may continue to strengthen the ability to produce complete results. Users have often complained that Gemini can be lazy with visual generation, SVG, and frontend pages. If the new model can produce several complete options in one pass, the experience will improve noticeably.&lt;/p&gt;
&lt;p&gt;Second, coding ability may continue to move into lighter models. The leak repeatedly mentions Flash improvements in coding, reasoning, and interactive generation, which means complex tasks may not always require Pro models in the future.&lt;/p&gt;
&lt;p&gt;Third, agents will become more proactive. If Spark launches, Gemini may no longer just answer questions. It may start taking over email, web tasks, purchases, calendars, and cross-app workflows over longer periods.&lt;/p&gt;
&lt;p&gt;That is good for efficiency, but it creates a new challenge for permission management.&lt;/p&gt;
&lt;h2 id=&#34;what-this-means-for-developers&#34;&gt;What this means for developers
&lt;/h2&gt;&lt;p&gt;Developers should watch two issues more closely.&lt;/p&gt;
&lt;p&gt;The first is tooling. The 36Kr article says community screenshots showed an unreleased entry called &lt;code&gt;MCP Tool Testing&lt;/code&gt; in the model selector. If Gemini natively supports MCP or third-party tool testing, it will be easier to connect it to developers&amp;rsquo; own toolchains.&lt;/p&gt;
&lt;p&gt;The second is cost and stability. Even if the new Gemini matches GPT-5.5 on some benchmarks, developers will ultimately judge three things: actual code quality, context stability, and whether pricing and quotas are predictable.&lt;/p&gt;
&lt;p&gt;The past year of AI coding tool competition has shown that model capability is only the ticket in. What keeps developers is whether the tool can reliably edit code, run tests, read context, and handle edge cases in daily projects.&lt;/p&gt;
&lt;h2 id=&#34;how-to-read-this-news-now&#34;&gt;How to read this news now
&lt;/h2&gt;&lt;p&gt;This story is best understood as &amp;ldquo;strong signal, weak confirmation.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;The strong signal is that multiple community clues point to Google preparing a stronger new Gemini and a more proactive Gemini Spark Agent.&lt;/p&gt;
&lt;p&gt;The weak confirmation is that &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt; has not been officially released, &lt;code&gt;Cappuccino&lt;/code&gt; remains a leaked codename, and claims that it &amp;ldquo;matches GPT-5.5&amp;rdquo; still need validation through official Google benchmarks, third-party tests, and real user experience.&lt;/p&gt;
&lt;p&gt;The safest view for now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do not treat it as a released product.&lt;/li&gt;
&lt;li&gt;Treat it as an early preview of Google&amp;rsquo;s next Gemini direction.&lt;/li&gt;
&lt;li&gt;Watch whether I/O or later official events confirm the model name, API availability, pricing, context window, tool calling, and agent permission boundaries.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;The exposure of &lt;code&gt;Gemini 3.5 Pro / Cappuccino&lt;/code&gt; suggests Google may be preparing a stronger next-generation Gemini push. It is not trying to fix one isolated capability, but a whole AI workflow: the model needs to write code better, generate interfaces, and handle complex reasoning, while Spark pushes Gemini toward an always-on agent.&lt;/p&gt;
&lt;p&gt;But before an official release, all benchmarks and screenshots remain clues. What will decide whether Gemini 3.5 Pro can regain momentum is not whether the codename sounds good, but whether it can reliably win in real development, real office work, and real multi-step tasks.&lt;/p&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://m.36kr.com/p/3810432812162816&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;36Kr: Gemini 3.5 Pro leaked, coding performance reportedly catches up with GPT-5.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.testingcatalog.com/google-prepares-gemini-spark-ai-agent-ahead-of-i-o-launch/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;TestingCatalog: Google prepares Gemini Spark AI agent ahead of I/O launch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://x.com/alexeheath/status/2054747125616169229&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X: Alex Heath on the new Gemini and GPT-5.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://x.com/Lentils80/status/2054628116094501377&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X: Lentils on Gemini 3.5 / Cappuccino&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini Intelligence on Android: Google Is Turning the Phone into a Proactive AI System</title>
        <link>https://knightli.com/en/2026/05/17/google-gemini-intelligence-android/</link>
        <pubDate>Sun, 17 May 2026 09:13:32 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/17/google-gemini-intelligence-android/</guid>
        <description>&lt;p&gt;On May 12, 2026, Google published “A smarter, more proactive Android with Gemini Intelligence,” introducing Gemini Intelligence on Android. This is not a standalone chat app. It brings Gemini capabilities into Android, Chrome, Gboard, Autofill, widgets, and multi-device experiences, moving the phone from “wait for the user to tap” toward “proactively help the user complete tasks.”&lt;/p&gt;
&lt;p&gt;In short, Google wants Android to move from an operating system toward an intelligence system. The phone no longer just opens apps, shows notifications, and runs settings. It can understand the screen, apps, voice, and personal context, then complete more complex actions with user confirmation.&lt;/p&gt;
&lt;h2 id=&#34;short-version&#34;&gt;Short Version
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence on Android focuses on five areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multi-step automation: Gemini can complete flows across apps, such as rides, shopping, and research.&lt;/li&gt;
&lt;li&gt;Smarter Chrome browsing: summarize pages, compare information, and handle some repetitive web tasks on Android.&lt;/li&gt;
&lt;li&gt;Upgraded Autofill: use Gemini and personal context to fill more complex forms.&lt;/li&gt;
&lt;li&gt;Rambler: turn natural speech into clearer, more polished text.&lt;/li&gt;
&lt;li&gt;Natural-language widgets: describe what you want, and Android generates custom widgets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These features will start rolling out in summer 2026, first on select Samsung Galaxy and Google Pixel phones, and later to more Android devices including watches, cars, glasses, and laptops.&lt;/p&gt;
&lt;h2 id=&#34;multi-step-automation-from-suggestions-to-execution&#34;&gt;Multi-Step Automation: From Suggestions to Execution
&lt;/h2&gt;&lt;p&gt;The most important direction is letting Gemini complete multi-step tasks across apps.&lt;/p&gt;
&lt;p&gt;Google gives examples such as booking a spin class, finding a course syllabus in Gmail and adding required books to a shopping cart, or seeing a travel poster and asking Gemini to find a similar trip on Expedia.&lt;/p&gt;
&lt;p&gt;The hard part is not just understanding one sentence. The system needs to understand:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is on the user’s current screen or image.&lt;/li&gt;
&lt;li&gt;App information the user has authorized.&lt;/li&gt;
&lt;li&gt;Which app should be opened next.&lt;/li&gt;
&lt;li&gt;Which steps can be automated.&lt;/li&gt;
&lt;li&gt;Which steps must pause for user confirmation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google emphasizes that Gemini acts on user instructions and stops when the task is done, with final confirmation remaining under user control. This is not a fully autonomous agent, but a mobile agent with human confirmation in the loop.&lt;/p&gt;
&lt;h2 id=&#34;screen-and-image-context-matter-more&#34;&gt;Screen and Image Context Matter More
&lt;/h2&gt;&lt;p&gt;One important change is screen context and image context.&lt;/p&gt;
&lt;p&gt;Older phone assistants mostly relied on voice commands and fixed app integrations. Gemini Intelligence puts more emphasis on “seeing” the current screen. For example, if a user has a shopping list in notes, they can long-press the power button to summon Gemini and ask it to create a delivery cart from the list.&lt;/p&gt;
&lt;p&gt;This means Android AI is not just a chatbot. It is trying to understand the user’s current operating environment. Future mobile AI competition may depend not only on who has the better model answer, but also on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Whether the AI can understand the current screen.&lt;/li&gt;
&lt;li&gt;Whether it can act across apps.&lt;/li&gt;
&lt;li&gt;Whether it can track task progress in the background.&lt;/li&gt;
&lt;li&gt;Whether it can reliably ask for confirmation at key points.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is a major difference between mobile AI and web chat AI.&lt;/p&gt;
&lt;h2 id=&#34;chrome-from-search-to-web-task-agent&#34;&gt;Chrome: From Search to Web Task Agent
&lt;/h2&gt;&lt;p&gt;Google says Android devices will get a smarter Gemini in Chrome starting in late June 2026.&lt;/p&gt;
&lt;p&gt;It can help users research, summarize, and compare web content, and Chrome auto browse can handle some repetitive web tasks such as appointments and parking reservations.&lt;/p&gt;
&lt;p&gt;This means Gemini in Chrome is not just a page-summary feature. It is moving toward a browser agent. The browser is already where users complete many web tasks. If Gemini can understand pages, fill information, compare options, and execute some steps, Chrome becomes a task execution surface.&lt;/p&gt;
&lt;p&gt;The challenge is practical:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Websites are complex, so automated actions can fail.&lt;/li&gt;
&lt;li&gt;Forms, payments, logins, and CAPTCHAs require caution.&lt;/li&gt;
&lt;li&gt;Users need to know what Gemini did.&lt;/li&gt;
&lt;li&gt;Final submission, payment, or booking should usually remain human-confirmed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The hard part is not only model capability, but browser automation, safety boundaries, and user trust.&lt;/p&gt;
&lt;h2 id=&#34;autofill-from-password-filling-to-complex-forms&#34;&gt;Autofill: From Password Filling to Complex Forms
&lt;/h2&gt;&lt;p&gt;Autofill with Google was mostly about passwords, addresses, and payment details. Google now wants to upgrade it into a smarter form assistant.&lt;/p&gt;
&lt;p&gt;With Gemini’s Personal Intelligence, Android can use relevant information from connected apps to fill more complex form fields, including forms in Chrome.&lt;/p&gt;
&lt;p&gt;This is very practical. Filling complex forms on mobile is painful: small screen, many fields, and information scattered across email, calendar, chats, and documents. If Gemini can organize and fill this information with user permission, it can save a lot of time.&lt;/p&gt;
&lt;p&gt;Google also stresses that connecting Gemini and Autofill with Google is strictly opt-in. Users choose whether to connect them and can turn the connection on or off in settings.&lt;/p&gt;
&lt;p&gt;That matters because Autofill touches personal details, addresses, accounts, payments, work information, and sensitive forms. The more useful it becomes, the more important explicit permission and easy opt-out become.&lt;/p&gt;
&lt;h2 id=&#34;rambler-turning-speech-into-sendable-text&#34;&gt;Rambler: Turning Speech into Sendable Text
&lt;/h2&gt;&lt;p&gt;Rambler is one of the more interesting new features.&lt;/p&gt;
&lt;p&gt;Gboard already supports speech-to-text, but natural speech often includes repetition, pauses, filler words, and self-corrections. Rambler’s goal is to turn natural speech into clearer text that is ready to send.&lt;/p&gt;
&lt;p&gt;It is useful when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You want to dictate a message quickly without editing every word.&lt;/li&gt;
&lt;li&gt;Your speech includes pauses, repetition, or filler.&lt;/li&gt;
&lt;li&gt;You need to turn a rough thought into a more professional text, email, or chat message.&lt;/li&gt;
&lt;li&gt;You switch between languages and want the system to understand context.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google says Rambler will clearly show when it is enabled, and audio is used only for real-time transcription and not saved. This is a response to privacy and transparency concerns.&lt;/p&gt;
&lt;p&gt;From a product perspective, Rambler upgrades “voice input” into “voice writing.” It does not only record what you said; it helps turn speech into sendable text.&lt;/p&gt;
&lt;h2 id=&#34;natural-language-widgets&#34;&gt;Natural-Language Widgets
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence also introduces Create My Widget. Users can describe a widget in natural language, such as “recommend three high-protein meal prep recipes every week,” and Android generates a custom widget for the home screen.&lt;/p&gt;
&lt;p&gt;This points toward generative UI. Users no longer pick only from fixed widget templates; they describe the information and presentation they want.&lt;/p&gt;
&lt;p&gt;If the idea matures, the phone home screen could become much more personal. Weather, schedule, health, commute, food, learning, and work reminders could all become dynamic modules generated around user needs.&lt;/p&gt;
&lt;p&gt;But generative UI also needs stability. A widget is not a one-off chat response. It sits on the home screen for a long time and must be reliable, readable, configurable, and visually controlled.&lt;/p&gt;
&lt;h2 id=&#34;material-3-expressive-and-intelligent-ui&#34;&gt;Material 3 Expressive and Intelligent UI
&lt;/h2&gt;&lt;p&gt;Google also says Gemini Intelligence will bring design updates based on Material 3 Expressive.&lt;/p&gt;
&lt;p&gt;This is not just decoration. When AI starts acting proactively, the UI needs to clearly show:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What the AI is doing.&lt;/li&gt;
&lt;li&gt;Which steps are done.&lt;/li&gt;
&lt;li&gt;Where user confirmation is needed.&lt;/li&gt;
&lt;li&gt;How the user can cancel or change the action.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Proactive AI without clear UI easily makes users feel out of control. Design language becomes part of the AI product experience.&lt;/p&gt;
&lt;h2 id=&#34;availability-and-rollout&#34;&gt;Availability and Rollout
&lt;/h2&gt;&lt;p&gt;According to Google, Gemini Intelligence features will start on the latest Samsung Galaxy and Google Pixel phones in summer 2026, then expand to more Android devices, including watches, cars, glasses, and laptops.&lt;/p&gt;
&lt;p&gt;This is not a global all-at-once launch. Availability may depend on device, region, language, app support, and account settings.&lt;/p&gt;
&lt;p&gt;If you want to try it, the realistic expectations are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Watch Pixel and Samsung flagship phones first.&lt;/li&gt;
&lt;li&gt;Watch for system updates after summer 2026.&lt;/li&gt;
&lt;li&gt;Look for new toggles in Gemini, Chrome, Gboard, Autofill, and Android settings.&lt;/li&gt;
&lt;li&gt;Not every region and language will support every feature at the same time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-this-means-for-android&#34;&gt;What This Means for Android
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence on Android is not just a bundle of small AI features. It changes Android’s product direction.&lt;/p&gt;
&lt;p&gt;Traditional phone operating systems manage apps, notifications, permissions, files, and hardware. Google now wants the system to understand user intent and complete tasks across apps. If this works, Android’s competition will shift from “system features and app ecosystem” toward “how well the system can proactively help users do things.”&lt;/p&gt;
&lt;p&gt;It also changes mobile AI competition:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apple will emphasize on-device integration, privacy, and system-level control.&lt;/li&gt;
&lt;li&gt;Google will emphasize Gemini, Search, Chrome, Android, and multi-device ecosystems.&lt;/li&gt;
&lt;li&gt;Third-party AI apps will find it harder to compete with system-level entry points.&lt;/li&gt;
&lt;li&gt;App developers will need to think about how their apps can be called by AI agents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the next few years, AI on phones may no longer be just a chat entry point. It may become the system-level execution layer.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence on Android is not about adding another Gemini chat box to the phone. It puts AI into Android’s operating flow. Multi-step automation, smarter Chrome browsing, Autofill, Rambler, and natural-language widgets all aim to turn the phone from a passive tool into a proactive assistant.&lt;/p&gt;
&lt;p&gt;Whether it changes user habits depends on reliability, clear privacy controls, smooth cross-app operation, and keeping users in final control. At least from this announcement, Google is defining the next stage of Android as a proactive AI system, not just a traditional mobile operating system.&lt;/p&gt;
&lt;p&gt;Reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/products-and-platforms/platforms/android/gemini-intelligence/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: A smarter, more proactive Android with Gemini Intelligence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini 3.5 Pro Leaks: Google Wants Spark Agent to Win Back the AI Coding Entry Point</title>
        <link>https://knightli.com/en/2026/05/15/gemini-35-pro-spark-agent-ai-coding-race/</link>
        <pubDate>Fri, 15 May 2026 23:45:34 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/15/gemini-35-pro-spark-agent-ai-coding-race/</guid>
        <description>&lt;p&gt;Gemini 3.5 Pro has not been officially released yet, but leaks around it are already heating up.&lt;/p&gt;
&lt;p&gt;The current round of information revolves around several keywords: Gemini 3.5 Pro, the codename Cappuccino, Gemini Spark, AI coding, and MCP tool integration. Together, they point in one direction: Google is not just preparing another chat model update. It wants to reconnect models, tools, Agents, and Google ecosystem entry points.&lt;/p&gt;
&lt;p&gt;Before an official release, all of this should still be treated as leaked information. The more important signal is not one screenshot or one benchmark claim, but the gaps Google may be trying to close next.&lt;/p&gt;
&lt;h2 id=&#34;why-gemini-35-pro-matters&#34;&gt;Why Gemini 3.5 Pro Matters
&lt;/h2&gt;&lt;p&gt;Based on the exposed information, Gemini 3.5 Pro may be a jump in naming.&lt;/p&gt;
&lt;p&gt;People were still discussing Gemini 3.2 earlier, and then Gemini 3.5 Pro appeared in leaks. If the naming is real, Google likely wants to tell a bigger version story in the next release rather than ship a routine minor update.&lt;/p&gt;
&lt;p&gt;The leaked highlights mainly fall into three areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;continued improvements in coding and reasoning;&lt;/li&gt;
&lt;li&gt;stronger SVG, interactive page, animation, and 3D generation;&lt;/li&gt;
&lt;li&gt;a new Agent product, Gemini Spark, potentially moving to the front stage.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these directions is surprising. Gemini has long emphasized multimodality, and Google has very strong distribution channels. The real question is whether it can catch up with OpenAI and Anthropic in developer tools and Agent workflows.&lt;/p&gt;
&lt;h2 id=&#34;coding-is-the-lesson-google-most-needs-to-catch-up-on&#34;&gt;Coding Is The Lesson Google Most Needs To Catch Up On
&lt;/h2&gt;&lt;p&gt;In 2026, coding is no longer just a model benchmark item. It has become one of the most direct product entry points.&lt;/p&gt;
&lt;p&gt;The reason is simple: AI coding tools are used frequently and generate a large amount of feedback data. Developers ask models to read code, modify code, run tests, and fix bugs every day. These interactions naturally push the next generation of models and tooling forward.&lt;/p&gt;
&lt;p&gt;Over the past year, Claude Code has gained strong mindshare among developers, while OpenAI has kept strengthening the connection between Codex and ChatGPT. Google has products such as Antigravity, but its external presence has not been as strong.&lt;/p&gt;
&lt;p&gt;That is why Gemini 3.5 Pro is being watched closely. If it only becomes better at chatting or answering faster, the impact is limited. If it truly improves code understanding, cross-file editing, tool calling, and long-running task execution, it may change developer workflows.&lt;/p&gt;
&lt;h2 id=&#34;gemini-spark-may-be-the-bigger-variable&#34;&gt;Gemini Spark May Be The Bigger Variable
&lt;/h2&gt;&lt;p&gt;More aggressive than the model itself is the rumored Gemini Spark.&lt;/p&gt;
&lt;p&gt;According to the leaks, Spark is not positioned as a normal chat assistant, but as an always-on AI Agent. It may connect to email, calendars, web pages, tasks, account state, and personal context to help users handle multi-step workflows.&lt;/p&gt;
&lt;p&gt;This kind of product has a large imagination space. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;automatically organizing an inbox;&lt;/li&gt;
&lt;li&gt;following up on tasks for the user;&lt;/li&gt;
&lt;li&gt;performing actions on web pages;&lt;/li&gt;
&lt;li&gt;handling cross-application workflows;&lt;/li&gt;
&lt;li&gt;arranging daily matters based on personal preferences.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But the risks are just as obvious. If an always-on Agent can access login state, browser data, files, location, and third-party services, it must answer several questions: when must the user confirm an action? Which operations must be blocked from automation? Will data be shared with third parties? How are remote browsers and credentials isolated?&lt;/p&gt;
&lt;p&gt;So the real question for Spark is not just whether it can get work done. It is whether Google can make permissions, auditing, confirmation flows, and user control clear enough.&lt;/p&gt;
&lt;h2 id=&#34;what-mcp-tool-integration-suggests&#34;&gt;What MCP Tool Integration Suggests
&lt;/h2&gt;&lt;p&gt;The leaks also mention that the new Gemini selector may include MCP-related models or testing entries.&lt;/p&gt;
&lt;p&gt;If this ships, it suggests Google is also pushing models from a question-answering system toward a tool operating system. The model will no longer only generate text. It will need to call external tools, access business systems, read and write files, run commands, and maintain task state across multiple steps.&lt;/p&gt;
&lt;p&gt;This direction is consistent with OpenAI and Anthropic. Whoever makes tool calling more reliable will have an easier time embedding AI into real workflows.&lt;/p&gt;
&lt;p&gt;But MCP integration itself is not the finish line. The hard part is stability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;can the model choose the right tool;&lt;/li&gt;
&lt;li&gt;are the parameters reliable;&lt;/li&gt;
&lt;li&gt;can it recover after failure;&lt;/li&gt;
&lt;li&gt;are permission boundaries clear;&lt;/li&gt;
&lt;li&gt;can users trace every step.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If these questions are not solved, more tools also mean a larger surface for mistakes.&lt;/p&gt;
&lt;h2 id=&#34;multimodality-is-still-googles-strong-card&#34;&gt;Multimodality Is Still Google&amp;rsquo;s Strong Card
&lt;/h2&gt;&lt;p&gt;The place where Google has the best chance to differentiate is still multimodality.&lt;/p&gt;
&lt;p&gt;Based on exposed SVG, interactive page, animation, and visual generation examples, Gemini may continue to strengthen its ability to generate interactive content from prompts. Compared with simply writing a piece of code, this is closer to product prototyping: the user describes an idea, and the model directly produces an operable, adjustable, previewable interface.&lt;/p&gt;
&lt;p&gt;This path fits Google well. It can build on Gemini&amp;rsquo;s multimodal strengths and also connect with Android, Chrome, Workspace, Search, Ads, and Cloud.&lt;/p&gt;
&lt;p&gt;If Google wants to avoid competing only on &amp;ldquo;whose coding model is stronger&amp;rdquo;, it may put more emphasis on a more complete multimodal Agent system.&lt;/p&gt;
&lt;h2 id=&#34;the-three-companies-are-splitting-into-different-playbooks&#34;&gt;The Three Companies Are Splitting Into Different Playbooks
&lt;/h2&gt;&lt;p&gt;The current model race is no longer just a leaderboard race.&lt;/p&gt;
&lt;p&gt;OpenAI&amp;rsquo;s advantage lies in product iteration and distribution speed. Codex, ChatGPT, enterprise tools, and APIs are becoming more tightly connected.&lt;/p&gt;
&lt;p&gt;Anthropic&amp;rsquo;s advantage lies in developer mindshare and code model quality. Claude Code has already become the default AI coding entry point for many people.&lt;/p&gt;
&lt;p&gt;Google&amp;rsquo;s advantage is ecosystem access. Gmail, Docs, Chrome, Android, Search, YouTube, Maps, and Cloud services form a huge personal and enterprise data network. If Agents can safely connect to these entry points, Google may move from a &amp;ldquo;model chaser&amp;rdquo; to a &amp;ldquo;workflow entry point controller&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;That is why Gemini Spark is worth watching. It does not necessarily need to rank first on every benchmark. If it enters daily workflows, it may still build its own moat.&lt;/p&gt;
&lt;h2 id=&#34;how-regular-users-should-read-this&#34;&gt;How Regular Users Should Read This
&lt;/h2&gt;&lt;p&gt;For regular users, there is no need to be pulled around by every leak in the short term.&lt;/p&gt;
&lt;p&gt;The more practical things to watch are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Whether Gemini 3.5 Pro&amp;rsquo;s coding ability truly improves, especially in complex repositories, long context, and tool calling.&lt;/li&gt;
&lt;li&gt;Whether Gemini Spark is safe by default, with clear confirmation and traceable records before sensitive operations.&lt;/li&gt;
&lt;li&gt;Whether Google gives clear pricing, quotas, and enterprise permission management, rather than only showing demos.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pretty screenshots alone do not mean much. Whether it can reliably enter real workflows is the dividing line for this round of AI Agent products.&lt;/p&gt;
&lt;h2 id=&#34;what-it-means-for-developers&#34;&gt;What It Means For Developers
&lt;/h2&gt;&lt;p&gt;Developers should care less about &amp;ldquo;which model won&amp;rdquo; and more about whether their workflow is portable.&lt;/p&gt;
&lt;p&gt;Claude Code, Codex, Gemini, Antigravity, Cursor, Windsurf, and many other tools are all competing for the entry point. If every process is locked into one platform, future changes in cost, quota, model policy, or permission rules will make migration painful.&lt;/p&gt;
&lt;p&gt;A safer approach is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keep standard Git workflows for important projects;&lt;/li&gt;
&lt;li&gt;always inspect diffs after automated edits;&lt;/li&gt;
&lt;li&gt;use tests and CI as backstops for key tasks;&lt;/li&gt;
&lt;li&gt;do not hand production credentials to opaque Agents;&lt;/li&gt;
&lt;li&gt;when open protocols can connect tools, prefer replaceable options.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Models will keep getting stronger, but engineering discipline will not become obsolete.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;The Gemini 3.5 Pro leaks suggest that Google is accelerating its effort to catch up in AI coding and Agent entry points. Model improvements are only one part of the story; always-on Agents such as Gemini Spark may be the larger strategic move.&lt;/p&gt;
&lt;p&gt;But the more a system can &amp;ldquo;do things automatically&amp;rdquo; for users, the more it needs strict permission boundaries and verifiable workflows. For Google, the real challenge is not only catching up with GPT-5.5 or Claude. It is combining strong models, safety mechanisms, and ecosystem entry points into a trustworthy daily workflow.&lt;/p&gt;
&lt;p&gt;If Google pulls that off, Gemini may not need to top every leaderboard to regain some initiative in AI entry points.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>How Can Codex Use Chinese LLMs? Managing OpenAI-Compatible APIs with CCX</title>
        <link>https://knightli.com/en/2026/05/13/ccx-ai-api-proxy-gateway/</link>
        <pubDate>Wed, 13 May 2026 23:20:40 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/13/ccx-ai-api-proxy-gateway/</guid>
        <description>&lt;p&gt;CCX is an AI API proxy and protocol-conversion gateway. It puts Claude Messages, OpenAI Chat Completions, OpenAI Images, Codex Responses, and Gemini API behind one service entry point, while also providing a web management UI for configuring channels, keys, model mappings, priorities, failover, and traffic monitoring.&lt;/p&gt;
&lt;p&gt;If you use Claude, OpenAI, Gemini, and Codex at the same time, or maintain multiple upstream services compatible with OpenAI API, CCX is valuable because it gives you one entry point and one management layer. Clients connect to a single service address; CCX decides which upstream channel should handle each request.&lt;/p&gt;
&lt;p&gt;Project: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;what-problem-does-ccx-solve&#34;&gt;What problem does CCX solve?
&lt;/h2&gt;&lt;p&gt;When multiple AI APIs are used together, several problems appear quickly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each provider has different paths, authentication, and request formats.&lt;/li&gt;
&lt;li&gt;One class of models may have multiple upstreams, requiring manual switching of base URL and API key.&lt;/li&gt;
&lt;li&gt;When a key or channel fails, the client usually does not automatically switch to a backup channel.&lt;/li&gt;
&lt;li&gt;In team use, it is hard to centrally manage model allowlists, proxies, custom headers, and request logs.&lt;/li&gt;
&lt;li&gt;When Claude, Gemini, OpenAI Chat, image APIs, and Codex Responses all need to coexist, configuration becomes scattered.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CCX&amp;rsquo;s approach is to consolidate these differences into a proxy layer. Frontend tools, scripts, or business services call CCX; CCX then routes the request to a suitable upstream based on API type, model, channel status, priority, and health.&lt;/p&gt;
&lt;h2 id=&#34;supported-endpoints&#34;&gt;Supported endpoints
&lt;/h2&gt;&lt;p&gt;CCX exposes one backend entry point. The default port is &lt;code&gt;3000&lt;/code&gt;. Main paths include:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /                         -&amp;gt; Web management UI
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /health                   -&amp;gt; Health check
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/api/*                         -&amp;gt; Management API
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/messages              -&amp;gt; Claude Messages proxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/chat/completions      -&amp;gt; OpenAI Chat proxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/responses             -&amp;gt; Codex Responses proxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/generations    -&amp;gt; OpenAI Images generation
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/edits          -&amp;gt; OpenAI Images editing
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/variations     -&amp;gt; OpenAI Images variations
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /v1/models                -&amp;gt; Model list
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1beta/models/*          -&amp;gt; Gemini proxy
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;In other words, CCX does not proxy only one protocol. It manages common AI APIs as separate channel types: Messages, Chat, Responses, Gemini, and Images. Different protocols do not share the same health state or log space, which matters when troubleshooting.&lt;/p&gt;
&lt;h2 id=&#34;architecture-overview&#34;&gt;Architecture overview
&lt;/h2&gt;&lt;p&gt;CCX uses a Go backend and Vue 3 frontend. The frontend build is embedded into the backend binary, so it can be deployed on a single port: the same service provides the Web UI, management API, and proxy API.&lt;/p&gt;
&lt;p&gt;A request roughly follows this path:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Client -&amp;gt; Auth Middleware -&amp;gt; Route Handler -&amp;gt; Channel Scheduler -&amp;gt; Provider / Converter -&amp;gt; Upstream API -&amp;gt; Metrics / Channel Logs -&amp;gt; Client Response
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The main modules can be understood as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;handlers&lt;/code&gt;: receive requests for different protocols and management operations.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;providers&lt;/code&gt;: wrap upstream API request and response handling.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;converters&lt;/code&gt;: handle protocol conversion for scenarios such as Responses.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scheduler&lt;/code&gt;: choose channels based on priority, promotion period, health state, circuit breaker state, and trace affinity.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metrics&lt;/code&gt;: record request counts, success rate, latency, logs, and circuit breaker state.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config&lt;/code&gt;: maintain runtime configuration, with hot reload and backup support.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The design is not about forcing every API into one format. It proxies each protocol type separately, while unifying management, scheduling, logging, and authentication.&lt;/p&gt;
&lt;h2 id=&#34;ccx-vs-codexbridge&#34;&gt;CCX vs CodexBridge
&lt;/h2&gt;&lt;p&gt;CCX and CodexBridge are both related to Codex and OpenAI-compatible APIs, but they solve different problems.&lt;/p&gt;
&lt;p&gt;CodexBridge is more like a dedicated Codex bridge. Its main goal is to wrap Codex CLI/SDK as an OpenAI-compatible &lt;code&gt;/v1/chat/completions&lt;/code&gt; service, so OpenWebUI, Cherry Studio, scripts, or other OpenAI-compatible clients can call local Codex. In short, CodexBridge focuses on exposing Codex.&lt;/p&gt;
&lt;p&gt;CCX is more like a unified AI API gateway. It does not only handle Codex Responses; it also supports Claude Messages, OpenAI Chat, OpenAI Images, and Gemini API, with a web management UI, channel priority, failover, log monitoring, and multi-key management. In short, CCX focuses on managing multiple models and providers together.&lt;/p&gt;
&lt;p&gt;Quick comparison:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Item&lt;/th&gt;
          &lt;th&gt;CodexBridge&lt;/th&gt;
          &lt;th&gt;CCX&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Core positioning&lt;/td&gt;
          &lt;td&gt;Local Codex bridge&lt;/td&gt;
          &lt;td&gt;Multi-protocol AI API gateway&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Main goal&lt;/td&gt;
          &lt;td&gt;Turn Codex into an OpenAI-compatible endpoint&lt;/td&gt;
          &lt;td&gt;Manage Claude, OpenAI, Gemini, Codex, and other channels together&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Management UI&lt;/td&gt;
          &lt;td&gt;Focuses on the API service itself&lt;/td&gt;
          &lt;td&gt;Provides a web management UI&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Multi-channel scheduling&lt;/td&gt;
          &lt;td&gt;Not the focus&lt;/td&gt;
          &lt;td&gt;Supports channel priority, failover, and log monitoring&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Best fit&lt;/td&gt;
          &lt;td&gt;Local or single-service Codex calls&lt;/td&gt;
          &lt;td&gt;Teams, multiple keys, multiple providers, multiple protocols&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you only want to connect Codex to OpenWebUI or Cherry Studio, CodexBridge is more direct. If you want to manage Codex, Claude, Gemini, DeepSeek, Qwen, Kimi, and other upstreams together, CCX is a better fit.&lt;/p&gt;
&lt;h2 id=&#34;quick-deployment&#34;&gt;Quick deployment
&lt;/h2&gt;&lt;p&gt;The simplest way is to download the binary. After downloading it, create &lt;code&gt;.env&lt;/code&gt; in the same directory:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_WEB_UI&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;After startup, open:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://localhost:3000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If &lt;code&gt;localhost&lt;/code&gt; does not work from WSL, Docker, PowerShell, or another Windows environment, use the Windows host&amp;rsquo;s LAN IPv4 address instead, for example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://192.168.1.23:3000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;By default, CCX listens on &lt;code&gt;:PORT&lt;/code&gt; for all network interfaces, so access control matters if it is exposed to a LAN.&lt;/p&gt;
&lt;h2 id=&#34;docker-deployment&#34;&gt;Docker deployment
&lt;/h2&gt;&lt;p&gt;Docker is suitable for long-running service deployment:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -d &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --name ccx &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -p 3000:3000 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -e &lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -e &lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -v &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/.config:/app/.config &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  crpi-i19l8zl0ugidq97v.cn-hangzhou.personal.cr.aliyuncs.com/bene/ccx:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If the repository already has &lt;code&gt;docker-compose.yml&lt;/code&gt;, you can also run:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;For automatic updates, add the Watchtower configuration:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose -f docker-compose.yml -f docker-compose.watchtower.yml up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;After deployment, &lt;code&gt;.config&lt;/code&gt; stores runtime configuration and persistent data. Mount it to the host to avoid losing configuration when the container is recreated.&lt;/p&gt;
&lt;h2 id=&#34;running-from-source&#34;&gt;Running from source
&lt;/h2&gt;&lt;p&gt;For development or custom builds:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/BenedictKing/ccx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ccx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp backend-go/.env.example backend-go/.env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Common commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make dev
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make run
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make build
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make frontend-dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Frontend-only development:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; frontend
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Backend-only development:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; backend-go
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;key-environment-variables&#34;&gt;Key environment variables
&lt;/h2&gt;&lt;p&gt;Minimal usable configuration usually includes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;production
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_WEB_UI&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ADMIN_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-admin-secret-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LOG_LEVEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;REQUEST_TIMEOUT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;300000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PROXY_ACCESS_KEY&lt;/code&gt; is used for the proxy API and must be changed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADMIN_ACCESS_KEY&lt;/code&gt; is used for the Web UI and &lt;code&gt;/api/*&lt;/code&gt;; it should be separate from the proxy key.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENABLE_WEB_UI&lt;/code&gt; controls whether the management UI is enabled.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;REQUEST_TIMEOUT&lt;/code&gt; controls request timeout; increase it for long-context or image tasks.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LOG_LEVEL&lt;/code&gt; controls log verbosity; production usually uses &lt;code&gt;info&lt;/code&gt; or &lt;code&gt;warn&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To limit request body size, check:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;MAX_REQUEST_BODY_SIZE_MB&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Image editing, base64 images, and multimodal requests can all increase request body size.&lt;/p&gt;
&lt;h2 id=&#34;channel-orchestration-and-failover&#34;&gt;Channel orchestration and failover
&lt;/h2&gt;&lt;p&gt;The CCX management UI can configure multiple channels, with options such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Upstream service type.&lt;/li&gt;
&lt;li&gt;API key or multi-key rotation.&lt;/li&gt;
&lt;li&gt;Proxy address.&lt;/li&gt;
&lt;li&gt;Custom request headers.&lt;/li&gt;
&lt;li&gt;Model allowlist.&lt;/li&gt;
&lt;li&gt;Route prefix.&lt;/li&gt;
&lt;li&gt;Priority.&lt;/li&gt;
&lt;li&gt;Health checks and circuit-breaker recovery.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Scheduling considers channel state, priority, promotion period, trace affinity, circuit-breaker state, and available keys. In simple terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Under normal conditions, higher-priority channels are used first.&lt;/li&gt;
&lt;li&gt;If one channel fails, CCX can fail over to a backup channel.&lt;/li&gt;
&lt;li&gt;Circuit breaking avoids repeatedly hitting an obviously unavailable upstream.&lt;/li&gt;
&lt;li&gt;Trace affinity tries to keep related sessions on suitable channels.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These features are useful when you have multiple keys, providers, or regional upstreams. For personal lightweight use, you can also configure only one channel and use CCX as a proxy layer with a Web UI.&lt;/p&gt;
&lt;h2 id=&#34;logs-and-monitoring&#34;&gt;Logs and monitoring
&lt;/h2&gt;&lt;p&gt;CCX provides channel metrics and request logs, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Request volume.&lt;/li&gt;
&lt;li&gt;Success rate.&lt;/li&gt;
&lt;li&gt;Failure rate.&lt;/li&gt;
&lt;li&gt;Average latency.&lt;/li&gt;
&lt;li&gt;Historical data by model.&lt;/li&gt;
&lt;li&gt;Channel status and circuit-breaker state.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For production, use relatively conservative logging:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;production
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LOG_LEVEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_REQUEST_LOGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_RESPONSE_LOGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This keeps basic request information while avoiding full response content in logs. You can temporarily enable more detailed logs for troubleshooting, but restore the safer configuration afterward, especially in production.&lt;/p&gt;
&lt;h2 id=&#34;security-recommendations&#34;&gt;Security recommendations
&lt;/h2&gt;&lt;p&gt;CCX is a proxy gateway and stores upstream API keys, so deployment should not stop at &amp;ldquo;it runs.&amp;rdquo; At minimum:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do not use a default or short &lt;code&gt;PROXY_ACCESS_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set a separate &lt;code&gt;ADMIN_ACCESS_KEY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Do not expose the Web UI directly to the public internet.&lt;/li&gt;
&lt;li&gt;If public access is required, place it behind a reverse proxy, VPN, access control, or SSO.&lt;/li&gt;
&lt;li&gt;Do not commit &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.config&lt;/code&gt;, or log files to Git.&lt;/li&gt;
&lt;li&gt;Do not keep full request and response body logging enabled in production.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can generate random keys like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;openssl rand -base64 32&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ADMIN_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;openssl rand -base64 32&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;who-should-use-it&#34;&gt;Who should use it?
&lt;/h2&gt;&lt;p&gt;CCX is better suited to these scenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maintaining Claude, OpenAI, Gemini, Codex, or image APIs at the same time.&lt;/li&gt;
&lt;li&gt;Having multiple API keys that need rotation, routing, and failover.&lt;/li&gt;
&lt;li&gt;Managing upstream channels through a Web UI instead of editing config files manually.&lt;/li&gt;
&lt;li&gt;Observing success rate, latency, and logs for each channel.&lt;/li&gt;
&lt;li&gt;Providing one unified AI API entry point for a team.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you only call one model occasionally on your own machine, the official SDK or a single OpenAI-compatible proxy is simpler. CCX&amp;rsquo;s advantage is multi-channel, multi-protocol, unified operation.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;CCX is an AI API gateway, not a client for one specific model. It puts Claude Messages, OpenAI Chat, OpenAI Images, Codex Responses, and Gemini into one proxy layer, with channel orchestration, failover, logs, monitoring, and a Web management UI.&lt;/p&gt;
&lt;p&gt;For individuals, it reduces the trouble of switching API addresses and keys. For teams or long-running services, it is closer to a lightweight AI gateway. Before production use, the important work is not only configuring models, but also securing keys, the management entry point, logging levels, channel priority, and failover strategy.&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;GitHub project: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Architecture notes: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx/blob/main/ARCHITECTURE.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx/blob/main/ARCHITECTURE.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Environment variables: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx/blob/main/ENVIRONMENT.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx/blob/main/ENVIRONMENT.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>How ChatGPT, Claude Code, and Gemini memory mechanisms differ</title>
        <link>https://knightli.com/en/2026/05/07/chatgpt-claude-code-gemini-memory-comparison/</link>
        <pubDate>Thu, 07 May 2026 14:47:17 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/07/chatgpt-claude-code-gemini-memory-comparison/</guid>
        <description>&lt;p&gt;&amp;ldquo;Memory&amp;rdquo; is becoming increasingly important in AI products. It marks the shift from one-off conversations to long-term collaboration: you do not need to reintroduce your background, repeat your preferences, or ask the model to understand the same project again and again.&lt;/p&gt;
&lt;p&gt;But memory does not mean the same thing in every product. &lt;code&gt;ChatGPT&lt;/code&gt;, &lt;code&gt;Claude Code&lt;/code&gt;, and &lt;code&gt;Gemini&lt;/code&gt; all try to help AI remember longer, but their goals, storage locations, transparency, and use cases are very different.&lt;/p&gt;
&lt;p&gt;As of May 7, 2026, they can be roughly understood as three types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT is more like personal assistant memory.&lt;/li&gt;
&lt;li&gt;Claude Code is more like engineering project memory.&lt;/li&gt;
&lt;li&gt;Gemini is more like Google ecosystem context.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;chatgpt-long-term-preferences-around-the-person&#34;&gt;ChatGPT: long-term preferences around the person
&lt;/h2&gt;&lt;p&gt;ChatGPT memory is mainly designed for personal collaboration. It cares about who you are, what you prefer, and what you work on over time.&lt;/p&gt;
&lt;p&gt;OpenAI currently separates ChatGPT memory into &lt;code&gt;saved memories&lt;/code&gt; and &lt;code&gt;chat history&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;saved memories&lt;/code&gt; are important pieces of information ChatGPT stores, such as your name, preferences, goals, common tech stack, and writing habits. You can explicitly ask it to remember something, and it may also save information from conversation when it thinks it will be useful later.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;chat history&lt;/code&gt; lets ChatGPT reference past conversations when answering. It does not mean every chat becomes a permanent memory. Instead, ChatGPT can search past conversations for relevant context when needed.&lt;/p&gt;
&lt;p&gt;So ChatGPT&amp;rsquo;s core logic is: understand the same user across sessions.&lt;/p&gt;
&lt;p&gt;Typical examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Keep code examples concise for me.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;I mainly use Python and TypeScript.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;I am writing a Hugo blog about AI tools.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;I prefer conclusions first, then details.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These memories are not bound to one project. They follow the account and the user&amp;rsquo;s working habits.&lt;/p&gt;
&lt;h2 id=&#34;memory-sources-making-personalization-more-visible&#34;&gt;Memory Sources: making personalization more visible
&lt;/h2&gt;&lt;p&gt;OpenAI emphasized &lt;code&gt;Memory sources&lt;/code&gt; in its May 2026 update.&lt;/p&gt;
&lt;p&gt;The purpose is not to add another type of memory, but to show users what sources ChatGPT referenced when personalizing a response. According to OpenAI help documents, Memory Sources may show:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Past chats.&lt;/li&gt;
&lt;li&gt;Saved memories.&lt;/li&gt;
&lt;li&gt;Custom instructions.&lt;/li&gt;
&lt;li&gt;Files in the file library.&lt;/li&gt;
&lt;li&gt;Emails from connected Gmail.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Files and Gmail visibility depend on plan, region, and connection status. OpenAI also states that Memory sources may not show every factor that influenced a response, but they help users understand and manage personalization.&lt;/p&gt;
&lt;p&gt;This matters. The more AI can &amp;ldquo;remember you,&amp;rdquo; the more users need to know what it used to answer. Otherwise personalization becomes a black box: it seems to know you, but you do not know why.&lt;/p&gt;
&lt;p&gt;ChatGPT&amp;rsquo;s advantage is cross-session, cross-topic understanding of personal preferences. The risk is that memories can become outdated, or users may forget an old memory is still affecting answers. It is worth periodically cleaning saved memories and old chats.&lt;/p&gt;
&lt;h2 id=&#34;claude-code-around-codebases-and-engineering-rules&#34;&gt;Claude Code: around codebases and engineering rules
&lt;/h2&gt;&lt;p&gt;Claude Code memory is more engineering-oriented. It cares less about a user&amp;rsquo;s everyday preferences and more about how this codebase should be changed.&lt;/p&gt;
&lt;p&gt;Claude Code has two memory mechanisms that are easy to confuse:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Explicit project memory: &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Automatic project memory: Auto Memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; is the most basic and stable project memory file. It can live at the project root or inside subdirectories. Claude Code reads these files as project instructions and operating rules.&lt;/p&gt;
&lt;p&gt;Good content for &lt;code&gt;CLAUDE.md&lt;/code&gt; includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Common build, test, and lint commands.&lt;/li&gt;
&lt;li&gt;Code style and naming rules.&lt;/li&gt;
&lt;li&gt;Project architecture notes.&lt;/li&gt;
&lt;li&gt;Module boundaries and risky areas.&lt;/li&gt;
&lt;li&gt;Team conventions and commit workflow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If &lt;code&gt;CLAUDE.md&lt;/code&gt; is stored in the repository, it can be committed to Git and shared as a team agent guide. This is completely different from ChatGPT&amp;rsquo;s cloud-based personal memory.&lt;/p&gt;
&lt;h2 id=&#34;claude-code-auto-memory-accumulating-project-experience&#34;&gt;Claude Code Auto Memory: accumulating project experience
&lt;/h2&gt;&lt;p&gt;Claude Code also has &lt;code&gt;Auto Memory&lt;/code&gt;. Its goal is to let Claude automatically accumulate project knowledge across sessions without requiring users to write every note manually.&lt;/p&gt;
&lt;p&gt;According to Claude Code documentation, Auto Memory lets Claude save notes while working, such as build commands, debugging discoveries, architecture notes, code style preferences, and workflow habits. It does not save every session, but judges what may be useful later.&lt;/p&gt;
&lt;p&gt;One common misconception is that Auto Memory writes by default to &lt;code&gt;.claude/memory.md&lt;/code&gt; in the project root. Official documentation says each project has its own memory directory under the user&amp;rsquo;s home directory, with a path like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.claude/projects/&amp;lt;project&amp;gt;/memory/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;MEMORY.md&lt;/code&gt; loads the first 200 lines or 25KB at the start of each conversation, while detailed content may be split into other topic files. Auto Memory files are local Markdown files, and users can view, edit, or delete them through &lt;code&gt;/memory&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This makes Claude Code memory more like a local project knowledge base. It is closer to the codebase than ChatGPT&amp;rsquo;s personal memory, and more dynamic than a plain &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But Auto Memory is local to the machine. It does not naturally follow the repository to other machines or cloud environments. For team-shared stable rules, put them in the repository&amp;rsquo;s &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;gemini-around-google-ecosystem-context&#34;&gt;Gemini: around Google ecosystem context
&lt;/h2&gt;&lt;p&gt;Gemini&amp;rsquo;s memory logic is different again.&lt;/p&gt;
&lt;p&gt;Gemini also supports saved information and past-chat references. Google help documents say users can save information about life, work, or preferences, and Gemini can reference past chats before answering. When it uses this information, the response may show sources such as &lt;code&gt;Your saved info&lt;/code&gt; or &lt;code&gt;Previous chats&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But Gemini&amp;rsquo;s differentiation is not only &amp;ldquo;saving a few preferences.&amp;rdquo; It is Google ecosystem integration.&lt;/p&gt;
&lt;p&gt;With user authorization and feature availability, Gemini can access context from connected Google apps such as Gmail, Google Drive, Docs, and Sheets. Its advantage is not making users teach it every item manually, but turning existing Google account data into searchable work context.&lt;/p&gt;
&lt;p&gt;A typical difference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT remembers: &amp;ldquo;I have been repairing an LTO tape drive recently.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Gemini may find the purchase confirmation email in Gmail or read repair notes from Drive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This does not mean Gemini can unconditionally read all Google data. It depends on account type, region, permissions, connected apps, Keep Activity settings, and product availability. Enterprise and school accounts may also be controlled by Google Workspace administrators.&lt;/p&gt;
&lt;p&gt;More accurately, Gemini memory is a combination of saved info, past chats, and connected Google ecosystem data.&lt;/p&gt;
&lt;h2 id=&#34;core-differences&#34;&gt;Core differences
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Dimension&lt;/th&gt;
          &lt;th&gt;ChatGPT&lt;/th&gt;
          &lt;th&gt;Claude Code&lt;/th&gt;
          &lt;th&gt;Gemini&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Core object&lt;/td&gt;
          &lt;td&gt;Person and preferences&lt;/td&gt;
          &lt;td&gt;Project and codebase&lt;/td&gt;
          &lt;td&gt;Google account and ecosystem data&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Typical memory&lt;/td&gt;
          &lt;td&gt;Preferences, background, long-term goals&lt;/td&gt;
          &lt;td&gt;Architecture, commands, conventions, debugging experience&lt;/td&gt;
          &lt;td&gt;Saved info, past chats, Gmail/Drive/Docs context&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Storage form&lt;/td&gt;
          &lt;td&gt;Memory and chat context in OpenAI account&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;MEMORY.md&lt;/code&gt;, local Markdown files&lt;/td&gt;
          &lt;td&gt;Google account activity, saved info, connected app data&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Transparency&lt;/td&gt;
          &lt;td&gt;Memory sources show part of the source&lt;/td&gt;
          &lt;td&gt;Markdown files can be opened and edited&lt;/td&gt;
          &lt;td&gt;Managed through source prompts, Gemini Apps Activity, and Google settings&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Cross-project ability&lt;/td&gt;
          &lt;td&gt;Strong, follows user account&lt;/td&gt;
          &lt;td&gt;Weak, mainly follows project or local project memory&lt;/td&gt;
          &lt;td&gt;Strong, depends on Google data and permissions&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Team sharing&lt;/td&gt;
          &lt;td&gt;Not suitable for direct sharing&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; can be shared through Git&lt;/td&gt;
          &lt;td&gt;Mainly depends on Workspace and permissions&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Best for&lt;/td&gt;
          &lt;td&gt;Personal preferences and long-term assistant behavior&lt;/td&gt;
          &lt;td&gt;Long-term coding projects and agent collaboration&lt;/td&gt;
          &lt;td&gt;Google Workspace retrieval and cross-tool work&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;how-to-choose&#34;&gt;How to choose
&lt;/h2&gt;&lt;p&gt;If you want AI to remember who you are, what style you prefer, and how you usually work, ChatGPT memory is more suitable.&lt;/p&gt;
&lt;p&gt;It is good for saving personal preferences such as writing style, tech stack, answer format, professional background, and long-term project direction. Its focus is reducing self-introduction cost so each new conversation can start faster.&lt;/p&gt;
&lt;p&gt;If you want AI to remember how a codebase should be changed, which commands work, and which traps to avoid, Claude Code is more suitable.&lt;/p&gt;
&lt;p&gt;Put stable rules into &lt;code&gt;CLAUDE.md&lt;/code&gt; for team sharing. Let Auto Memory assist with dynamic experience. Important decisions should still be organized into documentation or &lt;code&gt;CLAUDE.md&lt;/code&gt;, not left only in local automatic memory.&lt;/p&gt;
&lt;p&gt;If most of your materials live in Gmail, Drive, Docs, and Sheets, Gemini&amp;rsquo;s ecosystem context has an advantage.&lt;/p&gt;
&lt;p&gt;It is useful for finding old emails, organizing Drive documents, and connecting calendar and office materials. The key to using Gemini is not repeatedly reminding it in chat, but making sure the relevant app connections, permissions, and activity settings are correct.&lt;/p&gt;
&lt;h2 id=&#34;a-practical-division-of-labor&#34;&gt;A practical division of labor
&lt;/h2&gt;&lt;p&gt;You can divide them like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT remembers general personal preferences.&lt;/li&gt;
&lt;li&gt;Claude Code remembers engineering knowledge for a repository.&lt;/li&gt;
&lt;li&gt;Gemini retrieves materials from your Google ecosystem.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, ChatGPT is like a personal secretary, Claude Code is like a senior engineer inside the project, and Gemini is like an indexer for your Google account.&lt;/p&gt;
&lt;p&gt;There is no absolute winner. They have different goals.&lt;/p&gt;
&lt;p&gt;The biggest mistake is mixing them together. Personal preferences do not always belong in project memory; project architecture does not always belong in cloud personal memory; and Google ecosystem retrieval does not mean the model has truly understood you long-term.&lt;/p&gt;
&lt;h2 id=&#34;short-take&#34;&gt;Short Take
&lt;/h2&gt;&lt;p&gt;The next stage of AI memory is not simply &amp;ldquo;remember more.&amp;rdquo; Memory needs layers, visibility, and control.&lt;/p&gt;
&lt;p&gt;ChatGPT focuses on cross-session personalization. Claude Code focuses on code project continuity. Gemini focuses on Google ecosystem context. Good long-term AI collaboration does not put all information into one black box; it keeps different kinds of memory in the right places.&lt;/p&gt;
&lt;p&gt;Put personal preferences in personal memory, engineering rules in the codebase, and historical materials in the original document and email systems. AI&amp;rsquo;s job is to call the right context when needed, not mix everything into one pile.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;OpenAI Memory FAQ: &lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/8590148-memory-faq&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/8590148-memory-faq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ChatGPT Release Notes: &lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/6825453-chatgpt-release-notes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/6825453-chatgpt-release-notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Claude Code Memory: &lt;a class=&#34;link&#34; href=&#34;https://code.claude.com/docs/en/memory&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://code.claude.com/docs/en/memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gemini Saved info: &lt;a class=&#34;link&#34; href=&#34;https://support.google.com/gemini/answer/15637730&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://support.google.com/gemini/answer/15637730&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gemini Apps Privacy Hub: &lt;a class=&#34;link&#34; href=&#34;https://support.google.com/gemini/answer/13594961&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://support.google.com/gemini/answer/13594961&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini Embedding 2: Putting Text, Images, Video, and Audio in One Vector Space</title>
        <link>https://knightli.com/en/2026/05/04/gemini-embedding-2-multimodal-rag/</link>
        <pubDate>Mon, 04 May 2026 06:01:10 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/04/gemini-embedding-2-multimodal-rag/</guid>
        <description>&lt;p&gt;Google Developers Blog introduced how to build with Gemini Embedding 2. The model is now generally available through the Gemini API and Gemini Enterprise Agent Platform. The important point is not simply that it is a new embedding model, but that it maps text, images, video, audio, and documents into the same semantic space.&lt;/p&gt;
&lt;p&gt;This broadens what retrieval systems can handle. Many RAG pipelines previously had to convert images, video, or audio into text or metadata before indexing them separately. Gemini Embedding 2 can process multimodal inputs directly, making it easier for agents, search systems, and classifiers to work with real business materials.&lt;/p&gt;
&lt;p&gt;Original article: &lt;a class=&#34;link&#34; href=&#34;https://developers.googleblog.com/building-with-gemini-embedding-2/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Building with Gemini Embedding 2: Agentic multimodal RAG and beyond&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;model-capabilities&#34;&gt;Model Capabilities
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 supports more than 100 languages. A single request can process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Up to 8,192 text tokens&lt;/li&gt;
&lt;li&gt;Up to 6 images&lt;/li&gt;
&lt;li&gt;Up to 120 seconds of video&lt;/li&gt;
&lt;li&gt;Up to 180 seconds of audio&lt;/li&gt;
&lt;li&gt;Up to 6 pages of PDF&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Its key idea is a unified semantic space. Developers can place content from different modalities into one vector representation system, then use the same retrieval, clustering, or reranking logic to process it.&lt;/p&gt;
&lt;p&gt;For example, a text description and an image can be included in the same embedding request:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google.genai&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dog.png&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;image_bytes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;embed_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;gemini-embedding-2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;An image of a dog&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;mime_type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;image/png&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;embeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If you want a separate embedding for each input rather than one aggregated vector, you can use the Batch API. The original article also notes that Agent Platform support for this kind of batch workflow is still in progress.&lt;/p&gt;
&lt;h2 id=&#34;what-it-means-for-rag&#34;&gt;What It Means for RAG
&lt;/h2&gt;&lt;p&gt;Multimodal embeddings are useful for agentic RAG. An AI agent may need to inspect a code repository, PDFs, screenshots, charts, audio meeting notes, and product images at the same time. If all of these materials can enter the same semantic space, the retrieval pipeline no longer needs a separate entry point for every format.&lt;/p&gt;
&lt;p&gt;Google recommends using task prefixes according to the goal of the task, so the embeddings better match the retrieval objective. For example, question answering, fact checking, code retrieval, and search results can use different prefixes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate embedding for your task&amp;#39;s query:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;prepare_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;task: question answering | query: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#34;task: fact checking | query: {content}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#34;task: code retrieval | query: {content}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#34;task: search result | query: {content}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate embedding for document of an asymmetric retrieval task:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;prepare_document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;title: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; | text: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This kind of prefix is suitable for asymmetric retrieval: user queries are often short, while documents are often long. Formatting &lt;code&gt;query&lt;/code&gt; and &lt;code&gt;document&lt;/code&gt; differently for the task can improve matching between short queries and long documents.&lt;/p&gt;
&lt;p&gt;The original article gives two real-world examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Harvey saw a 3% increase in Recall@20 precision on legal retrieval benchmarks compared with its previous embeddings.&lt;/li&gt;
&lt;li&gt;Supermemory saw a 40% increase in Recall@1 search accuracy and uses it across memory, indexing, search, and Q&amp;amp;A pipelines.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These numbers do not mean every scenario will improve by the same amount, but they show that multimodal embeddings are already producing results in real retrieval products, not only demos.&lt;/p&gt;
&lt;h2 id=&#34;visual-search&#34;&gt;Visual Search
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 is also suitable for image-to-image search, image-text hybrid search, and product identification. The original article mentions Nuuly, URBN&amp;rsquo;s clothing rental company, using it to match photos of untagged garments in warehouses against its catalog. Match@20 improved from 60% to nearly 87%, and the overall successful identification rate rose from 74% to over 90%.&lt;/p&gt;
&lt;p&gt;The point in this type of scenario is not content generation, but understanding which inventory item, document, or product record is closest to a given image. If your business has many images, video clips, or scanned documents, multimodal embeddings can be more natural than text-only indexing.&lt;/p&gt;
&lt;h2 id=&#34;search-reranking&#34;&gt;Search Reranking
&lt;/h2&gt;&lt;p&gt;Embeddings can also be used for reranking. A common approach is to first retrieve a set of candidate results, then calculate the similarity between each candidate and the user&amp;rsquo;s query, pushing more relevant content to the top:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 1. Define a function to calculate the dot product (cosine similarity)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;dot_product&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;@&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 2. Retrieve your embeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# (Assuming &amp;#39;summaries&amp;#39; is your list of search results)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;search_res&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_embeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;summaries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;embedded_query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_embeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 3. Calculate similarity scores&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sim_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dot_product&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_res&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;embedded_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 4. Select the most relevant result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;best_match_index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argmax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sim_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The original article also mentions another idea: first ask the model to generate a baseline hypothetical answer from its internal knowledge, embed that answer, and compare it with candidate content to find the most semantically relevant result. This is especially useful for Q&amp;amp;A-style RAG.&lt;/p&gt;
&lt;h2 id=&#34;clustering-classification-and-anomaly-detection&#34;&gt;Clustering, Classification, and Anomaly Detection
&lt;/h2&gt;&lt;p&gt;Beyond retrieval, embeddings are also useful for clustering, classification, and anomaly detection. Unlike the asymmetric question-answering retrieval above, these are symmetric tasks, where the same task prefix can be used for both query and document:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate embedding for query &amp;amp; document of your task.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;prepare_query_and_document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#39;task: clustering | query: {content}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#39;task: sentence similarity | query: {content}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#39;task: classification | query: {content}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;These tasks can be used for sentiment classification, content moderation, similar asset grouping, and anomaly discovery. They can also help agents organize large amounts of context before moving into later reasoning steps.&lt;/p&gt;
&lt;h2 id=&#34;storage-and-cost&#34;&gt;Storage and Cost
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 outputs 3,072-dimensional vectors by default. It uses Matryoshka Representation Learning, so vectors can be truncated to smaller dimensions with &lt;code&gt;output_dimensionality&lt;/code&gt;. Google recommends 1,536 or 768 dimensions when efficiency is the priority:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;embed_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-embedding-2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;What is the meaning of life?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dimensionality&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;768&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Vectors can be stored in Agent Platform Vector Search, Pinecone, Weaviate, Qdrant, ChromaDB, and similar systems. For cost, the original article notes that the Batch API provides higher throughput and reaches 50% of the default embedding price.&lt;/p&gt;
&lt;h2 id=&#34;how-developers-can-use-it&#34;&gt;How Developers Can Use It
&lt;/h2&gt;&lt;p&gt;If you already have text-based RAG, you can start with two incremental upgrades:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Put PDFs, screenshots, image descriptions, and text documents into the same index, then test whether retrieval recall becomes more stable.&lt;/li&gt;
&lt;li&gt;Add task prefixes for different tasks, such as question answering, fact checking, code retrieval, and product search. Do not process all content with the same embedding format.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are building a new product, consider these directions first:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enterprise knowledge bases: retrieve documents, charts, presentation screenshots, and meeting materials together.&lt;/li&gt;
&lt;li&gt;Visual search: use images, text, or mixed inputs to find products, assets, design drafts, and archives.&lt;/li&gt;
&lt;li&gt;Agent toolchains: let coding agents, research agents, or customer support agents retrieve business materials in multiple formats.&lt;/li&gt;
&lt;li&gt;Content governance: classify, cluster, and detect anomalies across text, images, and video clips.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The value of Gemini Embedding 2 is that it turns multimodal materials into one searchable asset system. For developers, this reduces the need for an intermediate &amp;ldquo;convert to text, then retrieve&amp;rdquo; layer and makes RAG systems closer to the shape of real-world data.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Gemini Comes to Cars with Google Built-in: In-Car Voice Assistants Start to Feel More Like Real AI Assistants</title>
        <link>https://knightli.com/en/2026/05/01/gemini-cars-with-google-built-in/</link>
        <pubDate>Fri, 01 May 2026 06:09:57 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/05/01/gemini-cars-with-google-built-in/</guid>
        <description>&lt;p&gt;Google announced on April 30, 2026 that &lt;code&gt;Gemini&lt;/code&gt; is starting to roll out to cars with &lt;code&gt;Google built-in&lt;/code&gt;, as an upgraded version of Google Assistant.&lt;/p&gt;
&lt;p&gt;The point is not simply that cars are getting another AI assistant. It is that in-car voice interaction is moving from fixed commands toward more natural, continuous conversation. Users no longer need to remember rigid command formats. They can speak more naturally and ask Gemini to help with navigation, messages, vehicle information, and even some in-car settings.&lt;/p&gt;
&lt;h2 id=&#34;starting-with-english-users-in-the-united-states&#34;&gt;Starting with English users in the United States
&lt;/h2&gt;&lt;p&gt;According to Google, this update will cover both new and existing vehicles, as long as the vehicle supports &lt;code&gt;Google built-in&lt;/code&gt; and the user is signed in to their Google account in the car.&lt;/p&gt;
&lt;p&gt;The rollout will begin with English-language users in the United States, then expand to more languages and countries. Eligible users will see an option in the car to upgrade to Gemini. After upgrading, they can call up Gemini in several ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Say &lt;code&gt;Hey Google&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Tap the microphone on the home screen&lt;/li&gt;
&lt;li&gt;Use the voice button on the steering wheel&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This shows that Google is not turning Gemini into a new entry point that users have to learn from scratch. It keeps the existing in-car voice entry point, while replacing the underlying assistant with a stronger Gemini experience.&lt;/p&gt;
&lt;h2 id=&#34;in-car-voice-no-longer-depends-only-on-fixed-commands&#34;&gt;In-car voice no longer depends only on fixed commands
&lt;/h2&gt;&lt;p&gt;A common problem with traditional in-car voice assistants is that they can do quite a lot, but users have to speak in a very &amp;ldquo;standard&amp;rdquo; way. As soon as the request becomes a little complex, the assistant may fail to understand it or only perform a basic action.&lt;/p&gt;
&lt;p&gt;With Gemini in the car, Google is emphasizing natural conversation. For example, a user can simply say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I need to grab lunch, find some highly rated sit-down restaurants along the way. I&amp;rsquo;m not in a rush, oh, and I’d like to eat outside.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Gemini can use Google Maps information to find suitable restaurants along the route. The user can then follow up by asking about parking or vegetarian options, without starting a whole new search.&lt;/p&gt;
&lt;p&gt;This interaction fits the driving context better. When driving, it is hard to repeatedly filter, tap, and revise options as you would on a phone. If a voice assistant can understand more complete intent, it can noticeably reduce distraction.&lt;/p&gt;
&lt;h2 id=&#34;maps-messages-and-music-become-easier-to-handle&#34;&gt;Maps, messages, and music become easier to handle
&lt;/h2&gt;&lt;p&gt;The examples Google gives are mostly built around the most common needs while driving.&lt;/p&gt;
&lt;p&gt;The first category is route and place search.&lt;/p&gt;
&lt;p&gt;Gemini can use Google Maps information to find restaurants, attractions, or charging stations along the way, and it can also answer questions related to the current route. For example, when passing near a stadium, the user can ask whether there is an event nearby and whether it will affect traffic.&lt;/p&gt;
&lt;p&gt;The second category is message handling.&lt;/p&gt;
&lt;p&gt;Users can ask Gemini to summarize new text messages and then reply based on the context. For example, they can ask it to tell a friend &amp;ldquo;I&amp;rsquo;m on my way&amp;rdquo; and include the estimated arrival time. If they want to change the message, they can add more instructions without starting over.&lt;/p&gt;
&lt;p&gt;The third category is music and ambience.&lt;/p&gt;
&lt;p&gt;Users do not necessarily need to know the name of a radio station or a specific playlist. They can simply describe what they want to hear. For example, they can ask for a jazz radio station, or ask YouTube Music to play upbeat &amp;rsquo;70s folk-rock for a mountain drive while skipping slow ballads.&lt;/p&gt;
&lt;p&gt;These functions are not entirely new by themselves. Gemini&amp;rsquo;s value is in handling multiple conditions in a single natural-language request, instead of forcing users back into fixed commands.&lt;/p&gt;
&lt;h2 id=&#34;gemini-live-lets-people-keep-talking-while-driving&#34;&gt;Gemini Live lets people keep talking while driving
&lt;/h2&gt;&lt;p&gt;Google also mentioned that &lt;code&gt;Gemini Live&lt;/code&gt; will enter the in-car experience and is currently in beta. Users can tap the Gemini Live button or say &lt;code&gt;Hey Google, let&#39;s talk&lt;/code&gt; to start a more free-flowing conversation.&lt;/p&gt;
&lt;p&gt;This scenario is closer to learning and brainstorming while driving. For example, when driving to Lake Tahoe, users can ask Gemini to share local history and fun facts. If something sounds interesting, they can interrupt and ask follow-up questions. Gemini can also help plan hikes and activities after arrival.&lt;/p&gt;
&lt;p&gt;The difference from traditional in-car assistants is clear. A traditional assistant is more like a tool button; Gemini Live is more like a voice interface that supports continuous conversation.&lt;/p&gt;
&lt;h2 id=&#34;owners-manuals-and-real-time-vehicle-status-are-the-key-differences&#34;&gt;Owner&amp;rsquo;s manuals and real-time vehicle status are the key differences
&lt;/h2&gt;&lt;p&gt;More importantly, Gemini does not only answer general questions. Google says it has worked with automakers to integrate Gemini more deeply with vehicle systems.&lt;/p&gt;
&lt;p&gt;This brings several capabilities closer to the car itself.&lt;/p&gt;
&lt;p&gt;First, users can ask about vehicle features.&lt;/p&gt;
&lt;p&gt;For example: &amp;ldquo;How should I prepare my car for an automatic car wash?&amp;rdquo; or &amp;ldquo;My garage ceiling is low and the trunk is hitting it. How do I program the trunk so it doesn&amp;rsquo;t open all the way?&amp;rdquo; Gemini can answer based on manufacturer-provided owner&amp;rsquo;s manuals, tailored to the specific vehicle model. The availability and level of detail will vary by brand and model.&lt;/p&gt;
&lt;p&gt;Second, EV users can ask about real-time battery level and range.&lt;/p&gt;
&lt;p&gt;For example, they can ask for the current battery level, the estimated battery level on arrival, or ask Gemini to find nearby charging stations. Gemini can also combine this with Google Maps and help find nearby cafes while charging.&lt;/p&gt;
&lt;p&gt;Third, some in-car settings can be adjusted through natural language.&lt;/p&gt;
&lt;p&gt;Google&amp;rsquo;s example is a user saying that the car is foggy and freezing. Gemini can understand the intent, turn up the heat, and switch on the defroster.&lt;/p&gt;
&lt;p&gt;These capabilities are more practical than simply moving a chatbot into the dashboard. A car is an environment with clear state, hardware capabilities, and safety boundaries. If an AI assistant can understand vehicle context, its value is much higher than ordinary Q&amp;amp;A.&lt;/p&gt;
&lt;h2 id=&#34;the-boundaries-of-in-car-ai-matter-even-more&#34;&gt;The boundaries of in-car AI matter even more
&lt;/h2&gt;&lt;p&gt;The requirements for AI in a car are different from those on a phone or web page.&lt;/p&gt;
&lt;p&gt;When driving, users cannot keep looking at the screen or spend much attention correcting AI. The assistant needs to be concise, reliable, and avoid creating new burdens in critical situations.&lt;/p&gt;
&lt;p&gt;So Gemini entering cars does not mean every complex task belongs in the car. A more reasonable direction is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reduce the operation cost of navigation and information lookup&lt;/li&gt;
&lt;li&gt;Replace multi-level menus with natural language&lt;/li&gt;
&lt;li&gt;Help users quickly understand vehicle features&lt;/li&gt;
&lt;li&gt;Handle messages and media without increasing distraction&lt;/li&gt;
&lt;li&gt;Give EV users smoother charging and route information&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the other hand, high-risk operations still need clear boundaries. Actions that affect driving safety, messages that require confirmation, and vehicle-control operations should all have sufficiently explicit confirmation flows.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Gemini coming to cars with &lt;code&gt;Google built-in&lt;/code&gt; is another step in AI assistants expanding from phones and web pages into everyday environments.&lt;/p&gt;
&lt;p&gt;Its significance is not that people can finally &amp;ldquo;chat&amp;rdquo; in the car. It is that in-car voice assistants are beginning to understand more complex intent and combine maps, messages, music, owner&amp;rsquo;s manuals, and some vehicle-status information to complete tasks.&lt;/p&gt;
&lt;p&gt;If the rollout goes well, in-car voice interaction may gradually move from &amp;ldquo;remember the command&amp;rdquo; to &amp;ldquo;describe the need.&amp;rdquo; That matters for driving, because a genuinely good in-car AI should not require the driver to give it too much attention.&lt;/p&gt;
&lt;p&gt;Reference link:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/products-and-platforms/platforms/android/cars-with-google-built-in-gemini-tips-2026/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Your car with Google built-in is about to get smarter, thanks to Gemini - Google Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>How to Split Tasks Between ChatGPT, Claude, and Gemini: Choosing for Daily Use, Coding, and Special Capabilities</title>
        <link>https://knightli.com/en/2026/04/25/chatgpt-claude-gemini-task-selection/</link>
        <pubDate>Sat, 25 Apr 2026 10:51:19 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/04/25/chatgpt-claude-gemini-task-selection/</guid>
        <description>&lt;p&gt;Many people no longer rely on just one model. Instead, they switch back and forth between &lt;code&gt;ChatGPT&lt;/code&gt;, &lt;code&gt;Claude&lt;/code&gt;, and &lt;code&gt;Gemini&lt;/code&gt;. That makes the question much more practical: &lt;strong&gt;which kinds of tasks should go to which model?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This feels confusing not because all three are weak, but because they are now strong in different ways. If you still choose based on a vague standard like “which one is smarter,” you can easily end up picking the wrong tool.&lt;/p&gt;
&lt;p&gt;If we simplify the conclusion first, it roughly looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For daily conversations and general-purpose tasks, many people start with &lt;code&gt;ChatGPT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For command-line coding, long-context collaboration, and sustained task execution, &lt;code&gt;Claude&lt;/code&gt; often feels smoother&lt;/li&gt;
&lt;li&gt;When you need Google ecosystem integration, search, multimodal entry points, or certain product-level capabilities, &lt;code&gt;Gemini&lt;/code&gt; tends to stand out more&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s break that down into three parts.&lt;/p&gt;
&lt;h2 id=&#34;1-daily-conversations-why-many-people-still-open-chatgpt-first&#34;&gt;1. Daily conversations: why many people still open &lt;code&gt;ChatGPT&lt;/code&gt; first
&lt;/h2&gt;&lt;p&gt;For most everyday scenarios, &lt;code&gt;ChatGPT&lt;/code&gt; still feels like the “default entry point.”&lt;/p&gt;
&lt;p&gt;This is not about a single benchmark. It is about the overall experience:&lt;br&gt;
when you want to ask a quick question, organize your thoughts, draft some copy, create a first version, or summarize a piece of material, &lt;code&gt;ChatGPT&lt;/code&gt; usually feels fairly balanced.&lt;/p&gt;
&lt;p&gt;Its strengths often show up in a few places:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Its response style is relatively stable&lt;/li&gt;
&lt;li&gt;The learning curve is low for general users&lt;/li&gt;
&lt;li&gt;Most broad tasks do not require much extra prompt tuning&lt;/li&gt;
&lt;li&gt;The product feels polished and works well for frequent everyday use&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So if your task is something like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Help me organize a topic&lt;/li&gt;
&lt;li&gt;Turn an idea into structured content&lt;/li&gt;
&lt;li&gt;Summarize a long article&lt;/li&gt;
&lt;li&gt;Brainstorm several approaches&lt;/li&gt;
&lt;li&gt;Rewrite something more clearly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then &lt;code&gt;ChatGPT&lt;/code&gt; is often a very natural place to start.&lt;/p&gt;
&lt;p&gt;That does not mean it is always the strongest option for every professional task. It means that for broad, general-purpose use, it often feels more like the default workspace.&lt;/p&gt;
&lt;h2 id=&#34;2-command-line-coding-and-long-tasks-why-many-people-lean-toward-claude&#34;&gt;2. Command-line coding and long tasks: why many people lean toward &lt;code&gt;Claude&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;Once a task shifts from “let’s chat” to “let’s keep working until this is done,” many people start preferring &lt;code&gt;Claude&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is especially true in scenarios like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Command-line programming&lt;/li&gt;
&lt;li&gt;Understanding the context of a large project&lt;/li&gt;
&lt;li&gt;Coordinating edits across multiple files&lt;/li&gt;
&lt;li&gt;Debugging long task chains&lt;/li&gt;
&lt;li&gt;Reading code while steadily moving a task forward&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this kind of work, the key is usually not whether one reply is especially impressive. It is whether the model can stay stable across a longer chain of work.&lt;/p&gt;
&lt;p&gt;The reason &lt;code&gt;Claude&lt;/code&gt; is often favored is usually not that “it says one sentence better than the others,” but that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It holds up better on long-context tasks&lt;/li&gt;
&lt;li&gt;It feels steadier when reading files, logs, and rules continuously&lt;/li&gt;
&lt;li&gt;It is better suited to gradually advancing complex coding work&lt;/li&gt;
&lt;li&gt;In command-line and agent workflows, it is often treated as the primary working model&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are doing &lt;code&gt;vibe coding&lt;/code&gt;, fixing bugs in the terminal, understanding project structure, or changing features across multiple files, &lt;code&gt;Claude&lt;/code&gt;’s strengths tend to show up more clearly.&lt;/p&gt;
&lt;p&gt;Put simply, &lt;code&gt;Claude&lt;/code&gt; feels more like a model you work with to get things done, not just one you ask a question and get an answer from.&lt;/p&gt;
&lt;h2 id=&#34;3-gemini-often-wins-not-by-competing-head-on-in-everything&#34;&gt;3. &lt;code&gt;Gemini&lt;/code&gt; often wins not by “competing head-on in everything”
&lt;/h2&gt;&lt;p&gt;When people talk about &lt;code&gt;Gemini&lt;/code&gt;, they often frame the question like this: is it the strongest of the three?&lt;/p&gt;
&lt;p&gt;But in real usage, the more useful question is usually not that. It is: &lt;strong&gt;in which scenarios is it especially worth pulling out and using on purpose?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Gemini&lt;/code&gt;’s value often shows up more clearly in these directions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Integration with the Google ecosystem&lt;/li&gt;
&lt;li&gt;Search and information gathering&lt;/li&gt;
&lt;li&gt;Multimodal entry points&lt;/li&gt;
&lt;li&gt;Certain product-side feature linkages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your workflow is already close to Google’s toolchain, for example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search&lt;/li&gt;
&lt;li&gt;Documents&lt;/li&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;li&gt;Browser-side usage&lt;/li&gt;
&lt;li&gt;Mobile entry points&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then &lt;code&gt;Gemini&lt;/code&gt;’s practical convenience may matter more than a simple model-score comparison.&lt;/p&gt;
&lt;p&gt;In other words, &lt;code&gt;Gemini&lt;/code&gt; is often useful because it plugs into your workflow more naturally, not just because it may or may not beat someone else in a single response.&lt;/p&gt;
&lt;h2 id=&#34;4-the-useful-way-to-choose-is-not-asking-who-is-strongest-but-asking-what-kind-of-task-you-have&#34;&gt;4. The useful way to choose is not asking who is strongest, but asking what kind of task you have
&lt;/h2&gt;&lt;p&gt;When people compare all three models side by side, the easiest trap is trying to find one “single best” model.&lt;/p&gt;
&lt;p&gt;But real tasks vary too much:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some are one-off Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;Some are long-running conversations&lt;/li&gt;
&lt;li&gt;Some are software projects&lt;/li&gt;
&lt;li&gt;Some are information retrieval&lt;/li&gt;
&lt;li&gt;Some are multimodal processing&lt;/li&gt;
&lt;li&gt;Some are toolchain collaboration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So the more effective approach is usually to sort by task type:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you want a broad, high-frequency assistant that works right away, start with &lt;code&gt;ChatGPT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If you need long context, command-line work, coding collaboration, and steady progress on complex tasks, try &lt;code&gt;Claude&lt;/code&gt; first&lt;/li&gt;
&lt;li&gt;If you need help from the Google ecosystem, search, multimodal entry points, or certain product integrations, pay special attention to &lt;code&gt;Gemini&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That kind of division of labor is much closer to real-world use than forcing a single overall champion.&lt;/p&gt;
&lt;h2 id=&#34;5-why-many-heavy-users-subscribe-to-all-three&#34;&gt;5. Why many heavy users subscribe to all three
&lt;/h2&gt;&lt;p&gt;From a light user’s perspective, paying for all three can look redundant.&lt;br&gt;
From a heavy user’s perspective, it is more like assigning different tools to different jobs.&lt;/p&gt;
&lt;p&gt;The reason is simple:&lt;br&gt;
if the strengths of the three models have already started to diverge clearly, then using them together is not really duplicated spending. It is a way to reduce switching costs and trial-and-error costs.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;ChatGPT&lt;/code&gt; for daily organization and general Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Claude&lt;/code&gt; for primary coding work&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Gemini&lt;/code&gt; for certain search, multimodal, or Google-related workflows&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The logic of this setup is not fundamentally different from designers installing multiple creative tools or developers using multiple IDEs.&lt;/p&gt;
&lt;h2 id=&#34;6-when-you-should-not-switch-models-too-often&#34;&gt;6. When you should not switch models too often
&lt;/h2&gt;&lt;p&gt;Of course, having more models is not always better.&lt;/p&gt;
&lt;p&gt;If you are still building a stable workflow, jumping too early and too often between three models can actually make things messier. Common issues include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Re-explaining the same task three times&lt;/li&gt;
&lt;li&gt;Getting different suggestions from different models and struggling more to judge them&lt;/li&gt;
&lt;li&gt;Losing context and increasing collaboration costs&lt;/li&gt;
&lt;li&gt;Getting stuck on tool choice before forming your own working boundaries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So a steadier way is usually this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Give each model one primary scenario first&lt;/li&gt;
&lt;li&gt;Use it continuously in that scenario for a while&lt;/li&gt;
&lt;li&gt;Gradually build your own habits of division of labor&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That makes it easier to gain reusable experience instead of staying forever in the “let me try this one today” stage.&lt;/p&gt;
&lt;h2 id=&#34;7-a-simple-way-to-remember-it&#34;&gt;7. A simple way to remember it
&lt;/h2&gt;&lt;p&gt;If you just want a practical version to remember, you can use this plain-language split:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ChatGPT&lt;/code&gt;: more like the default general-purpose assistant&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Claude&lt;/code&gt;: more like the main option for long tasks and coding collaboration&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini&lt;/code&gt;: more like the tool with stronger advantages in search, multimodal work, and the Google ecosystem&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is not an absolute rule, and it does not mean the three cannot replace each other. It is simply a more realistic starting point.&lt;/p&gt;
&lt;p&gt;What really matters is not choosing the “strongest model in the universe,” but figuring out as soon as possible:&lt;br&gt;
&lt;strong&gt;for the kind of task in front of you, which model saves the most time, costs the least mental effort, and makes it easiest to get results?&lt;/strong&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Google App for Desktop: Bringing AI Search to Windows</title>
        <link>https://knightli.com/en/2026/04/18/google-app-desktop-ai-search-windows/</link>
        <pubDate>Sat, 18 Apr 2026 11:08:00 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/04/18/google-app-desktop-ai-search-windows/</guid>
        <description>&lt;p&gt;Google has added a lighter search entry point to the Windows desktop. Instead of opening a browser first, you can press a shortcut, bring up a search box, ask questions, upload images, analyze files, select content on your screen, and keep asking follow-up questions.&lt;/p&gt;
&lt;p&gt;The official name is &lt;strong&gt;Google app for desktop&lt;/strong&gt;. It is not meant to replace a traditional browser. Its purpose is to bring Google Search, AI Mode, Google Lens, screen sharing, computer file search, and Google Drive search into one desktop search box.&lt;/p&gt;
&lt;p&gt;If you often look up information, summarize documents, identify screenshot content, or want a faster way to search your computer, this desktop Google App is worth trying.&lt;/p&gt;
&lt;h2 id=&#34;requirements&#34;&gt;Requirements
&lt;/h2&gt;&lt;p&gt;According to Google&amp;rsquo;s official page, the current requirements are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Users must be 13 or older.&lt;/li&gt;
&lt;li&gt;The device must run Windows 10 or later.&lt;/li&gt;
&lt;li&gt;The app is currently only available in English.&lt;/li&gt;
&lt;li&gt;AI Mode in Google Search is not supported for all accounts, countries, and languages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, Windows 10 and Windows 11 users can install it first and test it. The official page currently says &lt;strong&gt;Now available on Windows&lt;/strong&gt;, so this article focuses on the Windows version.&lt;/p&gt;
&lt;h2 id=&#34;main-features&#34;&gt;Main Features
&lt;/h2&gt;&lt;h3 id=&#34;1-open-search-with-a-shortcut&#34;&gt;1. Open Search With a Shortcut
&lt;/h3&gt;&lt;p&gt;After installation, press:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Alt + Space
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This opens the Google desktop search box. Press it again to hide the box.&lt;/p&gt;
&lt;p&gt;The experience is a bit like a system launcher. Whether you are writing a document, reading a web page, organizing files, or using another app, you can call up Search without switching back to the browser.&lt;/p&gt;
&lt;h3 id=&#34;2-ai-mode-and-follow-up-questions&#34;&gt;2. AI Mode and Follow-Up Questions
&lt;/h3&gt;&lt;p&gt;Traditional search usually gives you a list of links. AI Mode is closer to a summarized answer built from search results. You can ask a question directly, get a more complete response, and still open helpful links when needed.&lt;/p&gt;
&lt;p&gt;The useful part is that you can keep asking follow-up questions. For example, start with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What is this tool best used for?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Then continue with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If I create written content, how can I use it to improve my workflow?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This avoids repeatedly rewriting keywords or jumping between multiple pages.&lt;/p&gt;
&lt;h3 id=&#34;3-upload-images-for-recognition-and-search&#34;&gt;3. Upload Images for Recognition and Search
&lt;/h3&gt;&lt;p&gt;The desktop Google App supports uploading an image and asking questions about it. Common uses include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Identifying people, places, products, or objects in an image.&lt;/li&gt;
&lt;li&gt;Finding similar images and related information.&lt;/li&gt;
&lt;li&gt;Extracting a description from image content.&lt;/li&gt;
&lt;li&gt;Asking AI to generate creative prompts based on the image.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, after uploading a portrait, you could ask:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Who is the person in this image? Please provide an introduction and related references.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;For everyday image lookup, source finding, and object recognition, this is more convenient than manually opening a web page and uploading the image there.&lt;/p&gt;
&lt;h3 id=&#34;4-select-screen-content-with-google-lens&#34;&gt;4. Select Screen Content With Google Lens
&lt;/h3&gt;&lt;p&gt;Google Lens is one of the most useful parts of the desktop app. You can select an area on your screen and let it recognize and search that content.&lt;/p&gt;
&lt;p&gt;It is useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Selecting a product on a web page to find similar items or related information.&lt;/li&gt;
&lt;li&gt;Selecting text in a screenshot and asking for an explanation.&lt;/li&gt;
&lt;li&gt;Selecting a software interface and asking what tool it is.&lt;/li&gt;
&lt;li&gt;Selecting an error message and asking for troubleshooting ideas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The core idea is simple: search what you see. Previously, you might have needed to take a screenshot, save it, and upload it. Now you can select the target directly on the screen.&lt;/p&gt;
&lt;h3 id=&#34;5-screen-sharing-search&#34;&gt;5. Screen Sharing Search
&lt;/h3&gt;&lt;p&gt;In addition to selecting one part of the screen, the app also supports screen sharing. Once enabled, AI can see the current window or the entire screen, and you can ask questions about what is visible.&lt;/p&gt;
&lt;p&gt;For example, while reading an article, you can ask:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please summarize the key points on the current page.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Or:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What parts of this page could be improved?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This can save time when reading web pages, reviewing designs, analyzing code snippets, or summarizing long pages. When screen sharing is enabled, the system usually displays a clear border so you can confirm what is being shared.&lt;/p&gt;
&lt;h3 id=&#34;6-search-computer-files-and-google-drive&#34;&gt;6. Search Computer Files and Google Drive
&lt;/h3&gt;&lt;p&gt;Google&amp;rsquo;s official page also says the app can find apps and files across your computer and Google Drive from the same search box.&lt;/p&gt;
&lt;p&gt;This combines desktop search and cloud search. If you remember part of a file name, a keyword from the content, or want to quickly find something in Google Drive, you do not need to open File Explorer and Drive separately.&lt;/p&gt;
&lt;p&gt;On first use, the app may ask whether you want to enable Google Drive search or local file search. Authorize only the areas you actually need, especially when local files and cloud data are involved.&lt;/p&gt;
&lt;h2 id=&#34;installation-and-usage&#34;&gt;Installation and Usage
&lt;/h2&gt;&lt;h3 id=&#34;1-open-the-official-download-page&#34;&gt;1. Open the Official Download Page
&lt;/h3&gt;&lt;p&gt;Visit:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://search.google/google-app/desktop/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://search.google/google-app/desktop/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Click &lt;strong&gt;Download app&lt;/strong&gt; to download the installer.&lt;/p&gt;
&lt;h3 id=&#34;2-install-the-desktop-app&#34;&gt;2. Install the Desktop App
&lt;/h3&gt;&lt;p&gt;After the download finishes, run the installer and follow the prompts.&lt;/p&gt;
&lt;p&gt;You can choose to sign in with a Google account. Signing in is more useful if you want Google Drive search, personalized search, and some AI features. If you only want to try basic search, you can also start with the default prompts.&lt;/p&gt;
&lt;h3 id=&#34;3-open-the-search-box&#34;&gt;3. Open the Search Box
&lt;/h3&gt;&lt;p&gt;Press:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Alt + Space
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;A Google search box appears on the desktop. You can type a question directly, upload files, use Lens, or start screen sharing.&lt;/p&gt;
&lt;h3 id=&#34;4-enable-the-search-scope-you-need&#34;&gt;4. Enable the Search Scope You Need
&lt;/h3&gt;&lt;p&gt;If you want to search Google Drive or local files, follow the prompts to enable the relevant permissions.&lt;/p&gt;
&lt;p&gt;A practical approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable Google Drive search first and test cloud document search.&lt;/li&gt;
&lt;li&gt;Enable local file search only if you need it.&lt;/li&gt;
&lt;li&gt;Leave unnecessary scopes disabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This gives you access to the useful parts while keeping permissions clear.&lt;/p&gt;
&lt;h2 id=&#34;common-use-cases&#34;&gt;Common Use Cases
&lt;/h2&gt;&lt;h3 id=&#34;analyze-pdfs-and-documents&#34;&gt;Analyze PDFs and Documents
&lt;/h3&gt;&lt;p&gt;You can drag in a PDF, table, or document and ask it to summarize the key points.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please summarize the key points of this PDF and list anything I should pay attention to.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;For dense files such as forms, statements, application materials, or manuals, continue with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please organize the key information by category.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This is usually faster than reading a long document page by page.&lt;/p&gt;
&lt;h3 id=&#34;summarize-web-pages&#34;&gt;Summarize Web Pages
&lt;/h3&gt;&lt;p&gt;After enabling screen sharing, you can ask it to summarize the current page.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Extract the main ideas from this page and summarize them in five bullet points.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This is useful for long articles, product pages, documentation, and news pages.&lt;/p&gt;
&lt;h3 id=&#34;identify-screenshots-and-interfaces&#34;&gt;Identify Screenshots and Interfaces
&lt;/h3&gt;&lt;p&gt;Use Google Lens to select a software interface, code snippet, error message, or image content on the screen, then ask it to explain what you are seeing.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please explain what this error means and suggest a troubleshooting path.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Or:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What tool is shown in this screenshot, and what scenarios is it likely used for?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;help-with-content-creation&#34;&gt;Help With Content Creation
&lt;/h3&gt;&lt;p&gt;It can also help write titles, generate outlines, and organize selling points.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Write 10 article titles about AI tool recommendations, with angles for practical tips, productivity tools, and office workflows.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;After getting a draft, you can continue:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Make these titles more suitable for a tech blog.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This follow-up style feels more natural than asking a search engine for everything in one shot.&lt;/p&gt;
&lt;h2 id=&#34;usage-tips&#34;&gt;Usage Tips
&lt;/h2&gt;&lt;p&gt;If you only need daily information lookup, treat it as a faster Google Search entry point. If you often work with images, PDFs, web pages, and screenshots, focus on Lens, file uploads, and screen sharing.&lt;/p&gt;
&lt;p&gt;Keep three points in mind:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The official page says the app is currently only available in English. Chinese prompts may behave differently depending on your account and region.&lt;/li&gt;
&lt;li&gt;AI Mode is not available to every account. If you cannot see it, check your account, region, and language settings.&lt;/li&gt;
&lt;li&gt;Local file search, Google Drive search, and screen sharing involve privacy permissions. Confirm what content you want the app to access before enabling them.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;quick-summary&#34;&gt;Quick Summary
&lt;/h2&gt;&lt;p&gt;The main value of Google app for desktop is that it moves search out of the browser and turns it into an AI search box you can call up at any time.&lt;/p&gt;
&lt;p&gt;In short, it can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open search quickly with &lt;code&gt;Alt + Space&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use AI Mode to get organized answers.&lt;/li&gt;
&lt;li&gt;Upload images or files for analysis.&lt;/li&gt;
&lt;li&gt;Select screen content with Google Lens.&lt;/li&gt;
&lt;li&gt;Understand the current window or the whole screen through screen sharing.&lt;/li&gt;
&lt;li&gt;Search local files, apps, and Google Drive content.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you already rely on Google Search and want the experience to feel more like asking an assistant, Google app for desktop is worth a try.&lt;/p&gt;
&lt;h2 id=&#34;reference&#34;&gt;Reference
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Google app for desktop official page: &lt;a class=&#34;link&#34; href=&#34;https://search.google/google-app/desktop/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://search.google/google-app/desktop/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Sharing an Agent Skill for E-commerce Product Image Cutout and Standardization</title>
        <link>https://knightli.com/en/2026/04/09/product-cutout-normalize-agent-skill-guide/</link>
        <pubDate>Thu, 09 Apr 2026 21:43:50 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/04/09/product-cutout-normalize-agent-skill-guide/</guid>
        <description>&lt;p&gt;&lt;code&gt;product-cutout-normalize&lt;/code&gt; is an Agent Skill for product images.&lt;/p&gt;
&lt;p&gt;It turns raw product photos into square transparent images with a consistent layout. The default rules are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;1024x1024&lt;/code&gt; canvas&lt;/li&gt;
&lt;li&gt;transparent background&lt;/li&gt;
&lt;li&gt;preserve the full subject as much as possible&lt;/li&gt;
&lt;li&gt;rotate vertical subjects to horizontal&lt;/li&gt;
&lt;li&gt;center the subject&lt;/li&gt;
&lt;li&gt;normalize visible subject width to &lt;code&gt;820px&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is a good fit for e-commerce assets, product libraries, and product detail page image preparation.&lt;/p&gt;
&lt;h2 id=&#34;what-this-skill-solves&#34;&gt;What this skill solves
&lt;/h2&gt;&lt;p&gt;Even after a basic cutout, product images often still have issues such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;leftover white or light gray edges&lt;/li&gt;
&lt;li&gt;inconsistent subject orientation&lt;/li&gt;
&lt;li&gt;inconsistent canvas size&lt;/li&gt;
&lt;li&gt;inconsistent subject scale&lt;/li&gt;
&lt;li&gt;small specks in transparent regions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This skill handles them with a fixed workflow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use Gemini for cutout&lt;/li&gt;
&lt;li&gt;Clean light-colored background from the borders&lt;/li&gt;
&lt;li&gt;Remove small noise fragments&lt;/li&gt;
&lt;li&gt;Rotate vertical images to horizontal&lt;/li&gt;
&lt;li&gt;Scale the subject to a target width&lt;/li&gt;
&lt;li&gt;Place it in the center of a transparent square canvas&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That makes the output cleaner and more suitable for batch use.&lt;/p&gt;
&lt;h2 id=&#34;when-to-use-it&#34;&gt;When to use it
&lt;/h2&gt;&lt;p&gt;This is a good fit when you need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;batch-process product photos&lt;/li&gt;
&lt;li&gt;export transparent PNG assets&lt;/li&gt;
&lt;li&gt;keep a consistent visual size&lt;/li&gt;
&lt;li&gt;use a stable and repeatable workflow&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you only edit a few images or need to manually adjust each layout, this may not be the right tool.&lt;/p&gt;
&lt;h2 id=&#34;quick-start&#34;&gt;Quick start
&lt;/h2&gt;&lt;p&gt;The most direct way to run it is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\.venv\Scripts\python.exe&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.codex\skills\product-cutout-normalize\scripts\run_pipeline.py&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-overwrite&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Before running it, make sure you have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GEMINI_API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;google-genai&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Pillow&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Install dependencies:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.\.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;venv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scripts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;python&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;exe&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-m&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;google-genai&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pillow&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Set the environment variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:GEMINI_API_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your_api_key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;output-rules&#34;&gt;Output rules
&lt;/h2&gt;&lt;p&gt;The default output is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;transparent-background &lt;code&gt;PNG&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1024x1024&lt;/code&gt; canvas&lt;/li&gt;
&lt;li&gt;&lt;code&gt;820px&lt;/code&gt; subject width&lt;/li&gt;
&lt;li&gt;centered subject&lt;/li&gt;
&lt;li&gt;small noise fragments removed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So this is more than a simple background-removal script. It is closer to a product image cleanup script.&lt;/p&gt;
&lt;h2 id=&#34;main-parameters&#34;&gt;Main parameters
&lt;/h2&gt;&lt;p&gt;Common flags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--model&lt;/code&gt;
Default: &lt;code&gt;gemini-2.5-flash-image&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--canvas-size&lt;/code&gt;
Output square canvas size, default &lt;code&gt;1024&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--target-width&lt;/code&gt;
Visible subject width, default &lt;code&gt;820&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--min-component-pixels&lt;/code&gt;
Transparent fragments smaller than this are removed, default &lt;code&gt;500&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--overwrite&lt;/code&gt;
Overwrite existing outputs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\.venv\Scripts\python.exe&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.codex\skills\product-cutout-normalize\scripts\run_pipeline.py&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\input&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\output&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-canvas-size&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1280&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-target-width&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;960&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-overwrite&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;workflow&#34;&gt;Workflow
&lt;/h2&gt;&lt;p&gt;The workflow is straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use Gemini for cutout&lt;/li&gt;
&lt;li&gt;Clean light-colored border background&lt;/li&gt;
&lt;li&gt;Remove small fragments&lt;/li&gt;
&lt;li&gt;Rotate vertical images to horizontal&lt;/li&gt;
&lt;li&gt;Scale to the target width&lt;/li&gt;
&lt;li&gt;Place the result on a transparent square canvas&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;how-it-differs-from-a-basic-cutout-script&#34;&gt;How it differs from a basic cutout script
&lt;/h2&gt;&lt;p&gt;Compared with a basic background-removal script, it also handles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;subject orientation normalization&lt;/li&gt;
&lt;li&gt;subject size normalization&lt;/li&gt;
&lt;li&gt;canvas size normalization&lt;/li&gt;
&lt;li&gt;small-fragment cleanup&lt;/li&gt;
&lt;li&gt;outputs that are easier to place directly into an asset library&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;skillmd-source&#34;&gt;SKILL.md source
&lt;/h2&gt;&lt;p&gt;The full &lt;code&gt;SKILL.md&lt;/code&gt; source is preserved below without modification:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;name: product-cutout-normalize
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;description: Run a reusable Gemini product-image pipeline that removes backgrounds, preserves the full subject, rotates tall products to a horizontal orientation, centers them on a 1024x1024 transparent canvas, and normalizes the visible subject width to 820px. Use when the user wants a repeatable cutout-and-normalize workflow for product photos or asks to batch-process product images into standardized square PNG assets.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;# Product Cutout Normalize
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Use this skill when product photos need the same deterministic finishing pipeline:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Gemini cutout from the original photo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; border cleanup to transparent
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; preserve the full subject
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; rotate to horizontal when the subject is taller than it is wide
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; center on a &lt;span class=&#34;sb&#34;&gt;`1024x1024`&lt;/span&gt; transparent canvas
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; normalize the visible subject width to &lt;span class=&#34;sb&#34;&gt;`820px`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Quick Start
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Run the bundled script:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```powershell
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\.venv\Scripts\python.exe&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.codex\skills\product-cutout-normalize\scripts\run_pipeline.py&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-overwrite&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Required environment:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`GEMINI_API_KEY`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`google-genai`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`Pillow`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Workflow
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;1.&lt;/span&gt; Confirm the request matches this standard pipeline. If the user asks for a different canvas size, subject width, or layout rule, pass explicit flags instead of changing the script.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;2.&lt;/span&gt; Run the bundled script on the input directory.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;3.&lt;/span&gt; If a result looks misaligned, inspect the alpha bounding box and small detached artifacts first; this pipeline already removes tiny alpha components by default.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;4.&lt;/span&gt; Report the exact input and output directories used, plus any non-default flags.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Script
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Primary entry point:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`scripts/run_pipeline.py`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Key flags:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--model`&lt;/span&gt;: Gemini image model, default &lt;span class=&#34;sb&#34;&gt;`gemini-2.5-flash-image`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--canvas-size`&lt;/span&gt;: output square size, default &lt;span class=&#34;sb&#34;&gt;`1024`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--target-width`&lt;/span&gt;: visible subject width after normalization, default &lt;span class=&#34;sb&#34;&gt;`820`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--min-component-pixels`&lt;/span&gt;: remove detached alpha specks smaller than this, default &lt;span class=&#34;sb&#34;&gt;`500`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--overwrite`&lt;/span&gt;: replace existing outputs in the destination directory
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Repo Integration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If the current project already has [&lt;span class=&#34;nt&#34;&gt;`scripts/nano_banana_cutout.py`&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;/c:/Work/my_shop/scripts/nano_banana_cutout.py&lt;/span&gt;), prefer that repo script when the user wants the same pipeline inside this repository. Use the bundled skill script when the task is cross-project reuse or when you want the workflow to stay self-contained inside the skill.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;scriptsrun_pipelinepy-source&#34;&gt;scripts/run_pipeline.py source
&lt;/h2&gt;&lt;p&gt;The full &lt;code&gt;scripts/run_pipeline.py&lt;/code&gt; source is preserved below without modification:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;  1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 88
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 89
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 90
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 91
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 92
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 93
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 94
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 95
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 96
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 97
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 98
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 99
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;100
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;101
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;102
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;103
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;104
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;105
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;106
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;107
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;108
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;109
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;110
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;111
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;112
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;113
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;114
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;115
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;116
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;117
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;118
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;119
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;120
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;121
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;122
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;123
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;124
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;125
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;126
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;127
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;128
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;129
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;130
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;131
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;132
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;133
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;134
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;135
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;136
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;137
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;138
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;139
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;140
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;141
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;142
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;143
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;144
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;145
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;146
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;147
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;148
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;149
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;150
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;151
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;152
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;153
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;154
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;155
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;156
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;157
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;158
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;159
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;160
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;161
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;162
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;163
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;164
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;165
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;166
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;167
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;168
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;169
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;170
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;171
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;172
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;173
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;174
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;175
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;176
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;177
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;178
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;179
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;180
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;181
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;182
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;183
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;184
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;185
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;186
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;187
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;188
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;189
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;190
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;191
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;192
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;193
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;194
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;195
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;196
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;197
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;198
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;199
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;200
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;201
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;202
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;203
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;204
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;205
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;206
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;207
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;208
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;209
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;210
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;211
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;212
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;213
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;214
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;215
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;216
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;217
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;218
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;219
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;220
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;221
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;222
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;223
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;224
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;225
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;226
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;227
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;228
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;229
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;230
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;231
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;232
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;233
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;234
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;235
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;236
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;237
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;238
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;239
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;240
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;241
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;242
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;243
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;244
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;245
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;246
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;247
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;248
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;249
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;250
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;251
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;252
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;253
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;254
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;255
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;256
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;257
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;258
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;259
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;260
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;261
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;262
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;263
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;264
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;265
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;266
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;267
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;268
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;269
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;270
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;271
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;272
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;273
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;274
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;275
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;276
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;277
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;278
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;279
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;280
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;281
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;282
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;283
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;284
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;285
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;286
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;287
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;288
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;289
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;290
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;291
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;__future__&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;annotations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;collections&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;PIL&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ImportError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# pragma: no cover&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing dependency: google-genai. Install it with &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#39;.\.venv\Scripts\python.exe -m pip install google-genai&amp;#39;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;exc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Remove the entire background from this product photo and return only the product &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;on a fully transparent background as a PNG. Keep the full product intact, preserve &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;thin cable details, clean the inner loops and holes, and do not add any new objects &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;or shadows.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_CANVAS_SIZE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_TARGET_WIDTH&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;820&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_MIN_COMPONENT_PIXELS&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;SUPPORTED_EXTENSIONS&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpeg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.webp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;170&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;_pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Unsupported image object type: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;popleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;remove_small_components&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getchannel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;alpha_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alpha_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;popleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alpha_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;py&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;py&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;rgba_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;py&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;normalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;bbox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getchannel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getbbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bbox&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;90&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expand&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resample&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Resampling&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BICUBIC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;rotated_bbox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getchannel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getbbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rotated_bbox&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotated_bbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;scale&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;round&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;scale&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Resampling&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LANCZOS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;offset_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;offset_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alpha_composite&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset_y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;finalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;transparent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cleaned&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;remove_small_components&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transparent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;normalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cleaned&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;parts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;candidates&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;candidates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned no content parts.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;hasattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;as_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;finalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;wb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;finalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;with_suffix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unlink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;missing_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned text only and no edited image.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Cut out product images with Gemini and normalize them to square transparent PNGs.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--model&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-2.5-flash-image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--canvas-size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_CANVAS_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--target-width&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_TARGET_WIDTH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--min-component-pixels&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_MIN_COMPONENT_PIXELS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--overwrite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;action&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;store_true&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GEMINI_API_KEY&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing GEMINI_API_KEY environment variable.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Input directory does not exist: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--canvas-size must be positive.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--target-width must be positive and no larger than --canvas-size.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--min-component-pixels must be &amp;gt;= 0.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SUPPORTED_EXTENSIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stem&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exists&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;overwrite&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;skip &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Download attachment: &lt;a class=&#34;link&#34; href=&#34;product-cutout-normalize.7z&#34; &gt;product-cutout-normalize.7z&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>How to Use Google Nano Banana for Image Cutouts</title>
        <link>https://knightli.com/en/2026/04/09/google-nano-banana-cutout-guide/</link>
        <pubDate>Thu, 09 Apr 2026 20:10:48 +0800</pubDate>
        
        <guid>https://knightli.com/en/2026/04/09/google-nano-banana-cutout-guide/</guid>
        <description>&lt;p&gt;This article uses a practical Python script to show how to call Google&amp;rsquo;s &lt;code&gt;Nano Banana&lt;/code&gt; image editing capability for product-image cutouts.&lt;/p&gt;
&lt;p&gt;The goal of this implementation is very clear:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read product images from a directory&lt;/li&gt;
&lt;li&gt;Call a Google image model to remove the background&lt;/li&gt;
&lt;li&gt;Apply one more round of local transparent-background cleanup to the returned image&lt;/li&gt;
&lt;li&gt;Export the final result as a transparent &lt;code&gt;PNG&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you already have a batch of white-background product photos, headset images, or cable images and want to quickly generate transparent-background assets for e-commerce use, this approach is very direct.&lt;/p&gt;
&lt;h2 id=&#34;what-this-code-does&#34;&gt;What this code does
&lt;/h2&gt;&lt;p&gt;This script is mainly divided into 4 parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Define a prompt so the model understands it should remove the background, keep the subject intact, and avoid adding shadows&lt;/li&gt;
&lt;li&gt;Call the &lt;code&gt;google-genai&lt;/code&gt; image generation interface&lt;/li&gt;
&lt;li&gt;Extract the image result from the model response&lt;/li&gt;
&lt;li&gt;Use local logic to turn light-colored edge background areas transparent and reduce leftover halos&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In other words, it does not simply send the image to the model and stop there. It combines model editing with local post-processing.&lt;/p&gt;
&lt;h2 id=&#34;before-you-run-it&#34;&gt;Before you run it
&lt;/h2&gt;&lt;p&gt;Install the dependencies first:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;venv&lt;span class=&#34;se&#34;&gt;\S&lt;/span&gt;cripts&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;ython.exe -m pip install google-genai pillow
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;how-to-get-gemini_api_key&#34;&gt;How to get GEMINI_API_KEY
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;GEMINI_API_KEY&lt;/code&gt; is the key used when calling the Gemini API. According to Google&amp;rsquo;s official quickstart, if you do not already have one, you can create it directly in Google AI Studio.&lt;/p&gt;
&lt;p&gt;The process is straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open Google AI Studio.&lt;/li&gt;
&lt;li&gt;Sign in with your Google account.&lt;/li&gt;
&lt;li&gt;Find the &lt;code&gt;Get API key&lt;/code&gt; or &lt;code&gt;API keys&lt;/code&gt; page.&lt;/li&gt;
&lt;li&gt;Create a new API key.&lt;/li&gt;
&lt;li&gt;Copy the generated key.&lt;/li&gt;
&lt;li&gt;Configure it as a local environment variable for the script to read.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If there is no available project on the page yet, you typically need to finish project initialization first and then return to the API key page to create the key.&lt;/p&gt;
&lt;p&gt;After you have the key, configure the environment variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env&lt;/span&gt;:GEMINI_API_KEY&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your_api_key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If you are using &lt;code&gt;cmd&lt;/code&gt;, you can write:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your_api_key
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If both &lt;code&gt;GEMINI_API_KEY&lt;/code&gt; and &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt; are set, the runtime will usually prefer &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt;, so it is better to keep only one of them to avoid confusion.&lt;/p&gt;
&lt;h2 id=&#34;example-directory-structure&#34;&gt;Example directory structure
&lt;/h2&gt;&lt;p&gt;The script accepts two arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;input_dir&lt;/code&gt;: input image directory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;output_dir&lt;/code&gt;: output image directory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;images/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  product1.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  product2.png
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;output/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;how-to-run-it&#34;&gt;How to run it
&lt;/h2&gt;&lt;p&gt;Assuming the script file is named &lt;code&gt;cutout.py&lt;/code&gt;, run it like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;venv&lt;span class=&#34;se&#34;&gt;\S&lt;/span&gt;cripts&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;ython.exe .&lt;span class=&#34;se&#34;&gt;\c&lt;/span&gt;utout.py .&lt;span class=&#34;se&#34;&gt;\i&lt;/span&gt;mages .&lt;span class=&#34;se&#34;&gt;\o&lt;/span&gt;utput
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If you want to switch models, you can also pass it explicitly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;venv&lt;span class=&#34;se&#34;&gt;\S&lt;/span&gt;cripts&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;ython.exe .&lt;span class=&#34;se&#34;&gt;\c&lt;/span&gt;utout.py .&lt;span class=&#34;se&#34;&gt;\i&lt;/span&gt;mages .&lt;span class=&#34;se&#34;&gt;\o&lt;/span&gt;utput --model gemini-2.5-flash-image
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The script will iterate over these file types in the input directory:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.jpg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.jpeg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.png&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.webp&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After processing, it will generate transparent-background &lt;code&gt;PNG&lt;/code&gt; files with matching names in the output directory.&lt;/p&gt;
&lt;h2 id=&#34;core-api-call-flow&#34;&gt;Core API call flow
&lt;/h2&gt;&lt;p&gt;The key code that actually calls Google Nano Banana is here:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Two pieces of content are passed in here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A text prompt, &lt;code&gt;PROMPT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;PIL.Image&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The prompt asks the model to remove the full background from the product image, keep only the subject, and pay attention to a few important requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep the full product intact&lt;/li&gt;
&lt;li&gt;Preserve thin lines and cable details&lt;/li&gt;
&lt;li&gt;Clean up inner holes and loop areas&lt;/li&gt;
&lt;li&gt;Do not add new objects&lt;/li&gt;
&lt;li&gt;Do not add shadows&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prompts like this have a big effect on cutout quality, especially for details such as earphone wires, transparent edges, and hollow regions.&lt;/p&gt;
&lt;h2 id=&#34;why-local-post-processing-is-still-needed&#34;&gt;Why local post-processing is still needed
&lt;/h2&gt;&lt;p&gt;After the model returns the result, the script does not save it directly. It also runs &lt;code&gt;make_transparent_from_borders(image)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The idea behind this step is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start from the outer border of the image and find light-colored background pixels&lt;/li&gt;
&lt;li&gt;Use breadth-first search to mark all connected light-colored regions&lt;/li&gt;
&lt;li&gt;Convert those regions to transparent in one pass&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The benefit is that it can further clean up leftover white edges, light gray backgrounds, and edge areas that are not clean enough.&lt;/p&gt;
&lt;p&gt;The condition used to decide whether a pixel is background is here:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;170&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;In simple terms, this means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The overall color must be bright enough&lt;/li&gt;
&lt;li&gt;The RGB channel difference cannot be too large&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is especially suitable for product images with white, light gray, or near-solid-color backgrounds.&lt;/p&gt;
&lt;h2 id=&#34;full-source-code&#34;&gt;Full source code
&lt;/h2&gt;&lt;p&gt;The complete source code is preserved below so you can reuse or modify it directly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;  1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 88
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 89
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 90
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 91
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 92
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 93
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 94
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 95
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 96
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 97
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 98
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 99
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;100
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;101
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;102
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;103
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;104
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;105
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;106
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;107
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;108
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;109
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;110
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;111
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;112
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;113
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;114
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;115
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;116
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;117
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;118
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;119
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;120
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;121
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;122
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;123
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;124
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;125
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;126
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;127
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;128
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;129
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;130
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;131
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;132
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;133
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;134
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;135
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;136
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;137
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;138
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;139
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;140
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;141
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;142
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;143
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;144
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;145
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;146
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;147
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;148
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;149
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;150
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;__future__&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;annotations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;collections&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;PIL&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ImportError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# pragma: no cover&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing dependency: google-genai. Install it with &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#39;.\.venv\Scripts\python.exe -m pip install google-genai&amp;#39;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;exc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Remove the entire background from this product photo and return only the product &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;on a fully transparent background as a PNG. Keep the full product intact, preserve &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;thin cable details, clean the inner loops and holes, and do not add any new objects &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;or shadows.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;170&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;_pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Unsupported image object type: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;popleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;parts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;candidates&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;candidates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned no content parts.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;hasattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;as_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;mime_type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;mime_type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;wb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;with_suffix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unlink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;missing_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned text only and no edited image.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Use Nano Banana / Gemini image editing to cut out product images.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--model&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-2.5-flash-image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GEMINI_API_KEY&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing GEMINI_API_KEY environment variable.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;exts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpeg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.webp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stem&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;good-places-to-improve-it-further&#34;&gt;Good places to improve it further
&lt;/h2&gt;&lt;p&gt;If you plan to use this script for batch production, you can continue improving it in these directions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add retry logic so one failed image does not stop the whole batch&lt;/li&gt;
&lt;li&gt;Add logs to make it easier to identify which image failed&lt;/li&gt;
&lt;li&gt;Make background thresholds configurable&lt;/li&gt;
&lt;li&gt;Support recursive scanning of subdirectories&lt;/li&gt;
&lt;li&gt;Add a side-by-side preview of the original and processed result&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;&lt;p&gt;If you only want the shortest explanation of how to use Google Nano Banana for cutouts, the core process is just three steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;code&gt;google-genai&lt;/code&gt; and &lt;code&gt;Pillow&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;GEMINI_API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Pass the prompt and image to &lt;code&gt;client.models.generate_content()&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The value of this code is that it does more than just call the model. It also adds transparent-background post-processing, which makes it more suitable for direct product-image cutout work.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
