The go-nostr RelayConnect returns immediately after the WebSocket
handshake, but the relay has not yet sent the AUTH challenge. Calling
relay.Auth() right away signs the auth event with an empty challenge
tag, which the Buzz relay rejects permanently ('verification failed'
then 'authentication already failed' on retries).
Add a 2s sleep between RelayConnect and Auth() to give the background
read loop time to receive and store the challenge. The relay typically
delivers it within a few hundred milliseconds.
Implements a Buzz channel backed by a Nostr relay:
- kind:9 events scoped by "h" tag, "p" tags for mentions
- NIP-42 (kind:22242) auth before subscription
- optional threaded replies via "e" tag
- registered as config.ChannelBuzz with BuzzSettings
#3150 reworded write_file's description, overwrite parameter, and guard
error to prefer append_file/edit_file. But those tools register via their
own enable flags and the per-agent allowlist, so a config exposing only
write_file was steered toward tools it does not have — a dead end in the
most restrictive setups.
WriteFileTool now tracks which non-destructive alternatives are available
and names only the ones present; when none are, the guard still blocks the
overwrite without pointing anywhere. The agent wiring registers the editors
before write_file and resolves availability via registry.HasRegistered,
which reflects both the enable flag and the allowlist.
Tests: conditional copy at the tool level (none/one/both) and agent wiring
across the enable-flag and allowlist dimensions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ToolCall.Name and .Arguments are json:"-" (runtime-only), so after chat
history round-trips through the session store only ToolCall.Function
survives. The anthropic-messages and anthropic (SDK) providers emitted
tool_use blocks from tc.Name alone, silently skipping every historical
tool call while still emitting the matching tool_result — orphaned
tool_results 400 at the API ("unexpected tool_use_id found in
tool_result blocks"), killing every turn on agents with tool history.
Fall back to Function.Name / json-parsed Function.Arguments (the same
pattern the bedrock and openai_compat providers already use), and cover
the deserialized-history shape with table tests in both providers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The overwrite guard error ("Set overwrite=true to replace") steered the
model to clobber files like MEMORY.md. Reword write_file's description,
overwrite param, and guard error to prefer append_file/edit_file.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address review feedback: the routed-agent /clear path bypassed the
public ContextManager.Clear contract via an unexported hook. Restore
the single Clear call in the command path and resolve the session's
owning agent inside the built-in implementations instead:
- legacy: Clear resolves the owning agent via agentForSession instead
of assuming the default agent
- seahorse: drop ClearContextStore; Clear wipes the engine state and
the owning agent's session store
- command path: persist session scope metadata before Clear so
ownership resolves even when /clear is the session's first message
- add coverage that a custom ContextManager receives Clear for routed
agents
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Previously when io.Copy to the base64 encoder failed, encoder.Close()
was skipped. This left the encoder's internal buffer unflushed.
Now always call Close() and handle both copy and close errors
explicitly.