<?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>DEV Community: chowyu</title>
    <description>The latest articles on DEV Community by chowyu (@chowyu12).</description>
    <link>https://dev.to/chowyu12</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3971363%2F1a718455-75dc-463a-940e-b06417e82f97.png</url>
      <title>DEV Community: chowyu</title>
      <link>https://dev.to/chowyu12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chowyu12"/>
    <language>en</language>
    <item>
      <title>How AIClaw 3.7.5 Organizes Agent Chats Around Their Working Directories</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Mon, 12 Oct 2026 00:05:49 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaw-375-organizes-agent-chats-around-their-working-directories-3eak</link>
      <guid>https://dev.to/chowyu12/how-aiclaw-375-organizes-agent-chats-around-their-working-directories-3eak</guid>
      <description>&lt;p&gt;A chat title tells you what you asked. A working directory tells you where the agent is doing the work. When several conversations belong to the same repository, maintaining an additional manual chat group can become another organizational chore.&lt;/p&gt;

&lt;p&gt;AIClaw's desktop sidebar now uses the session's working directory as its primary grouping key. The change shipped in &lt;a href="https://github.com/chowyu12/aiclaw/releases/tag/v3.7.5" rel="noopener noreferrer"&gt;v3.7.5&lt;/a&gt; on October 10. At the time of writing, v3.7.6 is the latest public release; the workspace behavior discussed here was already released in v3.7.5.&lt;/p&gt;

&lt;p&gt;The interesting part is the distinction between a folder's display name, its identity, and the parent-child structure of agent sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let the workspace determine the bucket
&lt;/h2&gt;

&lt;p&gt;The sidebar takes the root sessions currently in the session list and groups those with a working directory into workspace buckets. Sessions without one appear under the ordinary-chat section.&lt;/p&gt;

&lt;p&gt;Channel conversations and scheduled conversations join the same workspace buckets. Small source labels preserve where they came from. Sub-agent sessions remain nested under their parents rather than filling the top-level list with separate entries.&lt;/p&gt;

&lt;p&gt;There is a useful fallback: a session is treated as a nested child only when its parent is present in the list. If the parent is absent, the child can appear at the top level instead of becoming unreachable.&lt;/p&gt;

&lt;p&gt;The previous custom-group controls were removed from the sidebar. Existing group data remains stored. This changes the navigation model without treating old organizational preferences as disposable data.&lt;/p&gt;

&lt;h2&gt;
  
  
  A short name is not an identity
&lt;/h2&gt;

&lt;p&gt;Consider these illustrative directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/work/client-a/service
/work/client-b/service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both are called &lt;code&gt;service&lt;/code&gt;, but they should not become one workspace.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.5/apps/desktop/src/renderer/workspace-buckets.ts" rel="noopener noreferrer"&gt;bucket helper&lt;/a&gt; groups by the stored full path after trimming surrounding whitespace. It derives the short folder name only for display. When names collide, it adds the parent path as secondary information.&lt;/p&gt;

&lt;p&gt;The helper sorts chats by their update timestamps and sorts buckets by their most recent chat. The sidebar then places pinned workspaces ahead of unpinned ones. Pinning records the full path in local storage, so selecting one &lt;code&gt;service&lt;/code&gt; directory does not pin every directory with that name.&lt;/p&gt;

&lt;p&gt;This is string-based identity, not filesystem canonicalization. The grouping helper does not resolve symlinks or normalize all equivalent path spellings. Two stored paths referring to the same underlying directory can remain separate buckets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start the next chat in the right place
&lt;/h2&gt;

&lt;p&gt;The workspace header provides a new-chat action. It passes that bucket's full path into the existing session-creation action and expands the bucket afterward.&lt;/p&gt;

&lt;p&gt;That is a small workflow improvement: after finishing one task in a repository, you can start another conversation there without selecting the directory again.&lt;/p&gt;

&lt;p&gt;Changing or clearing a session's workspace also refreshes the session list immediately. The sidebar can move that conversation to its new bucket rather than waiting for an unrelated reload.&lt;/p&gt;

&lt;p&gt;Search remains global. Its results carry workspace labels, so workspace grouping does not require the user to remember which section to expand before looking for an older conversation.&lt;/p&gt;

&lt;p&gt;These decisions live in &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.5/apps/desktop/src/renderer/views/SessionSidebar.vue" rel="noopener noreferrer"&gt;SessionSidebar.vue&lt;/a&gt; and the &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.5/apps/desktop/src/renderer/store.ts" rel="noopener noreferrer"&gt;renderer store&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workspace actions need precise targets
&lt;/h2&gt;

&lt;p&gt;The workspace menu includes pinning, directory reveal, and archiving the workspace's conversations.&lt;/p&gt;

&lt;p&gt;Directory reveal crosses the desktop bridge with the full path. The &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.5/apps/desktop/src/main/open-file.ts" rel="noopener noreferrer"&gt;host-side handler&lt;/a&gt; requires an existing absolute directory and calls Electron's &lt;code&gt;showItemInFolder&lt;/code&gt;. It reveals the target rather than running its contents.&lt;/p&gt;

&lt;p&gt;Archiving asks for confirmation and includes descendant sessions in the displayed count. The sidebar invokes the existing archive action for each root conversation in the selected bucket. The kernel's session-tree archive behavior includes child agents and stops active work; the conversations can be restored from the archived section in settings.&lt;/p&gt;

&lt;p&gt;This is a conversation operation. It does not delete the workspace directory. It is also a sequence of per-session archive calls, rather than one atomic transaction across the entire bucket.&lt;/p&gt;

&lt;p&gt;Workspace grouping itself does not introduce a filesystem sandbox or additional permission boundary. It makes the execution location easier to navigate; tool authorization remains a separate concern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence at the UI boundary
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.5/scripts/test-workspace-buckets.ts" rel="noopener noreferrer"&gt;pure helper tests&lt;/a&gt; cover same-name directories, ordering, empty workspace handling, Windows-style names, and root paths.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.5/scripts/smoke-work.cjs" rel="noopener noreferrer"&gt;desktop workflow smoke test&lt;/a&gt; exercises the real Vue/preload interface with fixture sessions and mocked host responses. Its workspace checks cover persisted collapse and pin state, global search labels, workspace changes, exact-path reveal, new-chat inheritance, archive cancellation, and preserving other workspaces when archiving one bucket.&lt;/p&gt;

&lt;p&gt;That proves UI and bridge behavior under the fixtures. It is not evidence that every operating system's native file manager was exercised or that every live agent task was archived during the smoke test.&lt;/p&gt;

&lt;p&gt;The v3.7.5 notes report the full local check passing, with 248 tests and 67 chat-interface checks. Those are suite totals, not counts dedicated to workspace navigation. Its &lt;a href="https://github.com/chowyu12/aiclaw/actions/runs/38034018056" rel="noopener noreferrer"&gt;release CI&lt;/a&gt; also completed successfully.&lt;/p&gt;

&lt;p&gt;For a desktop agent, the working directory is already part of the task. Using it to organize conversations gives the sidebar a useful default while retaining separate identities for distinct directories and separate hierarchy for child agents.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was generated by an AI agent and checked against the public AIClaw v3.7.5 source, release notes, and CI result.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How AIClaw 3.7.6 Keeps Web Search Sources Available Beyond the Tool Log</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Sun, 11 Oct 2026 07:06:25 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaw-376-keeps-web-search-sources-available-beyond-the-tool-log-5gck</link>
      <guid>https://dev.to/chowyu12/how-aiclaw-376-keeps-web-search-sources-available-beyond-the-tool-log-5gck</guid>
      <description>&lt;p&gt;A web-search tool can return useful pages while the final answer leaves the reader with no convenient way to inspect them. Expanding an execution log is possible, but it is a poor reading experience when all you want is the original page behind a result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chowyu12/aiclaw/releases/tag/v3.7.6" rel="noopener noreferrer"&gt;AIClaw 3.7.6&lt;/a&gt;, released on October 10, adds a turn-level source list to its desktop chat. This is a shipped feature in that release, rather than a proposal based on newer development code.&lt;/p&gt;

&lt;p&gt;The change builds on existing structured search results. It adds a small UI contract and carries the source data through execution, storage, and history replay.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the reader sees
&lt;/h2&gt;

&lt;p&gt;A reply that has search sources gets a compact source-count button below the answer. Opening it displays a panel on the right with each page's domain, title, and search snippet. A source card opens the original URL in the system browser.&lt;/p&gt;

&lt;p&gt;Multiple searches in the same turn share one list. URLs are deduplicated after removing their fragment identifiers, so two results pointing to different anchors on the same page do not inflate the count. Different query strings remain distinct; this is not a general canonical-URL resolver.&lt;/p&gt;

&lt;p&gt;Ordinary replies without source metadata do not get an empty source section. The panel supports Escape, clicking the backdrop, keyboard focus containment, and returning focus to its trigger when closed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collect the source at execution time
&lt;/h2&gt;

&lt;p&gt;The useful part is where the data comes from. The renderer does not scan the assistant's words and turn every apparent link into a search source.&lt;/p&gt;

&lt;p&gt;A successful MCP tool named &lt;code&gt;web_search&lt;/code&gt; is checked for the expected search-response structure: a query, a provider, and result entries containing title, URL, and snippet. Valid entries become local UI metadata.&lt;/p&gt;

&lt;p&gt;The path through the application is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Successful search response
  → source collector for the outer tool call
  → completed tool item and saved tool message
  → restored history item
  → deduplicated sources for the current turn
  → source panel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.6/tools/claw-agent/internal/tools/sources.go" rel="noopener noreferrer"&gt;collector&lt;/a&gt; lives in Go. It is attached to the call's context and protected by a mutex, rather than stored in a session-wide mutable list. Separate tool calls therefore have separate collections, while nested calls can share their outer call's collection.&lt;/p&gt;

&lt;p&gt;The stored &lt;code&gt;Sources&lt;/code&gt; field is omitted by the model request builder. That avoids adding another copy of the UI metadata to the model request. It does not change the existing search tool output that the model receives in ordinary tool execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Code Mode needs that boundary
&lt;/h2&gt;

&lt;p&gt;In Code Mode, the model runs JavaScript through an &lt;code&gt;exec&lt;/code&gt; tool and calls other tools from the script. The script may print a short summary instead of the full search result.&lt;/p&gt;

&lt;p&gt;Recovering sources only from printed output would miss successful searches whose results were never printed. AIClaw records the source metadata inside the search handler, before the script decides what to output. Nested tools inherit the context carrying the source collector.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.6/tools/claw-agent/internal/agent/sources_test.go" rel="noopener noreferrer"&gt;MCP and persistence test&lt;/a&gt; exercises that distinction: its Code Mode script awaits the search but prints only &lt;code&gt;finished&lt;/code&gt;. The sources still survive saving and loading the session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Older conversations have a narrower recovery path
&lt;/h2&gt;

&lt;p&gt;New tool messages save structured sources directly. Older messages may contain only the search tool's text response.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.6/tools/claw-agent/internal/agent/history.go" rel="noopener noreferrer"&gt;history compatibility code&lt;/a&gt; can recover complete structured responses from saved search output, including suitable &lt;code&gt;exec&lt;/code&gt; output and JSON-encoded strings. It preserves existing metadata when available.&lt;/p&gt;

&lt;p&gt;A missing or truncated result cannot be reconstructed reliably. The implementation leaves it alone instead of inventing sources from the assistant's answer or from unrelated tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search sources are not verified citations
&lt;/h2&gt;

&lt;p&gt;The panel shows pages returned by the search tool. It does not prove that the model used every page, or that a particular sentence is supported by a particular result. Sentence-level citation mapping and factual verification remain separate work.&lt;/p&gt;

&lt;p&gt;Navigation targets are restricted to HTTP and HTTPS URLs without embedded credentials. Titles and snippets render as text, and the domain icons use local letters rather than requesting remote favicons. These checks constrain display and navigation; they do not certify a website's trustworthiness or validate its claims.&lt;/p&gt;

&lt;p&gt;The implementation expects the structured response used by AIClaw's search service. It is not a universal parser for arbitrary provider-native search output or every third-party MCP response.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the release evidence covers
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/chowyu12/aiclaw/releases/tag/v3.7.6" rel="noopener noreferrer"&gt;release notes&lt;/a&gt; report the full local check passing, including 250 renderer tests, 14 basic desktop smoke checks, and 75 work-interface checks. These are suite totals, not counts of tests dedicated solely to sources.&lt;/p&gt;

&lt;p&gt;Source-specific coverage includes direct MCP calls and Code Mode, successful and failed searches, save/load persistence, legacy recovery, URL filtering, deduplication, live events, and panel interaction. The fixture-driven UI checks also exercise plain-text rendering, link opening, and keyboard controls.&lt;/p&gt;

&lt;p&gt;The release separately records real search validation in ordinary mode and Code Mode, with restored history matching live sources. The &lt;a href="https://github.com/chowyu12/aiclaw/actions/runs/38037181772" rel="noopener noreferrer"&gt;release CI run&lt;/a&gt; completed successfully. Neither fixture checks nor successful searches establish that an answer's factual claims are correct.&lt;/p&gt;

&lt;p&gt;For the UI implementation, see &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.6/apps/desktop/src/renderer/views/SearchSources.vue" rel="noopener noreferrer"&gt;SearchSources.vue&lt;/a&gt; and the &lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.6/apps/desktop/src/renderer/turns.ts" rel="noopener noreferrer"&gt;turn-level source selection&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A source list makes an agent's search results easier to inspect. Saving that list as structured metadata makes it useful again when the reader returns to the conversation later.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was generated by an AI agent and checked against the public AIClaw 3.7.6 source, release notes, and CI result.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How AIClaw 3.7.4 Keeps Generated Images Visible After Reopening a Chat</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Sat, 10 Oct 2026 05:41:07 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaw-374-keeps-generated-images-visible-after-reopening-a-chat-3him</link>
      <guid>https://dev.to/chowyu12/how-aiclaw-374-keeps-generated-images-visible-after-reopening-a-chat-3him</guid>
      <description>&lt;p&gt;An agent generates a picture, saves it successfully, and answers with a local filename. The tool did its job. The user still has to find the file to see the result.&lt;/p&gt;

&lt;p&gt;That was the gap behind AIClaw 3.7.4. The release adds inline previews for generated images, including images restored from older conversations. The interesting part was making the result survive the whole trip through tool execution, storage, and history replay.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/chowyu12/aiclaw" rel="noopener noreferrer"&gt;AIClaw&lt;/a&gt; is an open-source desktop agent with an Electron/Vue interface and a Go kernel. Here is how this change fits into that architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small UI contract
&lt;/h2&gt;

&lt;p&gt;The display rules are deliberately simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One image gets a larger preview below the answer.&lt;/li&gt;
&lt;li&gt;Multiple images appear as a row of thumbnails that wraps when needed.&lt;/li&gt;
&lt;li&gt;Clicking a preview opens a large image viewer inside the app.&lt;/li&gt;
&lt;li&gt;Escape, the close button, or a click on the backdrop closes the viewer.&lt;/li&gt;
&lt;li&gt;The filename remains available as an action for opening the local file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The images sit outside the collapsed execution steps. A user can inspect the output without expanding the tool log, while the log remains available for understanding how it was produced.&lt;/p&gt;

&lt;h2&gt;
  
  
  The preview starts with tool metadata
&lt;/h2&gt;

&lt;p&gt;The renderer collects image artifacts from successful tool steps in the current turn. It filters supported image extensions and deduplicates paths within that turn.&lt;/p&gt;

&lt;p&gt;The path comes from the tool result's artifact metadata. We do not scan the assistant's answer for anything that resembles a filename. An assistant can mention an example path or describe a file that was never created; that text alone should not become a preview.&lt;/p&gt;

&lt;p&gt;The flow is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tool execution → artifact paths → saved tool result → restored history item → turn-level image collection → preview&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the Go message structure, the persisted field is small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Artifacts are local UI metadata, omitted from model requests.&lt;/span&gt;
&lt;span class="n"&gt;Artifacts&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"artifacts,omitempty"`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model request builder omits this field. The UI needs it to restore local outputs; it does not need to add those paths to the model's request payload.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug that only appeared in history
&lt;/h2&gt;

&lt;p&gt;A preview working during a live turn is only half the job. Older sessions were saved before artifact paths were included in the stored messages.&lt;/p&gt;

&lt;p&gt;Some of those sessions also used Code Mode. The image tool ran inside the &lt;code&gt;exec&lt;/code&gt; wrapper, so the outer tool result was a string describing the generated file. That string could be plain text or JSON-encoded text, and it could appear among multiple output lines.&lt;/p&gt;

&lt;p&gt;Supporting only the direct image tool missed that case. Reopening the conversation still produced the answer and filename, but no image metadata reached the renderer.&lt;/p&gt;

&lt;p&gt;The compatibility path now handles the standard saved-image result emitted by both &lt;code&gt;generate_image&lt;/code&gt; and &lt;code&gt;exec&lt;/code&gt;. For wrapper output, it attempts to decode each line as a JSON string before matching the known result format.&lt;/p&gt;

&lt;p&gt;This is intentionally narrow: it recognizes the tool's standard Chinese or English success prefix and its generated image filename format. It keeps existing structured metadata when present, deduplicates recovered paths, and avoids extracting files from arbitrary assistant prose or unrelated tools.&lt;/p&gt;

&lt;p&gt;That gives older conversations a recovery path without making every line of chat text a file-discovery mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Load images when they become visible
&lt;/h2&gt;

&lt;p&gt;A long history can contain many generated images. Loading all of them immediately would make reopening that history unnecessarily expensive.&lt;/p&gt;

&lt;p&gt;The Vue component uses &lt;code&gt;IntersectionObserver&lt;/code&gt; to begin reading images when their turn enters the viewport. It then reads each file through the desktop host's media interface.&lt;/p&gt;

&lt;p&gt;Read or decode failures stay local to the affected image. The text answer and other previews remain usable. The large viewer uses the browser's native &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element, with explicit controls for closing it.&lt;/p&gt;

&lt;p&gt;The component is also keyed by session and turn so that switching conversations does not accidentally reuse another turn's media state.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we verified
&lt;/h2&gt;

&lt;p&gt;The release includes regression coverage for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Artifact paths surviving save and load.&lt;/li&gt;
&lt;li&gt;Legacy Code Mode output restoring the image metadata.&lt;/li&gt;
&lt;li&gt;Plain strings, JSON strings, multiple lines, and duplicate paths.&lt;/li&gt;
&lt;li&gt;Unrelated tools and failed steps being excluded from previews.&lt;/li&gt;
&lt;li&gt;Single-image and multiple-image layouts, large-viewer controls, and local image errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The release notes record the full local check passing, 34 work-interface smoke checks, and 13 real-model scenarios passing with no failures or skips. The UI checks use fixtures to exercise display behavior; the real-model scenarios separately cover capabilities including image generation. Those are different kinds of evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it or read the implementation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/chowyu12/aiclaw/releases/tag/v3.7.4" rel="noopener noreferrer"&gt;Download AIClaw 3.7.4&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The relevant code is small enough to follow directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.4/apps/desktop/src/renderer/views/GeneratedImages.vue" rel="noopener noreferrer"&gt;Image preview component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.4/apps/desktop/src/renderer/turns.ts" rel="noopener noreferrer"&gt;Turn-level artifact selection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.4/tools/claw-agent/internal/agent/history.go" rel="noopener noreferrer"&gt;History compatibility logic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/chowyu12/aiclaw/blob/v3.7.4/tools/claw-agent/internal/agent/artifacts_test.go" rel="noopener noreferrer"&gt;Persistence and compatibility tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feature previews local image artifacts produced by tools. Automatically recognizing arbitrary image URLs pasted into a conversation is a separate capability.&lt;/p&gt;

&lt;p&gt;For an agent application, the saved conversation includes more than the assistant's words. Its outputs need enough structure to remain useful when the user returns later.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was prepared with AI assistance and checked against the AIClaw 3.7.4 implementation and release notes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Giving the agent a real browser, indexed by element — AIClaw 3.5 browser tools</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Fri, 25 Sep 2026 00:17:30 +0000</pubDate>
      <link>https://dev.to/chowyu12/giving-the-agent-a-real-browser-indexed-by-element-aiclaw-35-browser-tools-1loj</link>
      <guid>https://dev.to/chowyu12/giving-the-agent-a-real-browser-indexed-by-element-aiclaw-35-browser-tools-1loj</guid>
      <description>&lt;p&gt;AIClaw is a local-first desktop agent. Until 3.5 there was one capability it plainly did not have: letting the model operate a web page the way &lt;a href="https://github.com/browser-use/browser-use" rel="noopener noreferrer"&gt;browser-use&lt;/a&gt; does — not by screen coordinates, but by an indexed list of the page's interactive elements.&lt;/p&gt;

&lt;p&gt;3.5 ships that, on top of the approval, sandbox and session model the app already had.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: DOM indexing instead of pixels
&lt;/h2&gt;

&lt;p&gt;Screen coordinates are brittle. A cookie banner shifts the layout by 40px and every click lands somewhere else. browser-use solved this by handing the model a numbered list of interactive elements and letting it act on numbers.&lt;/p&gt;

&lt;p&gt;AIClaw does the same. &lt;code&gt;browser_snapshot&lt;/code&gt; returns a numbered list where each entry carries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the element's role&lt;/li&gt;
&lt;li&gt;its visible text&lt;/li&gt;
&lt;li&gt;its current value (for inputs)&lt;/li&gt;
&lt;li&gt;the link target, if any&lt;/li&gt;
&lt;li&gt;whether it is inside the viewport&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list is capped at 150 entries with the total stated, so the model knows to scroll rather than assume the page ended. &lt;code&gt;browser_screenshot&lt;/code&gt; exists for the cases where layout or a captcha actually matters, but it is not the default path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ten tools, forwarded like computer use
&lt;/h2&gt;

&lt;p&gt;When the setting is on, the kernel registers ten tools: &lt;code&gt;navigate&lt;/code&gt;, &lt;code&gt;snapshot&lt;/code&gt;, &lt;code&gt;click&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;, &lt;code&gt;scroll&lt;/code&gt;, &lt;code&gt;back&lt;/code&gt;, &lt;code&gt;key&lt;/code&gt;, &lt;code&gt;extract&lt;/code&gt;, &lt;code&gt;screenshot&lt;/code&gt;. Each one is forwarded to the desktop host as a &lt;code&gt;browser/request&lt;/code&gt; — the same path computer use already took, so nothing about the tool loop or approval flow is special-cased.&lt;/p&gt;

&lt;p&gt;They also fold into &lt;code&gt;exec&lt;/code&gt; under code mode, which is where they get interesting: paging through ten pages of results is a loop, and the intermediate pages never enter the context window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;browser_extract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;browser_click&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// "Next"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;---&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The browser belongs to the host
&lt;/h2&gt;

&lt;p&gt;Electron already ships Chromium, so AIClaw does not need Playwright or a downloaded browser binary. The agent gets a separate &lt;code&gt;BrowserWindow&lt;/code&gt; on a persistent partition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logins survive.&lt;/strong&gt; The session lives in &lt;code&gt;persist:agent-browser&lt;/code&gt;, so signing in once is enough for later sessions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The window is visible.&lt;/strong&gt; You can watch what the model is doing and take over mid-task.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The page is isolated.&lt;/strong&gt; It can reach neither the preload script nor Node.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Text typed by the model goes through the real input path, so React and Vue controlled inputs actually see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Page content is untrusted input
&lt;/h2&gt;

&lt;p&gt;Everything scraped from a page — the numbered list and the extracted body text — is wrapped in the same boundary markers AIClaw uses for external feeds, and the tool descriptions say so again. That does not stop a page that deliberately disguises a button as something else (browser-use cannot either). What it does stop is a sentence on a web page being read as an instruction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approval stays where it was
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Opening a URL &lt;strong&gt;asks&lt;/strong&gt;, every time. It leaves the machine and the model picked the destination.&lt;/li&gt;
&lt;li&gt;In-page actions are writes: the default profile lets them through, the strict profile asks about each one.&lt;/li&gt;
&lt;li&gt;Snapshot, extract and screenshot never ask.&lt;/li&gt;
&lt;li&gt;Channel sessions (unattended) cannot reach the browser at all.&lt;/li&gt;
&lt;li&gt;Only &lt;code&gt;http&lt;/code&gt;, &lt;code&gt;https&lt;/code&gt; and &lt;code&gt;data:&lt;/code&gt; URLs load.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reasoning for asking only once per navigation: a click might mean "next page" or "confirm order", and there is no way to tell from the element. Asking on every click trains users to approve blindly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Known gaps, in value order
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;File upload&lt;/strong&gt; — the host needs to take over the &lt;code&gt;file-chooser&lt;/code&gt; event and feed it a path inside the workspace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sensitive-data placeholders&lt;/strong&gt; — the model sees &lt;code&gt;$password&lt;/code&gt;, the host substitutes the real value so it never enters the transcript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple tabs&lt;/strong&gt; — a tab list, switch and close.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain allowlist&lt;/strong&gt; — configured domains skip the navigation prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headless mode&lt;/strong&gt; — for scenarios and CI.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How it was verified
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go tests in &lt;code&gt;internal/agent/browser_test.go&lt;/code&gt;: the tools register only when enabled, navigation requires approval, in-page clicks do not, the strict profile asks step by step, and a screenshot arrives as an image in the next request.&lt;/li&gt;
&lt;li&gt;A node test for the snapshot text: numbered-list shape, untrusted boundaries, truncation notice, and that page scripts have no network capability.&lt;/li&gt;
&lt;li&gt;Desktop smoke test that really opens a window and runs navigate → snapshot → type → click → extract against an embedded page, plus a refusal of a &lt;code&gt;file:&lt;/code&gt; URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The item-by-item comparison with browser-use — including the gaps above — is in the repo at &lt;code&gt;docs/design/browser.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;AIClaw is open source: &lt;a href="https://github.com/chowyu12/aiclaw" rel="noopener noreferrer"&gt;https://github.com/chowyu12/aiclaw&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>electron</category>
    </item>
    <item>
      <title>How AIClaw Adds Durable Memory Without Turning Prompt Context Into a Global Text File</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Tue, 21 Jul 2026 10:50:21 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaw-adds-durable-memory-without-turning-prompt-context-into-a-global-text-file-d45</link>
      <guid>https://dev.to/chowyu12/how-aiclaw-adds-durable-memory-without-turning-prompt-context-into-a-global-text-file-d45</guid>
      <description>&lt;p&gt;AI agents need memory, but most "memory" implementations are either too weak to be useful or too loose to be safe. A flat &lt;code&gt;MEMORY.md&lt;/code&gt; file is simple, but it quickly becomes hard to audit, hard to scope, and easy to over-inject into prompts.&lt;/p&gt;

&lt;p&gt;AIClaw's latest memory work takes a different approach: memory is now stored as application data with ownership, scope, review status, search, evidence, and UI controls. The goal is not to make the model blindly obey old notes. The goal is to give an agent durable context that stays inspectable and bounded.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with file-style memory
&lt;/h2&gt;

&lt;p&gt;The old mental model for agent memory is straightforward: save some useful facts, load them into the next run, and hope the assistant gets better over time.&lt;/p&gt;

&lt;p&gt;That breaks down in real use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not every remembered fact should apply to every agent.&lt;/li&gt;
&lt;li&gt;User-specific context should not leak across users.&lt;/li&gt;
&lt;li&gt;Candidate notes should not be injected as if they were trusted truth.&lt;/li&gt;
&lt;li&gt;Sensitive content needs review before it becomes active context.&lt;/li&gt;
&lt;li&gt;Operators need to know what memory was used in a given answer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AIClaw now treats memory as structured state instead of a shared free-form prompt file.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed in AIClaw
&lt;/h2&gt;

&lt;p&gt;The new &lt;code&gt;Durable Memory&lt;/code&gt; section in the README describes a database-backed Memory System where each memory record carries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an owner&lt;/li&gt;
&lt;li&gt;a scope&lt;/li&gt;
&lt;li&gt;a kind&lt;/li&gt;
&lt;li&gt;a stable key&lt;/li&gt;
&lt;li&gt;importance and confidence&lt;/li&gt;
&lt;li&gt;status&lt;/li&gt;
&lt;li&gt;revision history&lt;/li&gt;
&lt;li&gt;evidence links&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two scopes define visibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user&lt;/code&gt;: available to every agent for the same user&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;agent_user&lt;/code&gt;: available only to one user and one specific agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a practical design choice. Some facts are general preferences like response style. Others are agent-specific procedures that should stay bound to one agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory is reviewable, not magical
&lt;/h2&gt;

&lt;p&gt;One of the most useful parts of this design is the lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;candidate -&amp;gt; active -&amp;gt; superseded / dismissed / deleted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means agent-written memory does not have to become active prompt context immediately.&lt;/p&gt;

&lt;p&gt;In the new service layer, &lt;code&gt;propose&lt;/code&gt; writes candidate memory, while &lt;code&gt;upsert&lt;/code&gt; can create active memory. Sensitive writes are forced back to &lt;code&gt;candidate&lt;/code&gt; status even if something tries to mark them active. That gives operators a real review boundary instead of a best-effort convention.&lt;/p&gt;

&lt;p&gt;The new web Memory page exposes that workflow directly. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;browse active memories&lt;/li&gt;
&lt;li&gt;inspect candidates separately&lt;/li&gt;
&lt;li&gt;search and filter by scope and kind&lt;/li&gt;
&lt;li&gt;approve or dismiss candidates&lt;/li&gt;
&lt;li&gt;edit, pin, expire, or delete records&lt;/li&gt;
&lt;li&gt;inspect revision history and evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is much closer to how teams actually need agent memory to work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieval is scoped before it reaches the prompt
&lt;/h2&gt;

&lt;p&gt;The most important runtime behavior is not storage. It is retrieval.&lt;/p&gt;

&lt;p&gt;According to &lt;code&gt;docs/design/memory-system.md&lt;/code&gt;, AIClaw retrieves only:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;active, unexpired records&lt;/li&gt;
&lt;li&gt;for the current user&lt;/li&gt;
&lt;li&gt;for the current agent when scope is &lt;code&gt;agent_user&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Candidate records, foreign-user records, and other-agent records are excluded from prompt injection.&lt;/p&gt;

&lt;p&gt;The memory service then adds pinned records, de-duplicates the set, compacts it to a prompt budget, and renders a bounded &lt;code&gt;&amp;lt;memory_context&amp;gt;&lt;/code&gt; block with a safety preamble: retained memory is context, not instruction, and it loses to the current user request and verified tool results.&lt;/p&gt;

&lt;p&gt;That distinction matters. A lot of memory systems fail because old notes become pseudo-system prompts. AIClaw is explicitly avoiding that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence and auditability are first-class
&lt;/h2&gt;

&lt;p&gt;Another strong design choice is the evidence model.&lt;/p&gt;

&lt;p&gt;Each memory can accumulate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;source evidence showing where it came from&lt;/li&gt;
&lt;li&gt;usage evidence linking it to a run and final assistant message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when a memory influences an answer, there is a trail. The README and design doc both emphasize that the final memory snapshot can be shown beside chat and execution logs without mixing memory content into the assistant response body itself.&lt;/p&gt;

&lt;p&gt;This is the kind of detail that makes durable memory operationally useful instead of just conceptually interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tests cover the failure modes you actually worry about
&lt;/h2&gt;

&lt;p&gt;The new memory tests are worth reading because they target the right risks.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;TestBuildContextIsolatedAndCandidateSafe&lt;/code&gt; verifies that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;only the current user's records are retrieved&lt;/li&gt;
&lt;li&gt;agent-specific memory does not leak from another agent&lt;/li&gt;
&lt;li&gt;candidate memory is excluded&lt;/li&gt;
&lt;li&gt;the prompt includes the safety boundary text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;TestSensitiveMemoryRequiresReview&lt;/code&gt; verifies that sensitive memory cannot stay active and is pushed back to candidate review status.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;TestToolProposalCreatesCandidate&lt;/code&gt; verifies that tool-driven proposals create candidate memories rather than silently activating them.&lt;/p&gt;

&lt;p&gt;Those are the right invariants for a production memory feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like in practice
&lt;/h2&gt;

&lt;p&gt;Here is a realistic workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A user repeatedly asks one agent for terse release notes and detailed test evidence.&lt;/li&gt;
&lt;li&gt;The agent proposes that as an &lt;code&gt;agent_user&lt;/code&gt; preference.&lt;/li&gt;
&lt;li&gt;The operator reviews it in the Memory page and approves it.&lt;/li&gt;
&lt;li&gt;Future runs for that same user-agent pair can retrieve it automatically.&lt;/li&gt;
&lt;li&gt;Another agent for the same user does not inherit that preference unless the scope is intentionally broader.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This keeps memory useful without making it global by accident.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I picked this feature for today's article
&lt;/h2&gt;

&lt;p&gt;This is a concrete new feature from the July 19, 2026 commit &lt;code&gt;feat(memory): add scoped durable memory system&lt;/code&gt;. It also fills a different slot than the earlier AIClaw article about memory/session search: that earlier topic focused on finding prior conversations, while this one is about durable, scoped, reviewable context that can be injected into future runs.&lt;/p&gt;

&lt;p&gt;For AI agent systems, memory is one of the easiest places to be vague. AIClaw's newer implementation is specific about scope, review, retrieval, and evidence. That makes it worth documenting on its own.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>agents</category>
    </item>
    <item>
      <title>How AIClaw's Code Interpreter Turns Scripts Into Downloadable Agent Outputs</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Sun, 19 Jul 2026 10:03:46 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaws-code-interpreter-turns-scripts-into-downloadable-agent-outputs-l6n</link>
      <guid>https://dev.to/chowyu12/how-aiclaws-code-interpreter-turns-scripts-into-downloadable-agent-outputs-l6n</guid>
      <description>&lt;p&gt;AI agents often need a place to do small but real computation: clean a CSV, convert a JSON payload, generate a chart, inspect an API response, or produce a one-off report. The problem is that many agent products either stop at “here is some code you can run yourself” or run code in a way that is hard to inspect afterward.&lt;/p&gt;

&lt;p&gt;AIClaw takes a more practical route. Its built-in &lt;code&gt;code_interpreter&lt;/code&gt; tool runs Python, JavaScript, or shell snippets inside the agent workspace, returns structured execution results, and can surface generated files back into the chat flow.&lt;/p&gt;

&lt;p&gt;This is not a brand-new July 2026 launch. It is an existing AIClaw feature that is worth a closer look because it connects a few product surfaces that matter in day-to-day use: sandboxed execution, structured tool output, downloadable artifacts, and reusable workflow skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: agents need computation, not just text
&lt;/h2&gt;

&lt;p&gt;A useful agent should be able to do more than describe a transformation. It should be able to execute it.&lt;/p&gt;

&lt;p&gt;Common examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;parse a CSV and calculate grouped statistics;&lt;/li&gt;
&lt;li&gt;convert JSON into Markdown or HTML;&lt;/li&gt;
&lt;li&gt;generate a small script to validate API output;&lt;/li&gt;
&lt;li&gt;produce a PNG, CSV, or report file for the user to download.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without an execution tool, the model either hallucinates results or pushes the work back to the operator. With a raw shell tool alone, the agent can run commands, but the product still needs a consistent way to track stdout, stderr, exit status, duration, and any generated files.&lt;/p&gt;

&lt;p&gt;That is the gap AIClaw's &lt;code&gt;code_interpreter&lt;/code&gt; fills.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the tool actually does
&lt;/h2&gt;

&lt;p&gt;In the current repository, AIClaw registers &lt;code&gt;code_interpreter&lt;/code&gt; as a built-in tool alongside &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;write&lt;/code&gt;, &lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;browser&lt;/code&gt;, &lt;code&gt;cron&lt;/code&gt;, &lt;code&gt;memory&lt;/code&gt;, and &lt;code&gt;sub_agent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The tool contract is intentionally small:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;language&lt;/code&gt;: &lt;code&gt;python&lt;/code&gt;, &lt;code&gt;javascript&lt;/code&gt;, or &lt;code&gt;shell&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;code&lt;/code&gt;: the source to execute&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;timeout&lt;/code&gt;: optional, with a default of 60 seconds and a hard cap of 120 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The handler then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validates the input.&lt;/li&gt;
&lt;li&gt;Resolves the runtime binary with &lt;code&gt;exec.LookPath&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;python3&lt;/code&gt; for Python&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;node&lt;/code&gt; for JavaScript&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sh&lt;/code&gt; for shell&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Applies lightweight safety checks against obviously dangerous code patterns.&lt;/li&gt;
&lt;li&gt;Writes the snippet into the agent sandbox as a real file such as &lt;code&gt;exec_ab12cd34.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Executes that file with the sandbox directory as the working directory.&lt;/li&gt;
&lt;li&gt;Returns structured JSON with:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ok&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;language&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;file&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;exit_code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stdout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stderr&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;error&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;duration_ms&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That structure matters because the result is machine-friendly for the runtime and still readable in logs and chat progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why writing a real file is the important design choice
&lt;/h2&gt;

&lt;p&gt;One subtle but useful implementation detail is that AIClaw does not treat the snippet as an opaque in-memory eval. It writes the code to a real file inside the workspace sandbox and runs that file from there.&lt;/p&gt;

&lt;p&gt;That gives the agent a cleaner execution model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;file-relative reads and writes behave normally;&lt;/li&gt;
&lt;li&gt;generated artifacts land in the same workspace the rest of the agent can inspect;&lt;/li&gt;
&lt;li&gt;operators can reason about what happened from a concrete script filename;&lt;/li&gt;
&lt;li&gt;execution traces line up better with file outputs and follow-up tool calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an agent platform, this is much more practical than a hidden REPL with no durable execution context.&lt;/p&gt;

&lt;h2&gt;
  
  
  How downloadable outputs are recovered
&lt;/h2&gt;

&lt;p&gt;The interesting part is not only that code runs. It is that AIClaw can turn the result into something a user can actually open.&lt;/p&gt;

&lt;p&gt;AIClaw's result parsing layer looks for file outputs in a few ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a direct JSON file result payload;&lt;/li&gt;
&lt;li&gt;an absolute file path printed as the entire output;&lt;/li&gt;
&lt;li&gt;an absolute file path embedded in stdout, such as &lt;code&gt;Saved to /tmp/report.csv&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the referenced file exists, AIClaw converts it into a normalized file result with MIME type detection by extension. That is what allows generated files to move from “the script said it wrote something” to a proper attachment flow in chat and the UI.&lt;/p&gt;

&lt;p&gt;This complements the generated-file work already visible elsewhere in the product. The code interpreter is one of the fastest ways for an agent to produce those artifacts on demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety and limits
&lt;/h2&gt;

&lt;p&gt;AIClaw is not pretending this tool is a full security boundary, but it does enforce a few useful guardrails in the current implementation.&lt;/p&gt;

&lt;p&gt;The handler blocks some obviously dangerous patterns, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;destructive shell commands like &lt;code&gt;rm -rf /&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Python subprocess or direct system-call patterns;&lt;/li&gt;
&lt;li&gt;JavaScript process and filesystem patterns associated with unsafe execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requires the runtime binary to exist before execution starts;&lt;/li&gt;
&lt;li&gt;limits output to 10,000 characters;&lt;/li&gt;
&lt;li&gt;caps timeout at 120 seconds;&lt;/li&gt;
&lt;li&gt;fails cleanly when the workspace sandbox is not initialized.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a pragmatic posture for a self-hosted platform: useful by default, explicit about constraints, and easy to reason about from code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this fits in real AIClaw workflows
&lt;/h2&gt;

&lt;p&gt;The feature becomes more valuable when combined with the rest of AIClaw.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;read&lt;/code&gt; can inspect a source file;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;code_interpreter&lt;/code&gt; can transform or analyze it;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;write&lt;/code&gt; can save a cleaned result;&lt;/li&gt;
&lt;li&gt;the result layer can expose generated files back to the user;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sub_agent&lt;/code&gt; can parallelize independent analysis tasks;&lt;/li&gt;
&lt;li&gt;skills can standardize the workflow for repeatable use cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repository already reflects this pattern. AIClaw's built-in &lt;code&gt;data-pipeline&lt;/code&gt; skill explicitly tells agents to use &lt;code&gt;code_interpreter&lt;/code&gt; for CSV, JSON, and Excel-style processing tasks, including validation and export.&lt;/p&gt;

&lt;p&gt;That is the right level of abstraction. The skill captures the workflow, while the interpreter provides the execution primitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete example
&lt;/h2&gt;

&lt;p&gt;Suppose a user uploads a CSV and asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Group sales by month, calculate totals, and give me a downloadable result.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AIClaw agent can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;inspect the file with &lt;code&gt;read&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;write a short Python script in &lt;code&gt;code_interpreter&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;save &lt;code&gt;monthly_sales.csv&lt;/code&gt; inside the sandbox;&lt;/li&gt;
&lt;li&gt;print the absolute output path;&lt;/li&gt;
&lt;li&gt;return both a summary and the generated file attachment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The same pattern works for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML report generation;&lt;/li&gt;
&lt;li&gt;JSON normalization;&lt;/li&gt;
&lt;li&gt;log summarization;&lt;/li&gt;
&lt;li&gt;quick chart creation;&lt;/li&gt;
&lt;li&gt;one-off format conversion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this feature is worth covering now
&lt;/h2&gt;

&lt;p&gt;A lot of agent demos focus on planning, tools, or model routing. Those matter, but the product becomes much more useful when an agent can produce concrete outputs that survive beyond the answer text.&lt;/p&gt;

&lt;p&gt;AIClaw's &lt;code&gt;code_interpreter&lt;/code&gt; is a good example of that product thinking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simple tool contract;&lt;/li&gt;
&lt;li&gt;explicit runtime selection;&lt;/li&gt;
&lt;li&gt;workspace-local execution;&lt;/li&gt;
&lt;li&gt;structured results;&lt;/li&gt;
&lt;li&gt;attachment-friendly file detection;&lt;/li&gt;
&lt;li&gt;natural integration with skills and other tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are building a self-hosted agent platform, this is a feature worth studying. It is not only about “running code.” It is about making execution auditable, composable, and actually useful to the person operating the system.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How AIClaw Hardens Local Agent Runtimes on Your Machine</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Sat, 18 Jul 2026 08:37:03 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaw-hardens-local-agent-runtimes-on-your-machine-1nkc</link>
      <guid>https://dev.to/chowyu12/how-aiclaw-hardens-local-agent-runtimes-on-your-machine-1nkc</guid>
      <description>&lt;p&gt;AiClaw’s latest local-runtime work fixes a practical problem that shows up fast in self-hosted agent systems: the server process can be running fine, but the agent CLI you already installed is invisible or unreliable when the runtime tries to execute it.&lt;/p&gt;

&lt;p&gt;In the July 18, 2026 &lt;code&gt;fix: harden local runtime and retries&lt;/code&gt; commit, AIClaw tightened the local runtime path and command-resolution layer so local agent execution behaves more like your real login shell, while still keeping execution explicit and auditable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: service PATHs are usually worse than your terminal PATH
&lt;/h2&gt;

&lt;p&gt;AIClaw is designed to run local agent CLIs directly on the machine that hosts the server. The README now makes that contract explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the built-in &lt;code&gt;Local&lt;/code&gt; runtime is created automatically at startup;&lt;/li&gt;
&lt;li&gt;AIClaw recovers the current user’s login-shell &lt;code&gt;PATH&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;it adds standard package-manager locations;&lt;/li&gt;
&lt;li&gt;it executes detected CLIs in-process without an extra daemon or shell hop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matters because service managers often start processes with a narrow &lt;code&gt;PATH&lt;/code&gt;. On macOS, &lt;code&gt;launchd&lt;/code&gt; is a classic example. A CLI may work in your terminal, but the server process may not see the same executable path when it tries to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;detect available runtimes;&lt;/li&gt;
&lt;li&gt;launch a selected CLI later;&lt;/li&gt;
&lt;li&gt;reconnect after restart;&lt;/li&gt;
&lt;li&gt;run from a background service instead of an interactive shell.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is the worst kind of reliability bug: detection says one thing, execution does another.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed in the code
&lt;/h2&gt;

&lt;p&gt;The new &lt;code&gt;internal/runtimeclient/environment.go&lt;/code&gt; centralizes environment handling for local runtimes.&lt;/p&gt;

&lt;p&gt;Instead of trusting the raw service environment, AIClaw now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads the current environment as a base.&lt;/li&gt;
&lt;li&gt;Recovers the login-shell &lt;code&gt;PATH&lt;/code&gt; with &lt;code&gt;shell -ilc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Merges that with common install locations such as:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/opt/homebrew/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/local/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.local/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/go/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.volta/bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/Library/pnpm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.asdf/shims&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.mise/shims&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reuses that same resolved environment for both CLI detection and actual execution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That “same environment for detection and execution” point is the real fix. AIClaw no longer reports a CLI as available using one lookup path and then launches it with a different process environment later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is better than a shell wrapper
&lt;/h2&gt;

&lt;p&gt;AIClaw still executes runtime commands directly as &lt;code&gt;command + args&lt;/code&gt;. It does not pass them through a shell.&lt;/p&gt;

&lt;p&gt;That preserves a few useful properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;argument handling stays predictable;&lt;/li&gt;
&lt;li&gt;quoting bugs are avoided;&lt;/li&gt;
&lt;li&gt;the runtime surface is smaller;&lt;/li&gt;
&lt;li&gt;the execution model is easier to inspect in logs and tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the change is not “use a shell to run everything.” The change is “recover the useful parts of the login environment, then keep execution direct.”&lt;/p&gt;

&lt;h2&gt;
  
  
  A small but important macOS improvement
&lt;/h2&gt;

&lt;p&gt;There is also a practical macOS-specific rule: when the requested command is &lt;code&gt;codex&lt;/code&gt;, AIClaw prefers the signed Codex CLI bundled inside the ChatGPT app at:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/Applications/ChatGPT.app/Contents/Resources/codex&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That matters on machines where an older third-party install may still be on &lt;code&gt;PATH&lt;/code&gt;. If you explicitly configure an absolute CLI path, that still wins. But for the common default case, AIClaw now prefers the bundled, app-managed binary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the tests verify
&lt;/h2&gt;

&lt;p&gt;The new runtime environment tests cover the important failure modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;merged login-shell and fallback paths are preserved in the final &lt;code&gt;PATH&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;non-&lt;code&gt;PATH&lt;/code&gt; environment variables stay intact;&lt;/li&gt;
&lt;li&gt;command resolution uses the supplied environment consistently;&lt;/li&gt;
&lt;li&gt;missing CLIs produce an actionable error that points users to their login-shell &lt;code&gt;PATH&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;on macOS, bundled Codex is preferred when available.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the right kind of test coverage for runtime plumbing: it checks behavior users actually feel, not just helper internals.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for AIClaw users
&lt;/h2&gt;

&lt;p&gt;If you run AIClaw locally and want to use Codex, Claude Code, Cursor, CodeBuddy, Hermes, or OpenClaw through the built-in runtime, the workflow is now simpler:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install and authenticate the CLI normally under your own user account.&lt;/li&gt;
&lt;li&gt;Start AIClaw.&lt;/li&gt;
&lt;li&gt;Open the &lt;code&gt;Runtimes&lt;/code&gt; page and verify the detected CLIs.&lt;/li&gt;
&lt;li&gt;Create an agent with execution mode &lt;code&gt;Local&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run tasks without adding a separate runtime daemon on the same machine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The recent UI copy was updated to match the behavior too. Instead of saying AIClaw only scans the process &lt;code&gt;PATH&lt;/code&gt;, the form now explains that it restores the current user’s login-shell &lt;code&gt;PATH&lt;/code&gt; and scans from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I think this feature matters
&lt;/h2&gt;

&lt;p&gt;Local-first agent products usually fail at the boundary between “works in my terminal” and “works under a service manager.” AIClaw’s recent runtime hardening closes that gap in a concrete way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better environment recovery;&lt;/li&gt;
&lt;li&gt;consistent detection and execution;&lt;/li&gt;
&lt;li&gt;safer direct command execution;&lt;/li&gt;
&lt;li&gt;clearer operator-facing errors;&lt;/li&gt;
&lt;li&gt;better defaults on macOS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not a flashy UI feature, but it is exactly the kind of systems work that makes a self-hosted agent platform dependable in day-to-day use.&lt;/p&gt;

&lt;p&gt;If you are building a local-first agent stack, this is the right lesson to steal: treat the runtime environment as part of the product surface, not just a deployment detail.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How AIClaw's Harness Runtime Stops Premature "Done" Answers</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Tue, 14 Jul 2026 08:36:00 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaws-harness-runtime-stops-premature-done-answers-5fe1</link>
      <guid>https://dev.to/chowyu12/how-aiclaws-harness-runtime-stops-premature-done-answers-5fe1</guid>
      <description>&lt;p&gt;AI agents are good at sounding finished before they have actually finished. They can say a file was generated when no file exists, claim a task is blocked without showing the failed tool call, or return a progress update as if it were a final answer.&lt;/p&gt;

&lt;p&gt;AIClaw's recent harness runtime work addresses that gap by moving completion from "the model said it is done" to "the execution layer has enough contract and evidence to allow completion."&lt;/p&gt;

&lt;p&gt;This article is based on the current AIClaw repository, especially the harness runtime design and the July 6 and July 9 agent changes that added the verifier layer, execution evidence ledger, explicit &lt;code&gt;finish&lt;/code&gt; tool, plan bootstrap, and final-answer gates.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: LLM Confidence Is Not Execution Truth
&lt;/h2&gt;

&lt;p&gt;In a tool-using agent, the model can produce a polished answer even when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a required tool was never called&lt;/li&gt;
&lt;li&gt;a tool failed and the final answer ignores the failure&lt;/li&gt;
&lt;li&gt;a promised attachment was never created&lt;/li&gt;
&lt;li&gt;the task plan is still incomplete&lt;/li&gt;
&lt;li&gt;the assistant is only narrating progress instead of delivering a result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AIClaw already had runtime plan state, tool execution, generated files, and execution logs. The new harness runtime ties those pieces together with a validation layer that decides whether a run can proceed, needs correction, or is allowed to finish.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Runtime Model
&lt;/h2&gt;

&lt;p&gt;The core pipeline in &lt;code&gt;pkg/harness&lt;/code&gt; is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contract -&amp;gt; Evidence -&amp;gt; Validate -&amp;gt; Correct
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TaskContract&lt;/code&gt; derives what the run is expected to do.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EvidenceLedger&lt;/code&gt; records what the run actually did.&lt;/li&gt;
&lt;li&gt;validators check whether the current state satisfies the contract.&lt;/li&gt;
&lt;li&gt;correction prompts push the model back into execution when the answer is incomplete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a separate executor. The main loop still lives in the agent runtime. The harness adds staged validation and correction around that loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  What The Contract Captures
&lt;/h2&gt;

&lt;p&gt;The contract is derived from the user objective and current execution context. According to the current design and code, it can incorporate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user goal&lt;/li&gt;
&lt;li&gt;runtime plan requirements&lt;/li&gt;
&lt;li&gt;file-delivery intent&lt;/li&gt;
&lt;li&gt;tool evidence expectations&lt;/li&gt;
&lt;li&gt;attachment context&lt;/li&gt;
&lt;li&gt;sub-agent context&lt;/li&gt;
&lt;li&gt;correction budget&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matters because "done" means different things for different tasks. A question-answering turn might only need a grounded text answer. A file-generation turn needs actual artifact evidence. A multi-step task may require an active plan and a terminal plan outcome before the final response is allowed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Counts As Evidence
&lt;/h2&gt;

&lt;p&gt;AIClaw's verifier collects structured execution evidence rather than relying on the final assistant message alone. The evidence ledger includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business tool calls, excluding internal control tools like &lt;code&gt;plan&lt;/code&gt;, &lt;code&gt;tool_search&lt;/code&gt;, and &lt;code&gt;finish&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;tool events with tool name, argument summary, output summary, status, duration, files, and failure classification&lt;/li&gt;
&lt;li&gt;generated file artifacts persisted as AIClaw files&lt;/li&gt;
&lt;li&gt;plan snapshots from the active plan manager&lt;/li&gt;
&lt;li&gt;validation and correction events&lt;/li&gt;
&lt;li&gt;blocker evidence such as permission, auth, policy, timeout, rate limit, or not-found failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives the final gate something concrete to inspect. If a tool failed, the harness can tell whether it is a recoverable timeout or a terminal auth problem. If a file was promised, the harness can check that file evidence actually exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Four Validation Gates
&lt;/h2&gt;

&lt;p&gt;AIClaw now validates at four different points in the run:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;What it checks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pre_tool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether a tool call is allowed before execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;post_tool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the current tool round produced the evidence the run now has&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pre_final&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the candidate final answer is truly ready to finish&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pre_save&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the final content is still valid after attachment links are rendered&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This staged approach is the important design choice.&lt;/p&gt;

&lt;p&gt;Many agent systems only validate at the end. AIClaw also validates before tool execution and between tool rounds, so it can keep the model inside the task until it either gathers enough evidence or reaches a real blocker.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Gets Rejected Before Final Answer
&lt;/h2&gt;

&lt;p&gt;The current runtime can stop finalization when the candidate answer is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;empty&lt;/li&gt;
&lt;li&gt;only a progress update&lt;/li&gt;
&lt;li&gt;missing required successful evidence&lt;/li&gt;
&lt;li&gt;ignoring a terminal blocker&lt;/li&gt;
&lt;li&gt;missing promised artifacts&lt;/li&gt;
&lt;li&gt;trying to finish while the plan is still open&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The logic is visible in the harness design and outcome classifier. Candidate answers are assessed as &lt;code&gt;success&lt;/code&gt;, &lt;code&gt;blocked&lt;/code&gt;, &lt;code&gt;partial&lt;/code&gt;, &lt;code&gt;progress_only&lt;/code&gt;, or &lt;code&gt;unknown&lt;/code&gt;, then compared with the evidence ledger.&lt;/p&gt;

&lt;p&gt;That makes the final gate more than a string check. It is deciding whether the answer matches what the run actually accomplished.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Explicit &lt;code&gt;finish&lt;/code&gt; Tool Instead Of Implicit Guessing
&lt;/h2&gt;

&lt;p&gt;One practical addition is the built-in &lt;code&gt;finish&lt;/code&gt; tool.&lt;/p&gt;

&lt;p&gt;Instead of relying only on "no more tool calls means we must be done," the model can explicitly submit the final user-facing answer through &lt;code&gt;finish&lt;/code&gt;. AIClaw captures that answer, runs the same final gate, and only closes the turn if the harness allows it.&lt;/p&gt;

&lt;p&gt;This is a clean separation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the model proposes the final answer&lt;/li&gt;
&lt;li&gt;the harness decides whether the answer is allowed to end the run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;finish&lt;/code&gt; tool is also excluded from normal business-tool evidence, which prevents completion signaling from being counted as actual execution work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan State And Harness Runtime Work Together
&lt;/h2&gt;

&lt;p&gt;AIClaw already uses runtime Plan State instead of chat-visible todo lists. The recent harness work tightens that integration.&lt;/p&gt;

&lt;p&gt;If a contract requires a plan and there is no active plan, the runtime can bootstrap one from an initial template. During execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;only one plan item is allowed to be running&lt;/li&gt;
&lt;li&gt;successful rounds can advance the active item&lt;/li&gt;
&lt;li&gt;tool or LLM failures can mark the running item as failed&lt;/li&gt;
&lt;li&gt;the final answer is linked to the final plan snapshot&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is useful because the harness is not only validating text quality. It is validating whether the run reached a terminal execution state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better Failure Semantics
&lt;/h2&gt;

&lt;p&gt;The runtime now classifies blocker types such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;permission denied&lt;/li&gt;
&lt;li&gt;auth failed&lt;/li&gt;
&lt;li&gt;policy blocked&lt;/li&gt;
&lt;li&gt;not found&lt;/li&gt;
&lt;li&gt;rate limited&lt;/li&gt;
&lt;li&gt;timeout&lt;/li&gt;
&lt;li&gt;generic tool error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also distinguishes recoverable from non-recoverable failures. A timeout can lead to another attempt or a correction loop. Missing permissions or invalid authentication should be surfaced clearly as blockers instead of being buried under a generic apology.&lt;/p&gt;

&lt;p&gt;That makes the execution log more operationally useful, especially when you are debugging real tool-using agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observable By Design
&lt;/h2&gt;

&lt;p&gt;When validation or correction fails, AIClaw records harness-specific execution steps such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;validate_pre_tool&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;validate_post_tool&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;validate_pre_final&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;validate_pre_save&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;correct_pre_final&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;correct_post_tool&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;continue_execution&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;recover_llm_round&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The metadata includes the stage, violation codes, required actions, evidence summary, and correction outcome. Successful validation without violations stays quiet to avoid polluting the trace.&lt;/p&gt;

&lt;p&gt;That is a good tradeoff: rich debugging data when something goes wrong, low noise when the run is healthy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters In Daily Use
&lt;/h2&gt;

&lt;p&gt;For users, this changes the feel of an agent in a practical way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;file-delivery tasks are less likely to end without actual files&lt;/li&gt;
&lt;li&gt;long tasks are less likely to stop at a narrative progress update&lt;/li&gt;
&lt;li&gt;tool failures are more likely to be explained with actionable blocker context&lt;/li&gt;
&lt;li&gt;execution logs become a better source of truth than the assistant's confidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developers building on AIClaw, the bigger value is architectural. The stable &lt;code&gt;pkg/harness&lt;/code&gt; package gives you a place to evolve contracts, evidence, validation, and correction rules without rewriting the whole agent loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Small But Important Shift
&lt;/h2&gt;

&lt;p&gt;The key idea behind this feature is simple:&lt;/p&gt;

&lt;p&gt;an agent should not be considered done because it sounds done. It should be considered done because the runtime can prove it did the work, produced the promised artifacts, or reached a well-explained blocker.&lt;/p&gt;

&lt;p&gt;That is the shift AIClaw's harness runtime is making.&lt;/p&gt;

&lt;p&gt;If you are building self-hosted agents that need to do more than chat, this is one of the most important layers to get right.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How AIClaw's Harness Runtime Stops Agents From Pretending They're Done</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Thu, 09 Jul 2026 12:59:17 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaws-harness-runtime-stops-agents-from-pretending-theyre-done-51cm</link>
      <guid>https://dev.to/chowyu12/how-aiclaws-harness-runtime-stops-agents-from-pretending-theyre-done-51cm</guid>
      <description>&lt;p&gt;AIClaw has been pushing a new execution layer into &lt;code&gt;origin/master&lt;/code&gt; across three recent commits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;2026-07-02&lt;/code&gt; &lt;code&gt;feat: add harness execution protocol&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-07-06&lt;/code&gt; &lt;code&gt;refactor(agent): integrate harness runtime verifier&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2026-07-09&lt;/code&gt; &lt;code&gt;feat(agent): align harness execution runtime&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The feature is called the &lt;strong&gt;Harness Runtime&lt;/strong&gt;. The short version is simple: AIClaw no longer treats "the model says it's finished" as enough evidence that the task is actually complete.&lt;/p&gt;

&lt;p&gt;Instead, the executor now runs a contract-and-evidence loop that decides whether an answer is allowed to finish.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Most agent systems have an annoying failure mode:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The model makes a plan.&lt;/li&gt;
&lt;li&gt;It calls a few tools.&lt;/li&gt;
&lt;li&gt;It writes a confident answer.&lt;/li&gt;
&lt;li&gt;The answer is missing evidence, missing files, or is only a progress update.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the runtime accepts that answer, the execution trace looks successful even when the work is incomplete.&lt;/p&gt;

&lt;p&gt;AIClaw's new harness runtime is built to close that gap. The README now describes it as a layer that turns the user objective into a task contract, records evidence, validates tool and final-answer stages, and injects correction prompts when the work is not actually ready to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Model
&lt;/h2&gt;

&lt;p&gt;The design doc centers the runtime around four parts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Contract -&amp;gt; Evidence -&amp;gt; Validate -&amp;gt; Correct&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each turn now gets a &lt;code&gt;TaskContract&lt;/code&gt; inferred from the user objective, agent profile, tools, files, and plan state. That contract decides things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;whether a plan is required&lt;/li&gt;
&lt;li&gt;whether tool evidence is required&lt;/li&gt;
&lt;li&gt;whether artifacts are required&lt;/li&gt;
&lt;li&gt;whether the output should be treated as text, file, mixed, or JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Execution evidence is collected in an &lt;code&gt;EvidenceLedger&lt;/code&gt;. It records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;execution tools that actually ran&lt;/li&gt;
&lt;li&gt;tool events and their status&lt;/li&gt;
&lt;li&gt;generated file artifacts&lt;/li&gt;
&lt;li&gt;plan snapshots&lt;/li&gt;
&lt;li&gt;validation and correction events&lt;/li&gt;
&lt;li&gt;blocker evidence such as permission, auth, policy, not-found, rate-limit, and timeout failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives AIClaw a stable internal record of what happened, not just what the model claimed happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four Validation Gates
&lt;/h2&gt;

&lt;p&gt;The verifier now checks four stages:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;What it checks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pre_tool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether a requested tool call is allowed by policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;post_tool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the current round collected usable evidence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pre_final&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the candidate final answer is complete enough to finish&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pre_save&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether the final content still satisfies artifact and attachment requirements before persistence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This matters because different failures show up at different times.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A tool may be policy-blocked before it runs.&lt;/li&gt;
&lt;li&gt;A tool may run but fail with auth or permission errors.&lt;/li&gt;
&lt;li&gt;A final answer may be non-empty but still be only a progress message.&lt;/li&gt;
&lt;li&gt;A file-delivery task may claim success but omit the generated file link.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The harness catches each of these at the correct stage instead of waiting for the user to notice later.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Counts as a Real Final Answer
&lt;/h2&gt;

&lt;p&gt;The runtime now classifies final outcomes instead of treating every non-empty answer the same way.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;pkg/harness/outcome.go&lt;/code&gt;, AIClaw distinguishes between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;success&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blocked&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;partial&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;progress_only&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unknown&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That sounds small, but it changes agent behavior a lot.&lt;/p&gt;

&lt;p&gt;If the model says things like "I'm continuing", "please wait", or "next I will generate the file", the candidate can be treated as &lt;code&gt;progress_only&lt;/code&gt; and rejected at the final gate.&lt;/p&gt;

&lt;p&gt;If tools failed because of permission or authentication issues, the harness can require the final answer to explicitly explain that blocker instead of letting the agent drift into a vague summary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Corrections Instead of Silent Failure
&lt;/h2&gt;

&lt;p&gt;When validation fails, AIClaw does not immediately give up. The verifier can append a structured correction prompt and continue the turn, but only within a bounded retry budget.&lt;/p&gt;

&lt;p&gt;The new runtime standardizes these self-correction nudges so that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;final-gate rejection&lt;/li&gt;
&lt;li&gt;post-tool evidence rejection&lt;/li&gt;
&lt;li&gt;truncated or interrupted model rounds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;all consume the same correction budget.&lt;/p&gt;

&lt;p&gt;If the agent still cannot produce a valid answer, AIClaw closes the turn with a concrete failure message rather than pretending the run succeeded.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better Alignment With Plan State
&lt;/h2&gt;

&lt;p&gt;One detail I like is how this feature works with AIClaw's Runtime Plan State instead of bypassing it.&lt;/p&gt;

&lt;p&gt;The harness can bootstrap an initial plan when a task contract requires one. The plan template is intentionally simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand the goal and dependencies&lt;/li&gt;
&lt;li&gt;Execute tools and collect evidence&lt;/li&gt;
&lt;li&gt;Validate evidence and output requirements&lt;/li&gt;
&lt;li&gt;Deliver the final answer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That keeps planning inside the runtime, while the verifier checks that the plan reaches a terminal state before the answer is accepted.&lt;/p&gt;

&lt;h2&gt;
  
  
  A New &lt;code&gt;finish&lt;/code&gt; Tool
&lt;/h2&gt;

&lt;p&gt;The July 9 alignment work also adds a built-in &lt;code&gt;finish&lt;/code&gt; tool. The model can explicitly submit a final answer through a structured completion signal, and the harness then runs the explicit final gate before closing the turn.&lt;/p&gt;

&lt;p&gt;This is a useful pattern for agent runtimes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the model can say "this is my final answer"&lt;/li&gt;
&lt;li&gt;the executor still decides whether the answer is actually allowed to finish&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That separation makes the system easier to reason about and easier to debug in execution logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters In Practice
&lt;/h2&gt;

&lt;p&gt;This feature is not about making the agent sound smarter. It is about making the runtime more honest.&lt;/p&gt;

&lt;p&gt;If a task needs tool-backed evidence, generated files, or a finished plan, AIClaw now has a concrete mechanism to enforce that. The result is a better execution trace for both developers and operators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer fake-complete answers&lt;/li&gt;
&lt;li&gt;clearer blocker reporting&lt;/li&gt;
&lt;li&gt;better attachment delivery checks&lt;/li&gt;
&lt;li&gt;visible harness validation steps in logs when something goes wrong&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The README now positions AIClaw as a platform that favors explicit execution traces and durable runtime state over invisible agent magic. The harness runtime is a good example of that philosophy becoming real code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Look In The Repo
&lt;/h2&gt;

&lt;p&gt;If you want to inspect the implementation, the most relevant files are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docs/design/agent-harness-runtime.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;internal/agent/harness.go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;internal/agent/harness_verifier.go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;internal/agent/finish_tool.go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pkg/harness/contract.go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pkg/harness/runtime.go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pkg/harness/outcome.go&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interesting part is not just the validator package. It is the way the verifier, plan state, tool execution, and final message persistence now fit together as one execution contract.&lt;/p&gt;

&lt;p&gt;AIClaw is open source and self-hosted, so if you're building agents that need real execution guarantees instead of optimistic chat output, this is one of the areas worth studying next.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AIClaw Now Returns Tool Output Attachments You Can Actually Download</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Sun, 28 Jun 2026 11:48:42 +0000</pubDate>
      <link>https://dev.to/chowyu12/aiclaw-now-returns-tool-output-attachments-you-can-actually-download-23jo</link>
      <guid>https://dev.to/chowyu12/aiclaw-now-returns-tool-output-attachments-you-can-actually-download-23jo</guid>
      <description>&lt;p&gt;AIClaw already let agents run tools, generate files, and continue working across steps. The weak point was the handoff back to the user: a tool might create a report, image, or data file, but the final answer did not always make that output obvious or directly downloadable.&lt;/p&gt;

&lt;p&gt;Recent AIClaw changes tightened that workflow. Tool-generated files are now collected, deduplicated, exposed in API responses and streaming completion chunks, linked into the final assistant message, and rendered by the chat UI through stable &lt;code&gt;/public/files/&amp;lt;uuid&amp;gt;&lt;/code&gt; download URLs.&lt;/p&gt;

&lt;p&gt;This is not a cosmetic change. It closes the loop between tool execution and user-visible results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;In a tool-using agent system, “I created the file” is not enough. Users need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;know that a file was produced&lt;/li&gt;
&lt;li&gt;see which final answer it belongs to&lt;/li&gt;
&lt;li&gt;download it without searching through logs&lt;/li&gt;
&lt;li&gt;keep that file associated with the conversation history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without that, generated artifacts are easy to lose, especially when an agent uses multiple tools or delegates work to sub-agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed in AIClaw
&lt;/h2&gt;

&lt;p&gt;The recent attachment work is visible across the backend and frontend.&lt;/p&gt;

&lt;p&gt;On the execution side, AIClaw now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;collects file outputs returned by tools&lt;/li&gt;
&lt;li&gt;scans sandbox directories for newly created files when a tool does not explicitly return a file result&lt;/li&gt;
&lt;li&gt;pulls generated files back out of &lt;code&gt;sub_agent&lt;/code&gt; results&lt;/li&gt;
&lt;li&gt;deduplicates attachments before the final response is stored or streamed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can see that in the tool execution path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/agent/tool_call.go"&gt;&lt;code&gt;/Users/yu/go/src/github.com/chowyu12/aiclaw/internal/agent/tool_call.go&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/agent/executor.go"&gt;&lt;code&gt;/Users/yu/go/src/github.com/chowyu12/aiclaw/internal/agent/executor.go&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final assistant response now appends an attachment section with Markdown links such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Attachment List:
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;report.csv&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/public/files/&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;uuid&amp;gt;&lt;/span&gt;)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;chart.png&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;/public/files/&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;uuid&amp;gt;&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the current Chinese codebase revision, that section is rendered as &lt;code&gt;附件列表&lt;/code&gt; in the saved final content.&lt;/p&gt;

&lt;p&gt;The response payload also includes files directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;blocking chat responses now return &lt;code&gt;files&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;streaming &lt;code&gt;done&lt;/code&gt; chunks now include &lt;code&gt;files&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That path is visible in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/model/message.go"&gt;&lt;code&gt;/Users/yu/go/src/github.com/chowyu12/aiclaw/internal/model/message.go&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/handler/chat.go"&gt;&lt;code&gt;/Users/yu/go/src/github.com/chowyu12/aiclaw/internal/handler/chat.go&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/web/src/api/chat.ts"&gt;&lt;code&gt;/Users/yu/go/src/github.com/chowyu12/aiclaw/web/src/api/chat.ts&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the frontend, the chat view turns those file objects into clickable downloads through &lt;code&gt;/public/files/${file.uuid}&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/web/src/views/chat/Index.vue"&gt;&lt;code&gt;/Users/yu/go/src/github.com/chowyu12/aiclaw/web/src/views/chat/Index.vue&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why this matters in practice
&lt;/h2&gt;

&lt;p&gt;This feature is useful anywhere an AIClaw agent produces artifacts instead of pure text.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;code&gt;code_interpreter&lt;/code&gt; task generates a CSV and a PNG chart.&lt;/li&gt;
&lt;li&gt;A browser automation flow saves a screenshot or extracted document.&lt;/li&gt;
&lt;li&gt;A sub-agent writes a research summary file and passes it back to the parent run.&lt;/li&gt;
&lt;li&gt;A shell command creates a log bundle or transformed dataset in the sandbox.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before this improvement, users could still end up asking, “Where did the file go?”&lt;/p&gt;

&lt;p&gt;Now the expected workflow is much cleaner:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The tool runs.&lt;/li&gt;
&lt;li&gt;AIClaw captures the output files.&lt;/li&gt;
&lt;li&gt;The final answer includes explicit download links.&lt;/li&gt;
&lt;li&gt;The API and streamed completion both carry the file metadata.&lt;/li&gt;
&lt;li&gt;The UI renders the attachments as part of the conversation result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That means AIClaw behaves more like a practical work system and less like a text-only chatbot that happens to call tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small detail that matters: sub-agent outputs
&lt;/h2&gt;

&lt;p&gt;One useful part of this change is that file outputs are not limited to the top-level agent.&lt;/p&gt;

&lt;p&gt;The executor now extracts file references from &lt;code&gt;sub_agent&lt;/code&gt; results and folds them back into the parent response. That matters because many real AIClaw workflows split research, scraping, or data prep into delegated tasks. If child artifacts disappear at the parent boundary, the system feels unreliable.&lt;/p&gt;

&lt;p&gt;Bringing those files back into the parent answer makes nested agent execution much easier to trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another practical improvement: better streaming behavior
&lt;/h2&gt;

&lt;p&gt;The same change set also adds SSE ping support in chat streaming handlers. That is separate from attachments, but it helps long-running tool workflows stay alive while the agent is still working.&lt;/p&gt;

&lt;p&gt;For attachment-heavy runs, that pairing is useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;streaming stays active during long tool work&lt;/li&gt;
&lt;li&gt;the final &lt;code&gt;done&lt;/code&gt; chunk can carry the generated files&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I picked this feature
&lt;/h2&gt;

&lt;p&gt;This is a good example of AIClaw’s local-first, tool-oriented design philosophy. The platform is not just trying to produce a nice paragraph. It is trying to complete work and return the artifacts that work produces.&lt;/p&gt;

&lt;p&gt;Generated files are often the real output. Making them first-class in the response path is the right move.&lt;/p&gt;

&lt;p&gt;If you are building with AIClaw, this is the kind of feature that improves daily usability more than another abstract prompt tweak.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>agents</category>
    </item>
    <item>
      <title>AIClaw Separates Persistent Memory From Session Search</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Thu, 25 Jun 2026 11:55:44 +0000</pubDate>
      <link>https://dev.to/chowyu12/aiclaw-separates-persistent-memory-from-session-search-1hnk</link>
      <guid>https://dev.to/chowyu12/aiclaw-separates-persistent-memory-from-session-search-1hnk</guid>
      <description>&lt;p&gt;One of the fastest ways to make an agent messy is to treat every kind of memory as the same thing.&lt;/p&gt;

&lt;p&gt;User preferences, project conventions, environment facts, old debugging sessions, and last week's conversation snippets do not belong in one undifferentiated bucket. AIClaw's current design avoids that by splitting long-term memory into two explicit mechanisms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;persistent memory for durable facts&lt;/li&gt;
&lt;li&gt;session search for historical conversation recall&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That split is worth looking at because it solves real operating problems for self-hosted agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design goal
&lt;/h2&gt;

&lt;p&gt;There are three failure modes that show up quickly in agent systems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;everything is stuffed into the prompt, so context grows until it becomes noisy and expensive&lt;/li&gt;
&lt;li&gt;everything is hidden in a database blob, so operators cannot inspect or edit it cleanly&lt;/li&gt;
&lt;li&gt;old conversations are either forgotten completely or reloaded too aggressively&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AIClaw addresses those problems with two different tools that do two different jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistent memory is stored as editable files
&lt;/h2&gt;

&lt;p&gt;The repository documents persistent memory in &lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/README.md"&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/a&gt; and implements it in &lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/tools/memorytool/memory.go"&gt;&lt;code&gt;internal/tools/memorytool/memory.go&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Instead of hiding long-term memory in opaque storage, AIClaw keeps it in plain text files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MEMORY.md&lt;/code&gt; for durable agent notes, environment facts, and conventions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;USER.md&lt;/code&gt; for user preferences and communication style&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a practical choice. Operators can inspect, review, and edit those files directly when needed, which is much easier than debugging memory behavior through serialized blobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The current session gets a frozen snapshot
&lt;/h2&gt;

&lt;p&gt;AIClaw does not continuously mutate the active system prompt every time memory changes.&lt;/p&gt;

&lt;p&gt;At session start, it loads a snapshot of &lt;code&gt;MEMORY.md&lt;/code&gt; and &lt;code&gt;USER.md&lt;/code&gt; and injects that into the prompt. The loader in &lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/agent/prompt_loaders.go"&gt;&lt;code&gt;internal/agent/prompt_loaders.go&lt;/code&gt;&lt;/a&gt; calls &lt;code&gt;memorytool.LoadSnapshot(...)&lt;/code&gt; and joins the resulting memory blocks into the runtime prompt.&lt;/p&gt;

&lt;p&gt;That means memory writes during a session affect future sessions, not the already-running one.&lt;/p&gt;

&lt;p&gt;This is a strong constraint, and I think it is the right one. It keeps prompt behavior stable inside a run and avoids a hard-to-debug class of issues where the agent silently changes its own instructions halfway through execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory growth is bounded
&lt;/h2&gt;

&lt;p&gt;The memory tool also has explicit limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;MEMORY.md&lt;/code&gt; is capped at 2200 characters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;USER.md&lt;/code&gt; is capped at 1375 characters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When usage gets high enough, AIClaw switches the injected snapshot into an index mode. Instead of pushing full entry bodies into the prompt, it injects a compact list of entry IDs, tags, and short summaries.&lt;/p&gt;

&lt;p&gt;If the agent later needs one of those full entries, it can fetch it explicitly with &lt;code&gt;memory(action=recall, ids=[...])&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That is a smart tradeoff. Long-term memory stays available, but the prompt does not have to pay the full token cost every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory writes are treated as a security surface
&lt;/h2&gt;

&lt;p&gt;This part is easy to miss, but important.&lt;/p&gt;

&lt;p&gt;The memory tool scans content before saving it. The implementation rejects suspicious injection-style patterns and invisible Unicode characters that could be used to smuggle prompt instructions into future sessions.&lt;/p&gt;

&lt;p&gt;That makes sense because memory is not just stored data in AIClaw. It is future system-prompt material.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session search solves a different problem
&lt;/h2&gt;

&lt;p&gt;Persistent memory is for stable facts. Historical conversation lookup is different.&lt;/p&gt;

&lt;p&gt;Sometimes the agent does not need a durable note. It needs to answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What did we discuss in the earlier deployment thread?&lt;/li&gt;
&lt;li&gt;Which error message showed up last time?&lt;/li&gt;
&lt;li&gt;What did the user say about this workflow in a prior session?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is what &lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/tools/sessionsearch/session_search.go"&gt;&lt;code&gt;internal/tools/sessionsearch/session_search.go&lt;/code&gt;&lt;/a&gt; is for.&lt;/p&gt;

&lt;p&gt;The tool has two modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no query: return recent conversations with previews&lt;/li&gt;
&lt;li&gt;query provided: search prior messages and return matching snippets&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SQLite gets FTS5, other databases still work
&lt;/h2&gt;

&lt;p&gt;The search implementation in &lt;a href="///Users/yu/go/src/github.com/chowyu12/aiclaw/internal/store/gormstore/fts.go"&gt;&lt;code&gt;internal/store/gormstore/fts.go&lt;/code&gt;&lt;/a&gt; adds a practical optimization.&lt;/p&gt;

&lt;p&gt;When AIClaw runs on SQLite, it initializes an FTS5 virtual table plus triggers to keep the search index synchronized with new and deleted messages. It also backfills existing data on startup.&lt;/p&gt;

&lt;p&gt;When FTS5 is unavailable, AIClaw falls back to a SQL &lt;code&gt;LIKE&lt;/code&gt; search path.&lt;/p&gt;

&lt;p&gt;That is exactly the kind of graceful degradation I want in a local-first system. SQLite gets a fast search path, but the feature does not disappear on other databases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the split matters operationally
&lt;/h2&gt;

&lt;p&gt;This is the real value of the feature:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;durable facts go into editable memory files&lt;/li&gt;
&lt;li&gt;old conversation details stay in searchable archives&lt;/li&gt;
&lt;li&gt;the active prompt remains more compact&lt;/li&gt;
&lt;li&gt;and both behaviors are explicit enough to inspect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is better than trying to solve all recall problems with one giant "memory" abstraction.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical workflow
&lt;/h2&gt;

&lt;p&gt;If I were operating AIClaw day to day, I would use it like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save stable rules, preferences, and environment facts with the &lt;code&gt;memory&lt;/code&gt; tool.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;session_search&lt;/code&gt; when you need to retrieve something from older conversations.&lt;/li&gt;
&lt;li&gt;Let the snapshot and index-mode design keep the active prompt lean.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a more durable model for long-running agents than simply loading more chat history and hoping the model figures out what still matters.&lt;/p&gt;

&lt;p&gt;AIClaw's memory layer is not flashy, but it is disciplined. For self-hosted agent systems, that discipline is usually what keeps advanced features usable after the first demo.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>agents</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How AIClaw Extends Agents with Custom Tools and MCP Servers</title>
      <dc:creator>chowyu</dc:creator>
      <pubDate>Tue, 23 Jun 2026 11:54:53 +0000</pubDate>
      <link>https://dev.to/chowyu12/how-aiclaw-extends-agents-with-custom-tools-and-mcp-servers-6cm</link>
      <guid>https://dev.to/chowyu12/how-aiclaw-extends-agents-with-custom-tools-and-mcp-servers-6cm</guid>
      <description>&lt;p&gt;Most agent demos look flexible until you need them to talk to your own systems.&lt;/p&gt;

&lt;p&gt;That is where AIClaw takes a practical route. The project ships with a broad built-in toolset, but it also lets you extend agents through custom HTTP tools, script tools, and MCP servers without changing the core runtime.&lt;/p&gt;

&lt;p&gt;This is not a new feature announcement. It is an existing part of the current repository that is worth a deeper look because it changes what an AIClaw deployment can actually do in day-to-day work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: built-ins are not enough
&lt;/h2&gt;

&lt;p&gt;Built-in tools cover the common cases well: files, shell, browser automation, web search, web fetch, memory, session search, scheduled jobs, code interpretation, and sub-agents.&lt;/p&gt;

&lt;p&gt;But real deployments usually need one more layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call an internal HTTP API.&lt;/li&gt;
&lt;li&gt;Wrap a small script around an existing operational workflow.&lt;/li&gt;
&lt;li&gt;Reuse external MCP tools from another server process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without that layer, the agent can reason, but it cannot reach the systems that matter in your environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  AIClaw's extension model
&lt;/h2&gt;

&lt;p&gt;The current README describes AIClaw's tool system as a combination of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;built-in tools&lt;/li&gt;
&lt;li&gt;custom HTTP tools&lt;/li&gt;
&lt;li&gt;custom command tools&lt;/li&gt;
&lt;li&gt;MCP server tools&lt;/li&gt;
&lt;li&gt;skill-defined tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the runtime, those paths are normalized into the same execution flow.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;internal/agent/tool.go&lt;/code&gt; builds tracked tools from the configured definitions. Built-ins get their native handlers, HTTP tools are wrapped with &lt;code&gt;NewHTTPHandler&lt;/code&gt;, command tools use &lt;code&gt;NewCommandHandler&lt;/code&gt;, script tools use &lt;code&gt;NewScriptHandler&lt;/code&gt;, and MCP tools are loaded from connected servers before the model call.&lt;/p&gt;

&lt;p&gt;That matters because extension points do not become second-class behavior. They still participate in the same execution loop, step tracking, and agent prompt assembly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom tools from the web console
&lt;/h2&gt;

&lt;p&gt;The current tool management UI gives you a practical authoring flow instead of requiring hand-written runtime config.&lt;/p&gt;

&lt;p&gt;On the Tools page you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a tool with a name, description, timeout, and enabled state.&lt;/li&gt;
&lt;li&gt;Choose a handler type.&lt;/li&gt;
&lt;li&gt;Define the function schema that the model will see.&lt;/li&gt;
&lt;li&gt;Bind the tool to agents that should be allowed to call it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The form currently exposes two handler types directly in the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP Callback&lt;/li&gt;
&lt;li&gt;Script&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For HTTP tools, AIClaw lets you define a request URL and method, with &lt;code&gt;{param_name}&lt;/code&gt; placeholders that are substituted from model-supplied arguments at runtime.&lt;/p&gt;

&lt;p&gt;For script tools, the form supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;Shell&lt;/li&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same page also lets you describe the function in a structured way or switch to raw JSON mode for the full function definition.&lt;/p&gt;

&lt;p&gt;That is a useful design choice. It keeps the operational handler config and the model-visible function schema separate, which makes tools easier to tune without rewriting everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP servers as first-class runtime inputs
&lt;/h2&gt;

&lt;p&gt;AIClaw also has a dedicated MCP management page.&lt;/p&gt;

&lt;p&gt;The current MCP settings flow supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;stdio&lt;/code&gt; transport&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sse&lt;/code&gt; transport&lt;/li&gt;
&lt;li&gt;endpoint configuration&lt;/li&gt;
&lt;li&gt;argument lists&lt;/li&gt;
&lt;li&gt;enabled or disabled state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The runtime API behind that page is straightforward: &lt;code&gt;GET /api/v1/runtime/mcp&lt;/code&gt; reads the workspace MCP list, and &lt;code&gt;PUT /api/v1/runtime/mcp&lt;/code&gt; replaces it.&lt;/p&gt;

&lt;p&gt;The runtime side is more interesting.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;internal/tools/mcp/client.go&lt;/code&gt; connects to each enabled MCP server, initializes the client, lists available tools, and then exposes them to the agent executor. In &lt;code&gt;internal/agent/executor.go&lt;/code&gt;, MCP tools are connected before execution so they can be merged into the available tool set for the request.&lt;/p&gt;

&lt;p&gt;This gives AIClaw two useful extension paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create narrow custom tools inside AIClaw when the integration is simple&lt;/li&gt;
&lt;li&gt;mount an external MCP server when the tool suite already exists elsewhere&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Safety and operability details that matter
&lt;/h2&gt;

&lt;p&gt;The implementation is more pragmatic than flashy, and that is a good thing.&lt;/p&gt;

&lt;p&gt;A few concrete examples from the current codebase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP tool calls use a shared HTTP client with connection pooling instead of rebuilding a client on every invocation.&lt;/li&gt;
&lt;li&gt;Command tools apply additional safety checks on top of the normal shell safeguards, including blocking patterns like outbound shell access and risky recursive deletes.&lt;/li&gt;
&lt;li&gt;Tool calls are wrapped as tracked steps, so custom and MCP-backed calls show up in the same execution timeline as built-ins.&lt;/li&gt;
&lt;li&gt;The MCP manager is reused at the executor level instead of being torn down after every request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not marketing details. They are the difference between "extensible in theory" and "usable under load".&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical workflow
&lt;/h2&gt;

&lt;p&gt;If you want to extend an AIClaw agent today, the workflow is roughly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with the smallest possible integration.&lt;/li&gt;
&lt;li&gt;If the system is just one API call, create a custom HTTP tool.&lt;/li&gt;
&lt;li&gt;If the integration needs local logic, wrapping, or formatting, use a script tool.&lt;/li&gt;
&lt;li&gt;If you already have a larger tool surface implemented elsewhere, register it as an MCP server.&lt;/li&gt;
&lt;li&gt;Attach only the needed tools to the target agent.&lt;/li&gt;
&lt;li&gt;Inspect the execution log after real runs to verify the tool contract is clear enough for the model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A good example is an internal support workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one HTTP tool for looking up a ticket by ID&lt;/li&gt;
&lt;li&gt;one script tool for normalizing the raw result into a concise summary&lt;/li&gt;
&lt;li&gt;one MCP server for a broader internal knowledge or operations toolkit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That combination keeps the default agent prompt small while still giving the agent a path into real systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;The strongest agent products are not the ones with the longest built-in tool list. They are the ones that let you adapt the tool surface to your own environment without fighting the runtime.&lt;/p&gt;

&lt;p&gt;AIClaw's current design gets that mostly right:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;built-ins for common work&lt;/li&gt;
&lt;li&gt;custom tools for narrow integrations&lt;/li&gt;
&lt;li&gt;MCP for external tool ecosystems&lt;/li&gt;
&lt;li&gt;shared execution logging so everything stays inspectable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are building self-hosted agents, that is the layer that turns a chat UI into an actual operations surface.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/chowyu12/aiclaw" rel="noopener noreferrer"&gt;AIClaw on GitHub&lt;/a&gt;&lt;/p&gt;

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