peerd-preview-v0.2.2
Added
- The dweb actor: a dedicated, opt-in mesh operator (preview only). When
the network is on, a second toggle spins up a persistent, keyless agent in
its own worker heap. It absorbs the dweb tools (discover / share / install /
block / peers / discovery), keeps a peer-and-publisher reputation ledger,
and monitors messages addressed to your agent, surfacing only what's
notable. It's addressable in chat asmessage_actor("dweb", …). It can
never be made to act by an inbound message: inbound turns may only observe,
use its own tools, and report. It installs or shares only with your
confirmation. With it on, the mesh tools leave the orchestrator entirely.
Mesh work is one delegation.
Fixed
- The global instance reads are now fenced.
js_read_fileand
app_read_filestay on the orchestrator, so files can be inspected cheaply
without an actor turn, but their content now comes back inside the
wrapUntrustedfence. An instance file is not reliably agent-authored:
notebook/app code fetches and persists web data. So an unfenced read was
the last remaining way for untrusted bytes to reach the orchestrator's
trusted context.js_rungets the same treatment: output from a
pure-compute run stays raw (it is the agent's own code), but a run that
calledpeerd.egress.fetchhas its value, console, and error text fenced.
Added
- Actor replies now surface in the chat as their own messages. When a
delegated actor (web / WebVM / Notebook / App) replies, the reply appears
at its place in the conversation as a quiet, attributed bubble ("notebook
actor · Esoteric Math"). Before, it was buried inside themessage_actor
tool card of an earlier turn. Failures show the same way, marked failed. - Notebook heatmap charts.
chart({ type: 'heatmap', data, x, y, v })
frompeerd:stdrenders a density grid: rows of{ x, y, v }bins shaded
byv. This was the missing chart kind that agents kept building with
hand-rolled Vega specs. - Notebook errors point at your code. A run error's stack now maps back
tonotebook.js:<line>(both in the output pane and in the agent's tool
result) instead of showing internal blob-URL frames. Applies to the
headlessjs_runpath too (job.js:<line>). - Notebook iteration feel. When a new run starts, the previous run's
output stays visible but dims. Consecutive runs read like a loop while
every realm stays fresh. The toolbar also gains apeerd:std ?cheat
sheet: the import line, the chart spec, and the full helper list at a
glance.
Changed
- The heap split. Every non-orchestrator agent loop now runs in its own
dedicated offscreen Worker heap. Bound actors (web / WebVM / Notebook /
App) and subagents (both tool-less reasoning and tool-bearing) run keyless,
in isolated memory. They reach the model and their tools only through
service-worker routes that re-check every call. Untrusted page, instance,
and response content stays in the actor's heap. It cannot reach the vault
key or the orchestrator's memory. The "actor fence" went from a prompt
boundary in one shared heap to a real memory boundary, the correct answer to
prompt injection: the loop that reads hostile content never holds the
authority to act on it. One substrate, one
code path: a subagent is an ephemeral actor, so the former reasoning and
actor stacks collapsed into one. Chrome-only (it needs the offscreen API);
Firefox falls back to the keyless in-SW loop until it has one.
Fixed
- A subagent could be granted the actor-only DOM/page tools (
read_page,
page_exec,click,navigate,fetch_url, …) and read or drive the
user's foreground tab. That is authority the main agent itself lacks. A
subagent's grantable toolset is now narrowed from the main-agent surface,
so it holds a subset of what its parent holds and delegates web/DOM work
to the web actor like the main agent does. - The vault-gate code-stream backdrop left faint lighter-than-black bands on
every row it had ever typed on (the alpha-wash fade only asymptotes toward
the background). The animation now redraws from state each frame and
trails decay to exactly zero. Idle rows are indistinguishable from
untouched background. - A Notebook run that returned a huge unrecognized object (e.g. a
hand-rolled Vega-Lite spec) dumped the entire JSON, hundreds of KB, into
the output pane, and the model's copy of the value was blind-truncated
mid-JSON. The pane dump is now capped with a note, and the tool result's
[VALUE]block is cut cleanly at the source, with an actionable
instruction to return a compact value or achart()/table()descriptor. peerd.self.import('peerd:std')failed ("cannot resolve"). The dynamic
import shim routed builtins through the OPFS compose path, where a builtin
has no file. Builtins now import their real URL directly, matching the
static resolver.
Install (preview): Firefox: click the .xpi on this page. Chrome: drag the .crx into chrome://extensions with Developer mode on. Most users want the store packages (see the README). The auto-update feeds are attached here and served at peerd.ai/updates/.