<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: CAMEL AI</title>
    <description>The latest articles on Forem by CAMEL AI (@camel-ai).</description>
    <link>https://forem.com/camel-ai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2728501%2F9d02f1ae-563b-4f1a-aa3d-975e00afeeb9.png</url>
      <title>Forem: CAMEL AI</title>
      <link>https://forem.com/camel-ai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/camel-ai"/>
    <language>en</language>
    <item>
      <title>Eigent：Open-source Cowork Meets MiniMax M2.1</title>
      <dc:creator>CAMEL AI</dc:creator>
      <pubDate>Tue, 27 Jan 2026 16:21:56 +0000</pubDate>
      <link>https://forem.com/camel-ai/eigentopen-source-cowork-meets-minimax-m21-28kb</link>
      <guid>https://forem.com/camel-ai/eigentopen-source-cowork-meets-minimax-m21-28kb</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;In real enterprise environments, many internal tools, dashboards, and legacy systems operate entirely in the browser, forming the backbone of daily business operations.To automate these complex systems, we introduce &lt;strong&gt;Eigent&lt;/strong&gt;, an open-source multi-agent workforce application that runs locally and can be fully set up from source, with a strong focus on browser automation.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore how Eigent, the opensource Cowork leverages CAMEL’s Workforce architecture and browser automation to handle complex, multi-step enterprise tasks. We’ll also take a closer look at Minimax M2.1, analyzing its performance on a real-world enterprise tasks and examining the architectural features that enable it to perform effectively in long-horizon, agentic browser automation scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Background: What is Eigent and How it supports Minimax M2.1&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Eigent is an Open Source Cowork Desktop to Unlock Your Exceptional Productivity. It is built with a multi-agent workforce architecture, supported by general abilities such as browser automation, terminal automation and MCPs. This design enables agents in Eigent to perform tasks much like human workers — operating in real desktop environments, without the need for deep API integrations or constant workflow reconfiguration.&lt;/p&gt;

&lt;p&gt;As foundation models continue to advance, integrating them with Eigent’s open-source multi-agent system serves as an open-source cowork for enterprises, enabling developers and enterprise users to apply LLM capabilities directly to real-world use cases quickly and effectively. You can navigate to the Model Settings page in Eigent, locate the &lt;strong&gt;OpenAI Compatible&lt;/strong&gt; section, and input your API key and url. Once the model name is set to MiniMax-M2.1, you are ready to begin. need help? Check out our guide on &lt;strong&gt;[&lt;/strong&gt;&lt;a href="https://platform.minimaxi.com/docs/api-reference/text-openai-api" rel="noopener noreferrer"&gt;configuring your Minimax API key&lt;/a&gt;&lt;strong&gt;]&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Github Repository &amp;amp; how to setup Eigent&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/eigent-ai/eigent" rel="noopener noreferrer"&gt;https://github.com/eigent-ai/eigent&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Start: Setting Up the Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have two ways to run Eigent: using the pre-compiled desktop app for immediate usage, or setting up the development environment to inspect the code and customize the agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A: The "Zero-Config" Desktop App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For users who want to start automating tasks immediately without touching code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the client from the &lt;a href="https://www.eigent.ai/" rel="noopener noreferrer"&gt;Official Website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Install the &lt;code&gt;.dmg&lt;/code&gt; (macOS) or &lt;code&gt;.exe&lt;/code&gt; (Windows).&lt;/li&gt;
&lt;li&gt;Launch the app—the local backend starts automatically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Option B: Developer Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To access the source code and run the system locally for development, follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Prerequisites&lt;/strong&gt; Ensure you have Node.js (v18-22) and Python installed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Clone and Install&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone https://github.com/eigent-ai/eigent.git
&lt;span class="nb"&gt;cd &lt;/span&gt;eigent

&lt;span class="c"&gt;# Install frontend dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Run the Application&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Return to root and run dev mode&lt;/span&gt;
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once running, you can configure your LLM providers (Minimax M2.1, etc.) directly in the settings. For more detailed information on configuration, advanced features, and troubleshooting, please refer to our &lt;a href="https://docs.eigent.ai/get_started/welcome" rel="noopener noreferrer"&gt;&lt;strong&gt;Official Documentation&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Under the Hood: Eigent full stack and CAMEL Workforce Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Eigent System Overview
&lt;/h3&gt;

&lt;p&gt;Eigent constitutes a local-first desktop application with multi-agent orchestration, powered by the CAMEL Workforce as its core engine. The system implements a decoupled, full-stack architecture that operates entirely on the user's local infrastructure. This design strictly ensures data sovereignty, eliminating the privacy risks associated with cloud-resident agent execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Frontend&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The user interface serves as the control plane for agent configuration and workflow monitoring. Built on React and TypeScript within an Electron framework.&lt;/p&gt;

&lt;p&gt;Key technical components include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State Management: Zustand is employed for handling transient application state, ensuring efficient reactivity.&lt;/li&gt;
&lt;li&gt;Visual Orchestration: React Flow is integrated to visualize agent workspace to track real-time agent execution.&lt;/li&gt;
&lt;li&gt;Communication: The frontend communicates with the backend via secure local HTTP requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. The Backend&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The core logic resides in a local Python server utilizing FastAPI and Uvicorn, which acts as the host environment for the CAMEL multi-agent framework.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runtime Environment: The backend runs on Python 3.10+, managed by uv for high-performance dependency resolution and environment isolation.&lt;/li&gt;
&lt;li&gt;Persistence Layer: PostgreSQL, interfaced via SQLModel/SQLAlchemy ORM, provides robust structured data storage for audit logs, workflow history, and agent states.&lt;/li&gt;
&lt;li&gt;Multi-agentAgent Systemramework: The CAMEL framework handles agent orchestration logic (e.g., workforce), interfacing with Large Language Models (LLMs) whether remote (e.g., Minimax) or local (e.g.,via vLLM) for agent running. The CAMEL framework also offers a rich set of toolkits such as browser toolkit, terminal toolkit, document generation toolkit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CAMEL Workforce: A Multi-Agent System Inspired by Organizational Structures
&lt;/h3&gt;

&lt;p&gt;At the heart of Eigent lies CAMEL Workforce, a multi-agent system architected to resolve complex, real-world tasks through decentralized cooperation. The system utilizes a strict Producer-Consumer pattern, mediated by an asynchronous message channel to manage dependency graphs efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Agent Roles&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coordinator Agent: Functions as the primary dispatcher. It maintains the global state and allocates subtasks to specific workers based on availability and capability.&lt;/li&gt;
&lt;li&gt;Task Agent: Taking responsibility for the semantic decomposition of high-level objectives into executable, atomic units.&lt;/li&gt;
&lt;li&gt;Worker Agent: Serves as the specialized execution unit. Worker agents consume atomic subtasks and execute them using domain-specific tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Asynchronous Communication: The TaskChannel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Decoupling between the coordination layer and the execution layer is achieved via the TaskChannel. This asynchronous message queue manages task distribution without blocking the main execution thread.&lt;/p&gt;

&lt;p&gt;Execution Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Workforce initiates a task.&lt;/li&gt;
&lt;li&gt;Worker nodes poll for assignments.&lt;/li&gt;
&lt;li&gt;Upon completion, results are pushed back.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;3. Dynamic DAG Construction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise workflows are rarely linear. CAMEL Workforce implements a dynamic Directed Acyclic Graph (DAG) construction mechanism. When a high-level prompt is received (e.g., &lt;em&gt;"Create Travel Plan"&lt;/em&gt;), the Task Agent decomposes this objective into discrete nodes.&lt;/p&gt;

&lt;p&gt;The system explicitly maps dependencies, allowing the scheduler to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute independent nodes in parallel (e.g., &lt;em&gt;Search Flight Ticket&lt;/em&gt; and &lt;em&gt;Search Hotel&lt;/em&gt; run concurrently).&lt;/li&gt;
&lt;li&gt;Block dependent nodes until their predecessors reach a &lt;code&gt;DONE&lt;/code&gt; state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Fault-tolerant Mechanism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Given the non-deterministic nature of LLMs, Eigent treats failures as expected state transitions rather than fatal exceptions. The architecture implements a robust recovery mechanism utilizing the following strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RETRY: Re-executes the sub-task on the same worker to handle transient errors.&lt;/li&gt;
&lt;li&gt;REPLAN: The Task Agent modifies the original sub-task based on the failure log before re-queueing the sub-task.&lt;/li&gt;
&lt;li&gt;REASSIGN: The sub-task is migrated from the current worker to a different agent with a compatible skill set.&lt;/li&gt;
&lt;li&gt;DECOMPOSE: If a task fails due to excessive complexity, it is recursively broken down into smaller subtasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Browser Automation Architecture in Eigent&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Yet, a multi-agent workforce architecture can only unlock real enterprise automation when paired with the growing strength of general-purpose capabilities such as browser automation. This is why we emphasize building agents that can operate directly within real business environments rather than relying solely on rigid API integrations.&lt;/p&gt;

&lt;p&gt;Eigent adopts a two-layer architecture that separates browser control from agent orchestration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The TypeScript layer&lt;/strong&gt; is responsible for all browser interactions. It leverages native Playwright APIs to perform DOM operations, capture structured snapshots, generate SoM screenshots, detect occlusions, and handle advanced browser logic directly within the JavaScript runtime. As Playwright is natively built in TypeScript, this layer gains access to cutting-edge features like &lt;code&gt;_snapshotForAI()&lt;/code&gt; and ensures better performance, reliability, and developer ergonomics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Python layer&lt;/strong&gt; handles AI orchestration. It manages LLM calls, agent decision-making, and task planning. This separation allows Python to focus on agent logic, where the Python ecosystem excels in AI and workflow orchestration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The two layers communicate asynchronously via WebSocket&lt;/strong&gt;, enabling non-blocking operations. Python sends browser operation requests, TypeScript executes them and returns results. The interaction is transparent to the end user and supports concurrent task execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture improves performance, enhances the precision of element interactions, and enables advanced capabilities like dynamic DOM filtering, viewport-aware snapshots, and in-browser SoM rendering. It avoids the limitations of Python-only implementations, such as high latency, limited access to browser internals, and complex image processing logic. By delegating browser tasks to the native execution context, Eigent ensures a robust foundation for agent-based enterprise automation.&lt;/p&gt;

&lt;p&gt;During multi-agent execution in enterprise automation scenarios, browser-based automation offers a natural advantage in process visibility. Every step is transparent, inspectable, and easy to debug, making it far more practical for complex and evolving workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Test Minimax M2.1 in&lt;/strong&gt; Real-World Enterprise Tasks &lt;strong&gt;with Eigent browser automation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We have tested Eigent with Minimax M2.1 to automate sales processes &lt;strong&gt;using Eigent browser automation capabilities&lt;/strong&gt;. The tasks for agents are to automate various stages of the real-world sales cycle, including &lt;strong&gt;Lead Capture &amp;amp; Creation&lt;/strong&gt;, &lt;strong&gt;Qualification &amp;amp; Pipeline Management&lt;/strong&gt;, &lt;strong&gt;Quotation&lt;/strong&gt;, &lt;strong&gt;Negotiation&lt;/strong&gt;, &lt;strong&gt;Closing&lt;/strong&gt;, and &lt;strong&gt;Product Management&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Across experimental runs, Minimax M2.1 consistently shows three key strengths:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Handles complex page structures well, including iframes and nested elements:&lt;/strong&gt; It can reliably find the right content and buttons, even in complex layouts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks its own actions to stay accurate and short steps:&lt;/strong&gt; It uses a feedback loop to correct mistakes and make sure the task is really done right.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uses tools efficiently and flexibly:&lt;/strong&gt; It avoids unnecessary steps and knows how to combine tools smartly when needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Task:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We have a new contact at Global Media - Jennifer Martinez (&lt;a href="mailto:jennifer.m@globalmedia.com"&gt;jennifer.m@globalmedia.com&lt;/a&gt;) is their new Senior Marketing Manager. Add her to our Salesforce and make sure she’s connected to the right company."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/NLuy4gZ-vsA"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;In this task, &lt;strong&gt;Minimax M2.1&lt;/strong&gt; was required to operate within a highly complex Salesforce interface to complete a realistic business workflow: adding a new contact, &lt;strong&gt;Jennifer Martinez&lt;/strong&gt; (Senior Marketing Manager), to &lt;strong&gt;Global Media&lt;/strong&gt;, and ensuring she was correctly associated with the appropriate company account. This involved navigating multiple UI layers, identifying the correct entry points, creating the contact, populating key fields, and validating the account linkage.&lt;/p&gt;

&lt;p&gt;The results show that &lt;strong&gt;Minimax M2.1&lt;/strong&gt; executed every step &lt;strong&gt;accurately and without error&lt;/strong&gt;, with no mis-clicks or workflow breakdowns. This demonstrates the model’s strong capability in understanding complex enterprise UIs, planning multi-step actions, and reliably executing end-to-end tasks—highlighting its robustness in real-world, browser-based enterprise automation scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Minimax M2.1 Improves Task Performance
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Minimax M2.1&lt;/strong&gt; emerges as a strong choice for autonomous enterprise agents. Built to excel in real-world complex workflows, M2.1 consistently handles long-horizon, multi-step tasks with reliability. It delivers a compelling combination of performance, efficiency, and versatility, making it a practical option for scaling agent-based automation in enterprise environments. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enhanced Reasoning and Workflow Continuity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the key strengths of M2.1 lies in its systematic improvements for real-world complex tasks. Compared to its predecessor, M2.1 produces more concise and efficient reasoning chains, improved responsiveness, and reduced token consumption—resulting in smoother execution of continuous workflows such as agentic task automation. &lt;/p&gt;

&lt;p&gt;Rather than relying on simple conversational history, Minimax M2.1 is designed for better context management across multiple steps. This enhanced structured reasoning helps maintain logical continuity during multi-step function calls and reduces the chance of errors later in the workflow, especially in browser-driven task sequences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent and Tool Generalization Capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;M2.1 exhibits strong performance across a variety of agent scaffolding frameworks and tooling environments. It generalizes reliably with different tools and supports integrated workflows, enhancing its utility in real office and enterprise automation tasks. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Robustness in Long-Horizon Planning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enterprise automation often involves uncertainty—handling dynamic UI states, load delays, and unexpected interactions. Through its improved reasoning and execution efficiency, Minimax M2.1 demonstrates resilience in longer task sequences, making it well suited for agentic automation systems that require stability over many steps.&lt;/p&gt;

&lt;p&gt;While the gap between top-tier models can be small for standard queries, in scenarios where state retention, complex instruction following, and error recovery are crucial, Minimax M2.1’s enhancements provide a practical foundation for platforms like Eigent. Its ability to produce concise, efficient reasoning and maintain coherent task-level logic makes it an effective choice for complex, multi-step enterprise workflows. &lt;/p&gt;

&lt;p&gt;Eigent is fully open-source, and we invite developers, researchers, and enterprise teams to explore, extend, and contribute:&lt;/p&gt;

&lt;p&gt;👉 GitHub: &lt;a href="https://github.com/eigent-ai/eigent" rel="noopener noreferrer"&gt;https://github.com/eigent-ai/eigent&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Huggingface: &lt;a href="https://huggingface.co/MiniMaxAI/MiniMax-M2.1" rel="noopener noreferrer"&gt;https://huggingface.co/MiniMaxAI/MiniMax-M2.1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 Join our Discord community: &lt;a href="https://discord.camel-ai.org/" rel="noopener noreferrer"&gt;https://discord.camel-ai.org&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>eigent</category>
    </item>
    <item>
      <title>Brainwash Your Agent: How We Keep The Memory Clean</title>
      <dc:creator>CAMEL AI</dc:creator>
      <pubDate>Fri, 21 Nov 2025 11:44:47 +0000</pubDate>
      <link>https://forem.com/camel-ai/brainwash-your-agent-how-we-keep-the-memory-clean-24nn</link>
      <guid>https://forem.com/camel-ai/brainwash-your-agent-how-we-keep-the-memory-clean-24nn</guid>
      <description>&lt;p&gt;Written by Hesam&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Three techniques to cut context bloat, keep what matters, and dump the rest.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Your agent only forgets because you let it. You’re actually more in control of the agent’s intelligence than you think, and context engineering is the delicious secret sauce which allows that.&lt;/p&gt;

&lt;p&gt;Context engineering has been one of the major focuses of the engineering team at CAMEL. &lt;strong&gt;We are constantly thinking about ways to give control over the context to the developers&lt;/strong&gt;, allowing them to optimize the agent’s memory for maximum performance and efficiency. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyf3l59bpyep7gwwctkau.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyf3l59bpyep7gwwctkau.png" alt=" " width="800" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Context Engineering Doesn’t Have to Be Complex&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It may sound like a complex term, but “context engineering” is actually founded on a very simple idea: Only feed the agent what is necessary to achieve its goal.&lt;/p&gt;

&lt;p&gt;As you pollute the context with low-signal redundant information, the model’s intelligence suffers a setback. This context rot hurts the agent’s abilities in various ways, e.g. recalling critical information, choosing the right tools, or following explicit prompt instructions. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can read &lt;a href="https://www.dbreunig.com/2025/06/22/how-contexts-fail-and-how-to-fix-them.html" rel="noopener noreferrer"&gt;this blog post&lt;/a&gt; that explains how and why long contexts fail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This blog post is not an explanation of context engineering techniques. There are many high-quality articles out there explaining the creative ways companies engineer their agent’s context, and I don’t intend to repeat the same information. But as you read more about context engineering and how it is practically applied in the industry, you begin to see very simple techniques you can easily learn and apply to your own agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Matters
&lt;/h3&gt;

&lt;p&gt;because if you develop agents, or if you work with them, you must take seriously the methods and techniques to optimize how they perceive the context. Some of these techniques are actually low-hanging fruits. They don’t require extensive implementation and change to your working agents, but they’re just as effective in the performance and cost as the backend LLM that fuels your agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  In This Blog Post
&lt;/h3&gt;

&lt;p&gt;…we explain &lt;strong&gt;three of the techniques&lt;/strong&gt; implemented in the CAMEL framework that keep agent memory clean and context sharp: &lt;strong&gt;Context Summarization, Workflow Memory,&lt;/strong&gt; and &lt;strong&gt;Tool Output Caching.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Yes, simple and intuitive in principle, and intricate in implementation.&lt;/p&gt;

&lt;p&gt;You’ll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The real problems we hit with agentic workflows&lt;/li&gt;
&lt;li&gt;The methods we have used to optimize the context&lt;/li&gt;
&lt;li&gt;What remains to be done &lt;strong&gt;(and how you can help)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We have also opened a number of issues in the CAMEL repo so you can jump in, challenge yourself, ship fixes, and make agents remember better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context Summarization: Keeping What Matters
&lt;/h2&gt;

&lt;p&gt;Let’s imagine a scenario which might sound familiar to you. You prompt your agent to build a simple text-to-emoji app that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;takes an input text from the user,&lt;/li&gt;
&lt;li&gt;calls a text-to-image model to create an emoji,&lt;/li&gt;
&lt;li&gt;shows it to the user,&lt;/li&gt;
&lt;li&gt;stores it in a PostgreSQL database,&lt;/li&gt;
&lt;li&gt;and finally, handle the auth so users can login to their account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent builds a perfect app, the UI looks good enough, the emoji images look good, and ooops… the images are not stored in the database, there has to be a bug. So the agent starts searching the web to find why this is not working, checks the versions, and even takes a look at the official documentation. The process takes so much longer than you expected, and now a simple sub-task has become the main problem of the agent and has been taking 10 minutes to solve. &lt;/p&gt;

&lt;p&gt;The agent does find the root cause in the end, but there’s a problem here, and let’s look at the hypothetical context of our hypothetical agent to see what’s wrong:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaihi0ds8do1xejhf540.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyaihi0ds8do1xejhf540.png" alt=" " width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A simple bug-fix or “side quest” may completely overtake the purpose and the token consumption of your agent. If you have used coding agents such as Cursor or Claude Code, you most definitely have experienced this derailment, and it is just as true for general purpose agents as well.&lt;/p&gt;

&lt;p&gt;This is the purpose of context summarization. It takes the conversation, and breaks it down to its most critical components, focusing on what matters, throwing in the bin what doesn’t.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffe2ew9tbxfupbkjsqiq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffe2ew9tbxfupbkjsqiq6.png" alt=" " width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now context summarization is a common context management technique that is used in a number of situations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent has used the majority (e.g. 80%) of its context window.&lt;/li&gt;
&lt;li&gt;The context has been derailed by side-quests and you want to refresh it.&lt;/li&gt;
&lt;li&gt;You want to reference this session in another run, so you need a summary of what happened.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Summarization is a Swiss knife that you can whip out in various scenarios, and it’s a must-have in your agentic kit.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Context Summarization is Used in CAMEL
&lt;/h3&gt;

&lt;p&gt;CAMEL provides &lt;strong&gt;three main approaches&lt;/strong&gt; to context summarization:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automatic token-based summarization&lt;/strong&gt;: The ChatAgent monitors token usage and automatically triggers summarization.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual summarization API&lt;/strong&gt;: Explicit call by the developer, so you have full control even if you want to summarize the context when you see fit. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Toolkit-based summarization&lt;/strong&gt;: Agent-accessible tool for summarizing the full context, and also searching for the messages that have been summarized.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even though these approaches work slightly differently, the core summarization process follows the same pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj539mnp776obh2oh6kw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj539mnp776obh2oh6kw4.png" alt=" " width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now among this workflow, what’s the most critical part? Of course, it’s the prompt. The summarization prompt is what tells the agent how to summarize the context, what things to focus on, and how to handle uninformative bits. &lt;strong&gt;The prompt is what truly makes or breaks this method.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is an evolving bit for us, and we’re constantly looking for ways to improve prompts for maximum clarity and best outcomes—even though we allow developers to also use their custom prompts. We instruct the agent to extract key information from the conversation history, including: the main request of the user, the work that still needs to be done (necessary if you want to pass this to a fresh conversation), the current work that is being done, etc. In case of tokenlimit context summarization, we also pass a minimal list of user messages, which don’t consume too many tokens, but are highly informative, and &lt;strong&gt;reduce our reliance on the LLM summarization&lt;/strong&gt; to keep the full picture in mind (after all, LLM summarizations could be unreliable, or miss some of the bits, so we have to take cautionary measures.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/camel-ai/camel/issues/3371" rel="noopener noreferrer"&gt;[Enhance] tokenlimit Summarize up to the Last User Message · Issue #3371 · camel-ai/camel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/camel-ai/camel/issues/3372" rel="noopener noreferrer"&gt;[Enhance] Context Summarizer Toolkit Prompt · Issue #3372 · camel-ai/camel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/camel-ai/camel/issues/3373" rel="noopener noreferrer"&gt;[Enhance] ChatAgent Summarize Prompt · Issue #3373 · camel-ai/camel&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/camel-ai/camel/issues/3374" rel="noopener noreferrer"&gt;[Enhance] Unify Context Summarization Backend · Issue #3374 · camel-ai/camel&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflow Memory: Past Experiences Matter
&lt;/h2&gt;

&lt;p&gt;You ask your agent to get a list of the top available free books on ML mathematics and then create a CSV of each book, a description, subject, prerequisites, link, etc. The agent searches the web, finds a few titles, but can’t read some of the books available on &lt;a href="http://archive.org" rel="noopener noreferrer"&gt;archive.org&lt;/a&gt; website. It tries a few things, searches for a while, and finally, figures out a way to do this successfully. The agent has spent five minutes figuring out what it was doing wrong, which is perfectly fine for an agentic run, but it’s a problem if we need to do a similar task again in the future, especially if this is a recurring workflow. &lt;/p&gt;

&lt;p&gt;Workflow memory solves this problem with a simple idea: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Record what you learned about solving this task, so you have a clear strategy for similar problems in the future.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Intricate Details That Matter
&lt;/h3&gt;

&lt;p&gt;Behind the scenes, workflow memory is a wrapper around the context summarization. The key is to keep this summary &lt;strong&gt;general enough&lt;/strong&gt; so it can be &lt;strong&gt;useful in similar tasks&lt;/strong&gt;, but also &lt;strong&gt;detailed enough&lt;/strong&gt; to be beneficial and helpful &lt;strong&gt;in practice&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Here is a list of what we ask the agent to summarize and the prompt used to describe each:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Task title: A short, generic title of the main task (e.g. Remind weekly meetings on Slack)&lt;/li&gt;
&lt;li&gt;Task description: One-paragraph summary of what the user asked for. No implementation details; just the outcome the user wants.&lt;/li&gt;
&lt;li&gt;Solving steps: Numbered, ordered actions the agent took to complete the task. Each step starts with a verb and is generic enough to be repeatable.&lt;/li&gt;
&lt;li&gt;Tools: Bullet list of tool calls or functions calls used. For each: name → what it did → why it was useful (one line each). This field is explicitly for tool call messages or the MCP servers used.&lt;/li&gt;
&lt;li&gt;Failure and recovery strategy: [Optional] Bullet each incident with symptom, cause (if known), fix/workaround, verification of recovery. Leave empty if no failures.&lt;/li&gt;
&lt;li&gt;Notes and observations: [Optional] Anything not covered in previous fields that is critical to know for future executions of the task. Leave empty if no notes. Do not repeat any information, or mention trivial details. Only what is essential.&lt;/li&gt;
&lt;li&gt;Tags: 3-10 categorization tags that describe the workflow type, domain, and key capabilities. Use lowercase with hyphens. Tags should be broad, reusable categories to help with semantic matching to similar tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Loading the Right Workflows
&lt;/h3&gt;

&lt;p&gt;How does the agent find the right workflow memory for the current task? We help the agents by three methods of filtering:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the developer can pass a specific session that they find most relevant to the current task.&lt;/li&gt;
&lt;li&gt;the workflow memories are saved with the role_name of the agent as the filename (e.g. researcher_agent_workflow.md), and the same agent can find workflows previously saved by itself, which is most likely the one that’s needed.&lt;/li&gt;
&lt;li&gt;The agent is provided by the full list of workflow information: the title, concise description, and tags of all workflows. Then it can choose a maximum of N workflows which are most relevant. This selection procedure is then wiped out of memory to save context.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As you might have noticed, we have refrained from RAG to retrieve the workflows. This was a conscious decision to avoid the unnecessary complexity and uncertainty that RAG brings, which is absolutely not needed for this use case. If we’re at a point, in which we have so many workflow[.md] files that we need RAG, a critical principle of workflow memory is defeated: &lt;strong&gt;to have a handful of dynamic external memory files for each agent&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflows in Research
&lt;/h3&gt;

&lt;p&gt;Workflow memory is a new feature, and naturally, there’s much to learn and improve about it. Its effectiveness has been experimented in research and benchmarked in a &lt;a href="https://arxiv.org/pdf/2409.07429" rel="noopener noreferrer"&gt;paper&lt;/a&gt; in which the authors report a significant gain in web-navigation tasks, which you can read and learn more about this technique.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gtfp6ria84f9ti4d2ux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gtfp6ria84f9ti4d2ux.png" alt=" " width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are multiple areas of improvement when it comes to workflows, which again, have been turned into bite-sized issues for interested developers:&lt;br&gt;
&lt;a href="https://github.com/camel-ai/camel/issues/3375" rel="noopener noreferrer"&gt;[Enhance] Workflow Memory Summarization Prompt · Issue #3375 · camel-ai/camel&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Tool Output Caching (A Cautionary Tale)
&lt;/h2&gt;

&lt;p&gt;Research papers only cherry-pick what works best. But not us. Tool output caching was another effort by CAMEL developers to keep the agentic context clean, but was later reverted. The reason is the concern for information loss and performance degradation. While this is not a “failed” attempt and simply needs more refinement and testing, it pays off to learn about it as a cautionary tale of how over-engineering the context for the sake of “efficiency” may hinder the agent’s intellect.&lt;br&gt;
This represents a foundational challenge of memory management: &lt;strong&gt;token efficiency vs accuracy.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Tool Outputs are Boring!
&lt;/h3&gt;

&lt;p&gt;Well not exactly, but they are a challenge to handle. Tools are an essential part of what makes an agent, an agent. However, while tool outputs are absolutely necessary, they’re not usually useful after they serve their purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Agent searches the web
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;camel.toolkits&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SearchToolkit&lt;/span&gt;
&lt;span class="n"&gt;tool_result_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SearchToolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search_google&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AI agent frameworks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Returns: 4,250 characters of search results with snippets, URLs, metadata
&lt;/span&gt;
&lt;span class="c1"&gt;# Agent reads a large file
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;camel.toolkits&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FileToolkit&lt;/span&gt;
&lt;span class="n"&gt;tool_result_2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FileToolkit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;documentation.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Returns: 8,100 characters of markdown documentation
&lt;/span&gt;
&lt;span class="c1"&gt;# Agent makes 10 more tool calls
# Each subsequent LLM call includes all previous tool results
# → 60,000+ tokens of tool output in context
# → Context window polluted by stale tool data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tool results are often needed once, but stay in the context forever. This is especially a time-bomb in long-horizon real world tasks, in which the agent will make numerous tool calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Saving the Tool Outputs Outside Context
&lt;/h3&gt;

&lt;p&gt;One way to handle this is to store tool outputs outside the LLM's context (like saving them to a markdown file on disk) and just keep an ID reference in context. That way, if you need the full output later, you can retrieve it by the ID.&lt;/p&gt;

&lt;p&gt;CAMEL’s implementation of this strategy is to simply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor tool result sizes and identify if length &amp;gt;2000 chars&lt;/li&gt;
&lt;li&gt;Keep latest tool output full&lt;/li&gt;
&lt;li&gt;Cache older verbose outputs&lt;/li&gt;
&lt;li&gt;Replace full output with reference&lt;/li&gt;
&lt;li&gt;Include preview (first 160 chars)&lt;/li&gt;
&lt;li&gt;Provide retrieval instructions so the agent can load the full outputs if necessary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In theory this would drastically save the token consumption. You must know, if you haven’t been exposed to agents any more than courses and tutorial codes, that tools are more complicated than a get_weather API. Web navigation tools like Playwright or browser automation agents can return extremely large outputs, maybe even the entire DOM of a webpage, which can easily surpass 10,000 of tokens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7fjbstwixwdcuudhfaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx7fjbstwixwdcuudhfaa.png" alt=" " width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A Pinch of Salt.
&lt;/h3&gt;

&lt;p&gt;Like any context engineering technique, you must be careful not to pay for extra efficiency with a drop of accuracy. Here’s some ways the tool output caching might have negative effect.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Information loss:&lt;/strong&gt; Agent processes verbose tool output → system caches it and replaces with a preview + reference → agent later sees the preview and doesn’t think it needs the full output → makes decision based on incomplete data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive Load on Agent:&lt;/strong&gt; Agent must recognize when/if full output is needed, call the retrieve function at the right time, track which cache IDs relate to which output, and also decide whether the preview is sufficient or not. &lt;strong&gt;This is an extra cognitive load that is not directly related to solving the user-provided task.&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We believe the complete, fool-proof implementation of the tool output caching can be quite valuable. For the curious reader, we have created an issue to bring this feature back to life, and make sure it serves the purpose of context hygiene. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/camel-ai/camel/issues/3376" rel="noopener noreferrer"&gt;[Enhance] Revive Tool Output Caching · Issue #3376 · camel-ai/camel&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The Future Road Ahead
&lt;/h1&gt;

&lt;p&gt;While these methods are backed by research and common industry best-practices, we make it our mission to ensure they have substantial gains in the CAMEL repository. We commit to this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implementing new techniques to optimize the Agent’s memory.&lt;/li&gt;
&lt;li&gt;Fix and improve the existing methods.&lt;/li&gt;
&lt;li&gt;Benchmark the existing methods and raise the bar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What’s particularly fascinating about context engineering and memory management, &lt;strong&gt;is the abundance of creative and novel techniques&lt;/strong&gt; that is made possible by how new this field is.&lt;/p&gt;

&lt;p&gt;The fact that an agent can become so much smarter and more efficient, not by changing the LLM or spending more money and compute, but by simply changing how the agent views the conversation and its memory is managed, is pretty thrilling.&lt;/p&gt;

&lt;p&gt;What was covered in this blog post was only parts of the effort CAMEL has put into better memory of the agents. Our wish is that through this blog, you are &lt;strong&gt;more inspired&lt;/strong&gt; to work on this section of AI, and maybe even use this opportunity to &lt;strong&gt;start your open-source arc&lt;/strong&gt; by opening PRs for each issue, review and contribute to the ones opened by others, or create new issues if you find ways to fix/improve these techniques.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>opensource</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How CAMEL Rebuilt Browser Automation: From Python to TypeScript for Reliable AI Agents</title>
      <dc:creator>CAMEL AI</dc:creator>
      <pubDate>Thu, 13 Nov 2025 13:47:04 +0000</pubDate>
      <link>https://forem.com/camel-ai/how-camel-rebuilt-browser-automation-from-python-to-typescript-for-reliable-ai-agents-2893</link>
      <guid>https://forem.com/camel-ai/how-camel-rebuilt-browser-automation-from-python-to-typescript-for-reliable-ai-agents-2893</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2or99ytzrtto8d9rngqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2or99ytzrtto8d9rngqm.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
During the development of the CAMEL AI framework, we have been using browser automation tools to enable AI Agents to complete complex web tasks. The initial implementation was pure Python, based on Playwright Python bindings. However, as use cases increased, we gradually discovered some unavoidable pain points.&lt;/p&gt;

&lt;p&gt;The first issue was unstable snapshot quality. AI Agents need to understand web content to make correct decisions, and at that time we could only traverse the DOM tree and extract element information using JavaScript scripts ourselves. This process was not only error-prone but also frequently missed important interactive elements.&lt;/p&gt;

&lt;p&gt;The second pain point was the contradiction between cost and speed. When page content was complex, we needed to provide AI with visualized screenshots to help understand the layout, but the cost of image tokens was several times that of text, and processing speed was much slower. While pure text snapshots were cheap and accurate, they were prone to errors when encountering complex visual layouts. We needed a mechanism that could intelligently switch between the two.&lt;/p&gt;

&lt;p&gt;The third issue was the reliability of form filling. Real-world web forms come in all shapes and sizes: some input boxes are hidden in multiple layers of nesting, some dropdown menus are dynamically loaded, and some date pickers only show the actual input box after clicking. Relying purely on Playwright’s basic APIs made it difficult to handle these edge cases.&lt;/p&gt;

&lt;p&gt;So we decided to rethink this problem from an architectural level.&lt;/p&gt;

&lt;h2&gt;
  
  
  We decided to refactor to TypeScript, but why?
&lt;/h2&gt;

&lt;p&gt;CAMEL is a pure Python framework, and introducing Node.js would increase dependency complexity. However, after in-depth research, we found this was almost an inevitable choice.&lt;/p&gt;

&lt;p&gt;Playwright is essentially developed in TypeScript, and the Node.js version is a “first-class citizen”. Many advanced features are implemented first in Node.js and then ported to Python bindings. For example, the &lt;code&gt;_snapshotForAI()&lt;/code&gt; API we mentioned earlier can generate AI-optimized DOM snapshots, automatically handling ARIA attributes, element hierarchies, interactivity judgments, and other complex logic. If using pure Python, we would need to write over a thousand lines of JavaScript code ourselves to implement these features, and it would be difficult to guarantee quality.&lt;/p&gt;

&lt;p&gt;More importantly, browsers themselves run in a JavaScript environment. When we need to perform advanced operations within a page—such as detecting whether elements are occluded or dynamically injecting visual markers—executing directly in the browser’s JavaScript context is much more efficient than controlling indirectly from the Python side through the CDP protocol.&lt;/p&gt;

&lt;p&gt;So the final architecture is as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TypeScript layer handles browser interaction&lt;/strong&gt;: Manages all logic related to Playwright and DOM operations, directly calling native APIs for optimal performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python layer handles AI orchestration&lt;/strong&gt;: Manages LLM calls, Agent decision-making, and task flow control, which is Python ecosystem’s strength.&lt;/p&gt;

&lt;p&gt;The two communicate asynchronously through WebSocket, without blocking each other. The Python side initiates a browser operation request, the TypeScript side executes and returns the result, and the entire process is transparent to the user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjy3njs872bpnuuthqj9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjy3njs872bpnuuthqj9j.png" alt=" " width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Advantage&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Legacy Python Approach&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;TypeScript Framework&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Benefits&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Browser API Integration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python → JS bridge with overhead&lt;/td&gt;
&lt;td&gt;Direct native Playwright API calls&lt;/td&gt;
&lt;td&gt;• Lower latency• Better performance• Access to latest features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Asynchronous Operations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Limited async support&lt;/td&gt;
&lt;td&gt;Native async/await throughout&lt;/td&gt;
&lt;td&gt;• Non-blocking operations• Better concurrency• Efficient resource usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Element Interaction&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom JavaScript injection&lt;/td&gt;
&lt;td&gt;Native Playwright methods&lt;/td&gt;
&lt;td&gt;• More reliable• Better error handling• Cleaner code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-time Events&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Polling-based updates&lt;/td&gt;
&lt;td&gt;WebSocket event streaming&lt;/td&gt;
&lt;td&gt;• Instant updates• Lower resource usage• Better responsiveness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runtime type checking only&lt;/td&gt;
&lt;td&gt;Compile-time type checking&lt;/td&gt;
&lt;td&gt;• Catch errors early• Better IDE support• Safer refactoring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multiple language contexts&lt;/td&gt;
&lt;td&gt;Single runtime environment&lt;/td&gt;
&lt;td&gt;• Low-latency calls• Lower CPU usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Browser Features&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Limited to Python bindings&lt;/td&gt;
&lt;td&gt;Full Playwright API access&lt;/td&gt;
&lt;td&gt;• Playwright _SnapShotForAI• Advanced debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cross-language error propagation&lt;/td&gt;
&lt;td&gt;Native error boundaries&lt;/td&gt;
&lt;td&gt;• Clearer stack traces• Better error recovery• Easier debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Multi-Modal Output: Finding Balance Between Cost and Accuracy
&lt;/h2&gt;

&lt;p&gt;After having stable snapshot generation capabilities, we began thinking about the next question: when should we use text, and when should we use images?&lt;/p&gt;

&lt;p&gt;In actual use, we found that pure text snapshots are sufficient in most cases. For example, filling out a login form, the AI only needs to know “here is a username input box ref=e123, a password input box ref=e124, and a submit button ref=e125” to complete the task accurately. Text tokens are cheap, processing is fast, and information is very precise.&lt;/p&gt;

&lt;p&gt;But there are also scenarios where pure text loses critical information. For example, a complex dashboard with dozens of buttons and charts might have a text snapshot of thousands of lines, making it difficult for AI to understand which button is in which area. Or a visual design task like “move the blue button to the upper right corner” simply cannot be completed without a screenshot.&lt;/p&gt;

&lt;p&gt;So after decoupling all operational actions into primitive tools, we also provide &lt;code&gt;browser_get_page_snapshot&lt;/code&gt; and &lt;code&gt;browser_get_som_screenshot&lt;/code&gt; as optional actions to the agent, allowing the agent to freely switch between these two modes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Snapshot Optimization: Making AI See More Precisely
&lt;/h2&gt;

&lt;p&gt;Even with &lt;code&gt;_snapshotForAI()&lt;/code&gt;, we found there was still room for optimization in the generated snapshots.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 1: Interference from Decorative Elements
&lt;/h3&gt;

&lt;p&gt;Playwright snapshots include all ARIA-accessible elements, including many purely decorative icons, dividers, and decorative text. For example, a navigation bar might have 50 elements, but only 5 links are actually clickable, the rest are decorative. This noise distracts the AI’s attention and increases reasoning costs.&lt;/p&gt;

&lt;p&gt;Our approach was to add intelligent filtering logic on the Node.js side. By parsing the DOM hierarchy relationships through &lt;code&gt;snapshot-parser.ts&lt;/code&gt;, we identify the true “parent elements”. For example, if a button contains nested icons and text, we only keep the outermost button element and filter out the decorative child elements inside. This filtering is implemented through &lt;code&gt;filterClickableByHierarchy()&lt;/code&gt;, with rules including: if a link tag contains an img, remove the img and keep only the link; if a button contains generic elements, remove the generic and keep the button.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 2: Meaningless Off-Screen Elements
&lt;/h3&gt;

&lt;p&gt;Web pages are usually very long, and users can currently only see a small portion (viewport). But snapshots by default include all elements of the entire page, including parts that require scrolling to see. This is noise for AI—it shouldn’t try to click a button that hasn’t been scrolled to yet.&lt;/p&gt;

&lt;p&gt;We added a &lt;code&gt;viewportLimit&lt;/code&gt; parameter. When enabled, only elements within the current viewport are returned. This filtering is done on the browser side, calling the &lt;code&gt;isInViewport()&lt;/code&gt; function to check whether the element’s &lt;code&gt;getBoundingClientRect()&lt;/code&gt; is within the visible area. This way, the snapshot the AI sees is more focused, and decision quality is higher.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 3: Misleading from Element Occlusion
&lt;/h3&gt;

&lt;p&gt;This is a more subtle problem. Some elements exist in the DOM tree but are blocked by other elements, so users can’t see or click them. If we include these elements in the snapshot, the AI might try to click and then fail.&lt;/p&gt;

&lt;p&gt;In SoM screenshot mode, we implemented occlusion detection. Through the &lt;code&gt;checkElementVisibilityByCoords()&lt;/code&gt; function, for each element’s center point we call &lt;code&gt;document.elementsFromPoint(x, y)&lt;/code&gt;, a native browser API that returns all elements at that coordinate point, sorted by z-index from high to low. If our target element is not at the top layer, it means it’s occluded. We draw dashed boxes (instead of solid lines) for such elements, or filter them out directly.&lt;/p&gt;

&lt;p&gt;These optimizations all benefit from the TypeScript architecture. &lt;code&gt;document.elementsFromPoint()&lt;/code&gt; is implemented in native browser C++, with extremely high performance. If on the Python side, we could only get coordinate data and then use inefficient algorithms to judge ourselves, which would be both slow and inaccurate.&lt;/p&gt;




&lt;h2&gt;
  
  
  SoM Screenshot: Why Inject in Browser Rather Than Post-Process?
&lt;/h2&gt;

&lt;p&gt;SoM screenshots present an interesting design challenge. We need to mark all interactive elements in screenshots, drawing a box and number for each element.&lt;/p&gt;

&lt;p&gt;The most intuitive approach is: take a screenshot first, then use Python’s PIL library to draw boxes on the image. The pure Python version did exactly this. But we found this solution has several problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Poor visual quality&lt;/strong&gt;. PIL is CPU software rendering, and the drawn lines have jagged edges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-platform inconsistency&lt;/strong&gt;. PIL depends on system font libraries, and the font paths are different on Windows, macOS, and Linux, often resulting in “cannot find arial.ttf” errors, ultimately having to use ugly default fonts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most importantly&lt;/strong&gt;, when connecting to an existing browser in CDP mode, for screens with different resolutions, the zoom ratio needs to be adjusted to accurately map element coordinates to the correct positions on the image, which is very cumbersome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Large data transmission&lt;/strong&gt;. The Python version needs to first execute a JavaScript script to collect all element information, including coordinates, attributes, metadata, etc., then serialize this data into JSON and send it back to Python. For a page with huge amount of elements, this JSON might contain many redundant fields (such as disabled, checked, expanded, etc., which SoM doesn’t need at all).&lt;/p&gt;

&lt;p&gt;The TypeScript version’s approach is: &lt;strong&gt;directly inject DOM elements as markers in the browser, then take a screenshot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The specific process is as follows: execute JavaScript in the browser context through &lt;code&gt;page.evaluate()&lt;/code&gt;, create an &lt;code&gt;overlay&lt;/code&gt; div covering the entire page, with z-index set to the highest value. Then for each element that needs to be marked, create a &lt;code&gt;label&lt;/code&gt; div, set borders, background colors, and text, and position it correctly using CSS. Call &lt;code&gt;requestAnimationFrame()&lt;/code&gt; to wait for browser rendering to complete, then take a screenshot. After the screenshot is complete, call &lt;code&gt;page.evaluate()&lt;/code&gt; again to delete this overlay.&lt;/p&gt;

&lt;p&gt;The benefits of this approach are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visual perfection&lt;/strong&gt;. Markers are drawn by the browser rendering engine, with GPU acceleration, anti-aliasing, and perfect font rendering. We can use CSS to implement rounded corners (&lt;code&gt;border-radius&lt;/code&gt;), shadows (&lt;code&gt;box-shadow&lt;/code&gt;), and transparency (&lt;code&gt;opacity&lt;/code&gt;), resulting in very professional visual effects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-platform consistency&lt;/strong&gt;. The browser guarantees rendering consistency, with the same effect regardless of which operating system it runs on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small data transmission&lt;/strong&gt;. We only need to pass in element refs and coordinates, the browser internally completes marker drawing, then returns a simple result object. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intelligent label positioning&lt;/strong&gt;. We implemented the &lt;code&gt;findLabelPosition()&lt;/code&gt; function, which tries multiple positions (above, below, left, right, diagonal of the element), checks for overlap with existing labels, and automatically selects the optimal position. This is very simple to implement on the browser side because we can directly manipulate DOM element positions. If using PIL on the Python side, we would need to maintain a complex coordinate recording system, which is very inefficient.&lt;/p&gt;

&lt;p&gt;Another detail: during visibility detection, we mark completely occluded elements as &lt;code&gt;hidden&lt;/code&gt; status and skip drawing labels directly; partially visible elements are marked as &lt;code&gt;partial&lt;/code&gt;, with dashed boxes and semi-transparent labels. This allows AI to distinguish which elements are truly interactive.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;Our Previous SOM screenshot:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2u28iozct5d6k0mdccw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2u28iozct5d6k0mdccw.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Our Current SOM screenshot:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzwcfckzn4x7vyl9zz6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzzwcfckzn4x7vyl9zz6m.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Other popular open source SOM screenshot:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1qrzmgaw29iemdgjnuk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1qrzmgaw29iemdgjnuk.png" alt=" " width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Tool Registration Mechanism: Avoiding Context Explosion
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnabijb3xxjjhb5tya2fh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnabijb3xxjjhb5tya2fh.png" alt=" " width="800" height="1064"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Early versions had a hidden performance issue: SoM screenshots were saved in the agent’s context. If the Agent needed to take multiple screenshots (such as browsing multiple pages), context usage would grow rapidly.&lt;/p&gt;

&lt;p&gt;Our solution is to require the agent to write instructions as prompts when calling the &lt;code&gt;browser_get_som_screenshot&lt;/code&gt; tool, allowing the agent to leave corresponding descriptions in the context, while the image itself does not occupy the agent’s context.&lt;/p&gt;

&lt;p&gt;This optimization requires coordination with CAMEL’s Agent registration mechanism. Through the &lt;code&gt;RegisteredAgentToolkit&lt;/code&gt; base class, we allow the Toolkit to access the Agent instance that registered it. Specifically, when &lt;code&gt;browser_get_som_screenshot&lt;/code&gt; is called, if a registered Agent is detected, the Agent’s &lt;code&gt;astep()&lt;/code&gt; method is automatically called, passing a Message object containing the image path. The Agent internally uses PIL to load the image and passes it to the multimodal LLM for analysis.&lt;/p&gt;

&lt;p&gt;This design achieves clear separation of responsibilities: the Toolkit is responsible for generating screenshots, and the Agent is responsible for analysis and understanding. The connection between them is only through the lightweight interface of file paths.&lt;/p&gt;




&lt;h2&gt;
  
  
  Form Filling Optimization: Dealing with Real-World Complexity
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0gc8wstlxgzxg7mr8lnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0gc8wstlxgzxg7mr8lnc.png" alt=" " width="800" height="783"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Real-world web forms are much more complex than imagined. We encountered various strange scenarios during testing and gradually optimized to the current solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Batch Processing of Multiple Input Boxes
&lt;/h3&gt;

&lt;p&gt;The simplest optimization: allow filling multiple input boxes in one command. When calling &lt;code&gt;browser_type()&lt;/code&gt;, pass a dictionary &lt;code&gt;{ref1: text1, ref2: text2}&lt;/code&gt; to complete it all at once. This avoids multiple round trips containing snapshot changes and reduces the risk of page state changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intelligent Dropdown Menu Detection
&lt;/h3&gt;

&lt;p&gt;Some input boxes are actually disguised dropdown menus. For example, a search box will pop up a suggestion list when you type. Our &lt;code&gt;browser_type()&lt;/code&gt; implementation has a &lt;code&gt;shouldCheckDiff&lt;/code&gt; logic: if the input box type might trigger a dropdown menu (role includes combobox, searchbox, etc.), we capture a snapshot before and after input, then calculate the diff to extract newly appeared option elements. This diff result is returned to the Agent, so the Agent knows “there are now these options to choose from”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Snapshot Difference for Dynamic Content
&lt;/h3&gt;

&lt;p&gt;This function is implemented in &lt;code&gt;getSnapshotDiff()&lt;/code&gt;. The principle is to compare two snapshot texts and find newly added elements of specific types (such as option, menuitem). We use regular expressions to match &lt;code&gt;[ref=...]&lt;/code&gt;, record all refs in the first snapshot, then find newly appeared refs in the second snapshot. This way the AI can see “after clicking this input box, 5 options appeared”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Special Handling for Read-Only Elements
&lt;/h3&gt;

&lt;p&gt;Date pickers are usually a read-only input box that pops up a calendar component after clicking. Our &lt;code&gt;performType()&lt;/code&gt; function first checks the element’s &lt;code&gt;readonly&lt;/code&gt; attribute and &lt;code&gt;type&lt;/code&gt; (date, datetime-local, time, etc.). If it’s this type of element, click it first, wait 500ms, then look for the actual input box in newly appeared elements (matched by placeholder).&lt;/p&gt;

&lt;h3&gt;
  
  
  Nested Input Box Search
&lt;/h3&gt;

&lt;p&gt;Some buttons, after clicking, don’t directly replace the original position but appear in nested child elements. Our strategy is: if &lt;code&gt;fill()&lt;/code&gt; fails on a certain ref, search for &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;textarea&lt;/code&gt;, &lt;code&gt;[contenteditable]&lt;/code&gt;, etc. in its child elements and try to fill. This search uses Playwright’s &lt;code&gt;locator()&lt;/code&gt; API, which supports complex CSS selectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error Recovery Mechanism
&lt;/h3&gt;

&lt;p&gt;All this complex logic is wrapped in try-catch blocks. If a step fails, we record detailed error information (including the element’s tagName, id, className, placeholder, and other debugging information), but don’t throw an exception directly; instead, we try the next strategy. Only when all strategies fail do we return a descriptive error message to the Agent.&lt;/p&gt;

&lt;p&gt;These optimizations were accumulated gradually in actual use. Each time we encountered a form that the Agent couldn’t handle, we analyzed which link had the problem and then made targeted improvements.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Future Plans&lt;/strong&gt;
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Improved Page Snapshots&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A high-quality snapshot is fundamental to the efficiency of browser-use agents. An ideal snapshot should maintain a high signal-to-noise ratio and low redundancy, preserving meaningful information while filtering out noise.&lt;/p&gt;

&lt;p&gt;Current implementations still include numerous empty or generic elements, and the filtering of off-viewport elements remains imprecise. In some cases, invisible or irrelevant nodes are still captured, leading to unnecessary data and potential confusion for the model.&lt;/p&gt;

&lt;p&gt;Future work will focus on optimizing snapshot extraction to ensure that only semantically relevant and visually significant elements are retained. This includes accurate viewport filtering, hierarchical aggregation of non-interactive elements, and enhancing semantic representation for key UI components. The goal is to create a snapshot format that is compact yet information-dense, improving model understanding and token efficiency.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Support for Purely Visual Model Evaluation Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recently, several model providers have introduced purely visual, coordinate-based “computer-use” models, such as Gemini 2.5 Computer Use, which interact with GUIs directly through pixel-level clicks, similar to human users. Under this paradigm, performing computer-use tasks no longer requires complex engineering layers to expose element-level interaction APIs, which significantly simplifies the implementation of GUI interaction for model developers.&lt;/p&gt;

&lt;p&gt;To support this new paradigm, we can provide a simulation and evaluation environment where model-predicted click coordinates can be validated against ground-truth element positions derived from snapshots. This framework would enable accuracy assessment and reinforcement learning for purely visual GUI agents. Such an environment could serve as foundational infrastructure for training and benchmarking vision-based computer-use models, reducing engineering overhead for model developers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reliable Long-Term Memory Paradigm&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Browser-use is a specific form of GUI interaction where an agent operates within a web environment through sequential actions and feedback. As the action sequence grows, the accumulation of intermediate feedback poses challenges: exceeding context length limits, reducing efficiency of historical retrieval, and increasing the risk of information loss.&lt;/p&gt;

&lt;p&gt;This issue is even more pronounced for purely visual models, as visual context lacks structured semantics and cannot be easily indexed or summarized. Building a robust long-term memory paradigm is therefore essential.&lt;/p&gt;

&lt;p&gt;Future efforts will explore mechanisms for efficient retrieval and compression of historical states and feedback, combining semantic summarization, hierarchical caching, and adaptive context reconstruction. The ultimate goal is to enable agents to maintain awareness and continuity over extended sequences, preserving both behavioral traceability and task coherence.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;CAMEL's GitHub: &lt;a href="https://github.com/camel-ai/camel" rel="noopener noreferrer"&gt;https://github.com/camel-ai/camel&lt;/a&gt;&lt;br&gt;
Official Website: &lt;a href="https://www.camel-ai.org/" rel="noopener noreferrer"&gt;https://www.camel-ai.org/&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Thanks to the Community
&lt;/h1&gt;

&lt;p&gt;All of the above refactors are task-motivated. Through extensive testing and collaboration with community members, we gradually developed and implemented these ideas together. Since browser use is a highly engineering-oriented part of Agent era, it can only be continuously improved through rich and diverse testing. We would like to express our gratitude to everyone in the community for their contributions.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>agents</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
