Calling relay.Auth() immediately after RelayConnect signed an auth event
with an empty challenge tag. go-nostr keeps the relay's challenge on an
unexported field populated by its reader goroutine when the AUTH envelope
arrives, so the value is not yet set at connect time, and relays reject
the resulting event.
Subscribe first and run the handshake only once the relay answers
"auth-required". That guarantees the challenge has been read: the CLOSED
envelope is processed after AUTH on the relay's single reader goroutine,
and receiving it over a channel establishes the happens-before edge that
makes the read safe.
A second rejection after authenticating is a permissions failure rather
than a mistimed handshake, so it fails instead of retrying. Both waits
are bounded by a 15s timeout, and relays that accept without auth still
work via EndOfStoredEvents.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>