@nopeek/agent-bridge 0.6.2 → 0.6.3
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/dist/bot.d.ts +4 -0
- package/dist/bot.js +20 -6
- package/dist/bridge.d.ts +1 -1
- package/dist/bridge.js +1 -1
- package/package.json +1 -1
package/dist/bot.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare class BotRunner {
|
|
|
27
27
|
private declined;
|
|
28
28
|
private ownerPresence;
|
|
29
29
|
private mutedNoOwner;
|
|
30
|
+
private runtimeOwnerId;
|
|
30
31
|
private chains;
|
|
31
32
|
private cantPost;
|
|
32
33
|
private log;
|
|
@@ -46,6 +47,9 @@ export declare class BotRunner {
|
|
|
46
47
|
refreshAccess(): Promise<void>;
|
|
47
48
|
/** Sender permitted to talk to this bot? Fail closed if access never loaded. */
|
|
48
49
|
private isAllowed;
|
|
50
|
+
/** The USER whose presence the owner-present policy requires: the bot's
|
|
51
|
+
* owner for user-owned bots, else the user who paired this runtime. */
|
|
52
|
+
private effectiveOwnerId;
|
|
49
53
|
/** Is the bot's owner currently a member of this channel? Server-checked via
|
|
50
54
|
* the channel roster (the bot is a member, so it may list members), cached
|
|
51
55
|
* for a short TTL, invalidated by member.joined/left. On a fetch failure we
|
package/dist/bot.js
CHANGED
|
@@ -39,6 +39,10 @@ export class BotRunner {
|
|
|
39
39
|
// server per channel and cached briefly; member.joined/left invalidate it.
|
|
40
40
|
ownerPresence = new Map();
|
|
41
41
|
mutedNoOwner = new Set(); // channels already logged as owner-absent
|
|
42
|
+
// For a workspace-owned bot there is no single owner USER — the accountable
|
|
43
|
+
// human is whoever paired the runtime that runs it. The access endpoint
|
|
44
|
+
// reports that as runtimeOwnerUserId; the owner-present policy uses it.
|
|
45
|
+
runtimeOwnerId;
|
|
42
46
|
// Per-channel serialization: two messages in one channel must be answered in
|
|
43
47
|
// order, one at a time — concurrent brain runs against the same agent session
|
|
44
48
|
// (e.g. one Hermes session per channel) deadlock or reply out of order.
|
|
@@ -107,6 +111,8 @@ export class BotRunner {
|
|
|
107
111
|
throw new Error(`access HTTP ${res.status}`);
|
|
108
112
|
const j = (await res.json());
|
|
109
113
|
this.allowed = new Set(j.allowedUserIds ?? []);
|
|
114
|
+
if (j.runtimeOwnerUserId)
|
|
115
|
+
this.runtimeOwnerId = j.runtimeOwnerUserId;
|
|
110
116
|
// The access response is authoritative on ownership — adopt it so the
|
|
111
117
|
// owner-present policy always knows who the owner is, even when the
|
|
112
118
|
// runtime/bots listing omitted the fields.
|
|
@@ -129,12 +135,19 @@ export class BotRunner {
|
|
|
129
135
|
return false; // fail closed until we know the list
|
|
130
136
|
return this.allowed.has(senderUserId);
|
|
131
137
|
}
|
|
138
|
+
/** The USER whose presence the owner-present policy requires: the bot's
|
|
139
|
+
* owner for user-owned bots, else the user who paired this runtime. */
|
|
140
|
+
effectiveOwnerId() {
|
|
141
|
+
if (this.info.ownerType === "workspace")
|
|
142
|
+
return this.runtimeOwnerId;
|
|
143
|
+
return this.info.ownerId ?? this.runtimeOwnerId;
|
|
144
|
+
}
|
|
132
145
|
/** Is the bot's owner currently a member of this channel? Server-checked via
|
|
133
146
|
* the channel roster (the bot is a member, so it may list members), cached
|
|
134
147
|
* for a short TTL, invalidated by member.joined/left. On a fetch failure we
|
|
135
148
|
* keep the last-known answer; with no known answer we FAIL CLOSED. */
|
|
136
149
|
async ownerIsChannelMember(channelId) {
|
|
137
|
-
const ownerId = this.
|
|
150
|
+
const ownerId = this.effectiveOwnerId();
|
|
138
151
|
if (!ownerId)
|
|
139
152
|
return false; // unknown owner → fail closed
|
|
140
153
|
const cached = this.ownerPresence.get(channelId);
|
|
@@ -214,7 +227,7 @@ export class BotRunner {
|
|
|
214
227
|
if (!p?.channelId)
|
|
215
228
|
return;
|
|
216
229
|
this.ownerPresence.delete(p.channelId);
|
|
217
|
-
if (p.userId && p.userId === this.
|
|
230
|
+
if (p.userId && p.userId === this.effectiveOwnerId()) {
|
|
218
231
|
this.mutedNoOwner.delete(p.channelId); // re-log if the owner leaves again later
|
|
219
232
|
this.log(`owner membership changed in ${p.channelId} — presence cache invalidated`);
|
|
220
233
|
}
|
|
@@ -311,15 +324,16 @@ export class BotRunner {
|
|
|
311
324
|
// OWNER-PRESENT POLICY: in a multi-party channel (anything but a direct
|
|
312
325
|
// chat), a non-owner sender may use the bot ONLY while the bot's owner is
|
|
313
326
|
// also a member of that channel. Owner absent → completely silent (no
|
|
314
|
-
// brain run, not even the decline notice), regardless of grants.
|
|
315
|
-
//
|
|
316
|
-
|
|
327
|
+
// brain run, not even the decline notice), regardless of grants. For a
|
|
328
|
+
// workspace bot "owner" means the user who paired this runtime.
|
|
329
|
+
const effOwner = this.effectiveOwnerId();
|
|
330
|
+
if (m.senderUserId !== effOwner) {
|
|
317
331
|
const ch = await this.getChannel(m.channelId);
|
|
318
332
|
if (ch.record.kind !== "direct") {
|
|
319
333
|
if (!(await this.ownerIsChannelMember(m.channelId))) {
|
|
320
334
|
if (!this.mutedNoOwner.has(m.channelId)) {
|
|
321
335
|
this.mutedNoOwner.add(m.channelId);
|
|
322
|
-
this.log(`muting ${m.channelId} — owner ${
|
|
336
|
+
this.log(`muting ${m.channelId} — owner ${effOwner ?? "?"} is not a member (owner-present policy); staying silent`);
|
|
323
337
|
}
|
|
324
338
|
return;
|
|
325
339
|
}
|
package/dist/bridge.d.ts
CHANGED
package/dist/bridge.js
CHANGED
|
@@ -17,7 +17,7 @@ import { resolveBrain } from "./brain.js";
|
|
|
17
17
|
import { provisionSoul, provisionHermesProfile } from "./backends.js";
|
|
18
18
|
import { reportCapabilities } from "./capabilities.js";
|
|
19
19
|
import { isBrainBackend } from "./config.js";
|
|
20
|
-
export const VERSION = "0.6.
|
|
20
|
+
export const VERSION = "0.6.3";
|
|
21
21
|
/** How often to re-probe + report brain availability to the server. */
|
|
22
22
|
const CAPABILITIES_INTERVAL_MS = 5 * 60_000;
|
|
23
23
|
export class PairError extends Error {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nopeek/agent-bridge",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Run your own agents as E2EE NoPeek bots. Pairs with one-time codes (multiple accounts per computer), runs every bot each account owns, and pipes messages to any command or webhook.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|