@1presence/bridge 0.74.0 → 0.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/claude.js +6 -1
- package/dist/config.js +3 -6
- package/dist/index.js +17 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,9 +53,11 @@ Your OAuth tokens and vault data stay server-side — nothing sensitive is store
|
|
|
53
53
|
|
|
54
54
|
## Model
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
**Every start** the bridge asks which Claude model to use — the choice is held in memory for that run only and nothing is written to disk, so restarting always asks again. Pick "Use Claude Code default" to defer to your local Claude Code default, or pin one of the latest models per family: `claude-opus-5`, `claude-fable-5`, `claude-sonnet-5`, `claude-haiku-4-5`. If the prompt times out it auto-selects "Use Claude Code default", which tracks whatever model Claude Code serves for your plan.
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
Superseded versions (`claude-opus-4-8`, `claude-sonnet-4-6`, …) are deliberately not listed. If you need something other than the latest, use "Use Claude Code default" and set the model in Claude Code itself.
|
|
59
|
+
|
|
60
|
+
Every reply prints the model, the account it ran for, and your context/cost usage, so you can always see what is running — and if the model that answered isn't the one you pinned, the bridge says so explicitly. Note that only **one bridge per account** serves your turns: start a second one and the older process exits, because otherwise your turns could be answered by a terminal you aren't watching, on the model *it* pinned.
|
|
59
61
|
|
|
60
62
|
## Signing out
|
|
61
63
|
|
package/dist/claude.js
CHANGED
|
@@ -258,15 +258,20 @@ export function spawnClaude(params) {
|
|
|
258
258
|
extractedModel = model;
|
|
259
259
|
if (ccv)
|
|
260
260
|
cliVersion = ccv;
|
|
261
|
+
const pinnedAtStartup = getBridgeModel();
|
|
262
|
+
const pinHonoured = !!pinnedAtStartup && !!model && model === pinnedAtStartup;
|
|
261
263
|
if (!modelAnnounced) {
|
|
262
264
|
const source = keySource === 'none' || !keySource ? 'claude.ai subscription' : keySource;
|
|
263
|
-
const pin =
|
|
265
|
+
const pin = pinHonoured ? ' (selected at startup)' : '';
|
|
264
266
|
process.stdout.write(`\n model: ${model ?? 'unknown'}${pin}\n auth: ${source}\n\n`);
|
|
265
267
|
modelAnnounced = true;
|
|
266
268
|
}
|
|
267
269
|
else {
|
|
268
270
|
process.stderr.write(`[bridge] model: ${model ?? 'unknown'} apiKeySource: ${keySource ?? 'none'}\n`);
|
|
269
271
|
}
|
|
272
|
+
if (pinnedAtStartup && model && model !== pinnedAtStartup) {
|
|
273
|
+
process.stderr.write(`[bridge] WARNING: ${pinnedAtStartup} was selected at startup, but this turn ran on ${model}.\n`);
|
|
274
|
+
}
|
|
270
275
|
sessionIdExtracted = true;
|
|
271
276
|
}
|
|
272
277
|
if (type === 'assistant') {
|
package/dist/config.js
CHANGED
|
@@ -60,12 +60,9 @@ function detectClaudeDefaultModel() {
|
|
|
60
60
|
const MODEL_OPTIONS = [
|
|
61
61
|
{ num: 1, model: null, label: 'Use Claude Code default' },
|
|
62
62
|
{ num: 2, model: 'claude-opus-5', label: 'claude-opus-5' },
|
|
63
|
-
{ num: 3, model: 'claude-
|
|
64
|
-
{ num: 4, model: 'claude-
|
|
65
|
-
{ num: 5, model: 'claude-
|
|
66
|
-
{ num: 6, model: 'claude-sonnet-5', label: 'claude-sonnet-5' },
|
|
67
|
-
{ num: 7, model: 'claude-sonnet-4-6', label: 'claude-sonnet-4-6' },
|
|
68
|
-
{ num: 8, model: 'claude-haiku-4-5', label: 'claude-haiku-4-5' },
|
|
63
|
+
{ num: 3, model: 'claude-fable-5', label: 'claude-fable-5' },
|
|
64
|
+
{ num: 4, model: 'claude-sonnet-5', label: 'claude-sonnet-5' },
|
|
65
|
+
{ num: 5, model: 'claude-haiku-4-5', label: 'claude-haiku-4-5' },
|
|
69
66
|
];
|
|
70
67
|
const PROMPT_TIMEOUT_MS = 10_000;
|
|
71
68
|
const DEFAULT_OPTION_NUM = 1;
|
package/dist/index.js
CHANGED
|
@@ -383,7 +383,8 @@ async function handleMessage(conversationId, text, sessionId, history, auth, vau
|
|
|
383
383
|
const costSeg = sessionCostUsd > 0 ? `$${sessionCostUsd.toFixed(2)} session` : 'plan usage';
|
|
384
384
|
const ver = getCliVersion();
|
|
385
385
|
const verSeg = ver ? ` v${ver}` : '';
|
|
386
|
-
|
|
386
|
+
const whoSeg = currentAuth?.email ? ` | 👤 ${currentAuth.email}` : '';
|
|
387
|
+
console.log(paint('90', ` 🤖 ${friendlyModelName(model)}${verSeg} | 🧠 ${ctxPct}% | 💰 ${costSeg}${whoSeg}`));
|
|
387
388
|
const windows = [
|
|
388
389
|
formatWindow('5h', getRateLimitWindow('five_hour')),
|
|
389
390
|
formatWindow('7d', sevenDayWindow()),
|
|
@@ -450,7 +451,11 @@ const PING_INTERVAL_MS = 30_000;
|
|
|
450
451
|
const PONG_TIMEOUT_MS = 10_000;
|
|
451
452
|
function connect(auth, retryDelay = 1000) {
|
|
452
453
|
const ws = new WebSocket(GATEWAY_WS, {
|
|
453
|
-
headers: {
|
|
454
|
+
headers: {
|
|
455
|
+
Authorization: `Bearer ${auth.token}`,
|
|
456
|
+
'X-Bridge-Capabilities': 'displace-4004',
|
|
457
|
+
'X-Bridge-Version': version,
|
|
458
|
+
},
|
|
454
459
|
});
|
|
455
460
|
let pingTimer = null;
|
|
456
461
|
let pongTimer = null;
|
|
@@ -546,6 +551,16 @@ function connect(auth, retryDelay = 1000) {
|
|
|
546
551
|
console.error('Local Claude Code is not enabled for your account. To request access, email hello@1presence.com.');
|
|
547
552
|
process.exit(1);
|
|
548
553
|
}
|
|
554
|
+
if (code === 4004) {
|
|
555
|
+
if (ws !== currentWs) {
|
|
556
|
+
console.log('[bridge] ignoring a "replaced" close for a socket we already reconnected past.');
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
console.log('\nAnother 1Presence bridge connected for this account — this one has exited.');
|
|
560
|
+
console.log('Local Mode runs one bridge per account: the newest connection serves your turns.');
|
|
561
|
+
killAll();
|
|
562
|
+
process.exit(0);
|
|
563
|
+
}
|
|
549
564
|
scheduleReconnect(code, retryDelay);
|
|
550
565
|
});
|
|
551
566
|
ws.on('error', (err) => {
|