eleven / ocho Public

web: refresh roster on unknown-thread messages; agent: default to Sonnet (#56)

- chat.js: a WS message for a thread we don't know reloads threads but not
  the roster, so a first-contact sender (new joiner's DM, a bot's welcome)
  rendered as "Someone" until a full reload. Refresh the roster there too.
- Bots default to claude-sonnet-5 (was Opus) — cheaper, and the default
  personas don't need deep reasoning; per-bot console config still picks
  any model. Admin dropdown + README follow.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 66aa5a0c42de29e0f71e22eccb51ae3ee1518eb1 parent 0230692
5 files changed, +8 −3
  • agent/README.md +1 −1
  • agent/config.mjs +1 −1
  • changelog/2026-07-02-someone-label.md +1 −0
  • web/pages/admin.html +1 −1
  • web/static/chat.js +4 −0
diff --git a/agent/README.md b/agent/README.md
index e630335..868ceca 100644
--- a/agent/README.md
+++ b/agent/README.md
@@ -25,7 +25,7 @@ console, its `#fragment` passed once as the matching `*_INVITE` env var.
| `LCHAT_INVITE` | **One-time.** The `#fragment` of a `/join/…` link minted in the admin console (tick "This is an agent"). Spent after provisioning. |
Optional: `LCHAT_AGENT_NAME` (default `Claude`), `LCHAT_MODEL` (default
-`claude-opus-4-8`; try `claude-sonnet-5` for lower cost), `LCHAT_SYSTEM` (system
+`claude-sonnet-5`; try `claude-opus-4-8` when a bot needs deeper reasoning), `LCHAT_SYSTEM` (system
prompt), `LCHAT_SESSION` (session-file path).
## Run
diff --git a/agent/config.mjs b/agent/config.mjs
index 49c501e..db65464 100644
--- a/agent/config.mjs
+++ b/agent/config.mjs
@@ -12,7 +12,7 @@ export const BASE = (process.env.LCHAT_BASE || "").replace(/\/$/, "");
export const WS_BASE = BASE.replace(/^http/, "ws");
export const AGENT_NAME = process.env.LCHAT_AGENT_NAME || "Claude";
-export const MODEL = process.env.LCHAT_MODEL || "claude-opus-4-8";
+export const MODEL = process.env.LCHAT_MODEL || "claude-sonnet-5";
// Session lives next to this module by default so `node agent.mjs` works from
// any cwd; override with LCHAT_SESSION.
diff --git a/changelog/2026-07-02-someone-label.md b/changelog/2026-07-02-someone-label.md
new file mode 100644
index 0000000..2463b6d
--- /dev/null
+++ b/changelog/2026-07-02-someone-label.md
@@ -0,0 +1 @@
+Fixed: a first-time chat from someone new (like a helper saying hi) no longer shows as "Someone" until you refresh.
diff --git a/web/pages/admin.html b/web/pages/admin.html
index fdb7bfd..7b433f2 100644
--- a/web/pages/admin.html
+++ b/web/pages/admin.html
@@ -69,7 +69,7 @@
<input id="agentLabel" placeholder="Bot name (e.g. Claude)" maxlength="60" style="display:block;width:100%;margin:0 0 8px" />
<input id="agentDescription" placeholder="What this helper does, in one line — members see this in the Helpers list" maxlength="200" style="display:block;width:100%;margin:0 0 8px" />
<select id="agentModel" style="display:block;width:100%;margin:0 0 8px">
- <option value="">Default model (Opus)</option>
+ <option value="">Default model (Sonnet)</option>
<option value="claude-opus-4-8">Opus — most capable</option>
<option value="claude-sonnet-5">Sonnet — balanced</option>
<option value="claude-haiku-4-5">Haiku — fast &amp; cheap</option>
diff --git a/web/static/chat.js b/web/static/chat.js
index 6b05157..6062ff9 100644
--- a/web/static/chat.js
+++ b/web/static/chat.js
@@ -2884,6 +2884,10 @@ function connectWS() {
// mode the native sidebar owns the other threads and we have no private key to
// unwrap them, so ignore anything but the active thread.
if (embed) return;
+ // The sender may be someone we haven't seen either (a new joiner's first DM,
+ // a bot like Eleven welcoming us) — without a roster refresh they render as
+ // "Someone" until the next full reload.
+ await loadRoster();
await loadThreads();
renderThreadList();
return;