@drisp/cli 0.4.4 → 0.4.5
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/athena-gateway.js +195 -160
- package/dist/{chunk-6TJHAUNB.js → chunk-M44KEGM7.js} +15 -3
- package/dist/{chunk-JAPBSL7D.js → chunk-PJUDHH4R.js} +275 -148
- package/dist/cli.js +112 -4
- package/dist/dashboard-daemon.js +1 -1
- package/package.json +1 -1
package/dist/athena-gateway.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
loadOrCreateToken,
|
|
5
5
|
requireTokenForBind,
|
|
6
6
|
timingSafeTokenEqual
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-M44KEGM7.js";
|
|
8
8
|
import {
|
|
9
9
|
CHANNEL_REQUEST_ID_REGEX,
|
|
10
10
|
createUdsServerTransport,
|
|
@@ -353,11 +353,11 @@ function makeFrameId() {
|
|
|
353
353
|
}
|
|
354
354
|
|
|
355
355
|
// src/gateway/adapters/console/adapter.ts
|
|
356
|
-
var
|
|
356
|
+
var CONSOLE_DEFAULT_ID = "console";
|
|
357
357
|
var CLIENT_NAME = "athena-cli";
|
|
358
358
|
var CLIENT_VERSION = "0.0.0";
|
|
359
359
|
var ConsoleAdapter = class {
|
|
360
|
-
id
|
|
360
|
+
id;
|
|
361
361
|
capabilities = {
|
|
362
362
|
chat: true,
|
|
363
363
|
threads: true,
|
|
@@ -369,8 +369,9 @@ var ConsoleAdapter = class {
|
|
|
369
369
|
ctx = null;
|
|
370
370
|
pendingPermissions = /* @__PURE__ */ new Map();
|
|
371
371
|
pendingQuestions = /* @__PURE__ */ new Map();
|
|
372
|
-
constructor(opts) {
|
|
372
|
+
constructor(opts, id = CONSOLE_DEFAULT_ID) {
|
|
373
373
|
this.opts = opts;
|
|
374
|
+
this.id = id;
|
|
374
375
|
}
|
|
375
376
|
async start(ctx) {
|
|
376
377
|
if (this.client) {
|
|
@@ -502,7 +503,7 @@ var ConsoleAdapter = class {
|
|
|
502
503
|
if (!entry) return;
|
|
503
504
|
this.pendingPermissions.delete(channelRequestId);
|
|
504
505
|
entry.signal.removeEventListener("abort", entry.abortListener);
|
|
505
|
-
entry.resolve({ kind: "verdict", behavior: decision, channelId:
|
|
506
|
+
entry.resolve({ kind: "verdict", behavior: decision, channelId: this.id });
|
|
506
507
|
}
|
|
507
508
|
disposePermissions(reason = "auto_resolved") {
|
|
508
509
|
for (const [id, entry] of [...this.pendingPermissions.entries()]) {
|
|
@@ -571,7 +572,7 @@ var ConsoleAdapter = class {
|
|
|
571
572
|
entry.resolve({ kind: "cancelled", reason: "auto_resolved" });
|
|
572
573
|
return;
|
|
573
574
|
}
|
|
574
|
-
entry.resolve({ kind: "answer", answers: filtered, channelId:
|
|
575
|
+
entry.resolve({ kind: "answer", answers: filtered, channelId: this.id });
|
|
575
576
|
}
|
|
576
577
|
disposeQuestions(reason = "auto_resolved") {
|
|
577
578
|
for (const [id, entry] of [...this.pendingQuestions.entries()]) {
|
|
@@ -612,7 +613,7 @@ var ConsoleAdapter = class {
|
|
|
612
613
|
this.ctx?.log("warn", "console.message.in dropped: missing messageId");
|
|
613
614
|
return;
|
|
614
615
|
}
|
|
615
|
-
const inbound = normalizeInbound(frame, this.opts.runnerId);
|
|
616
|
+
const inbound = normalizeInbound(frame, this.opts.runnerId, this.id);
|
|
616
617
|
if (!inbound || !this.ctx) return;
|
|
617
618
|
try {
|
|
618
619
|
this.ctx.emitInbound(inbound);
|
|
@@ -723,13 +724,13 @@ function isValidConsoleAddress(value) {
|
|
|
723
724
|
}
|
|
724
725
|
return true;
|
|
725
726
|
}
|
|
726
|
-
function normalizeInbound(frame, runnerId) {
|
|
727
|
+
function normalizeInbound(frame, runnerId, channelId) {
|
|
727
728
|
if (typeof frame.text !== "string" || frame.text.length === 0) return null;
|
|
728
729
|
const userId = frame.address.userId ?? "console-user";
|
|
729
730
|
const idempotencyKey = typeof frame.idempotencyKey === "string" && frame.idempotencyKey.length > 0 ? frame.idempotencyKey : `console:${runnerId}:${frame.messageId}`;
|
|
730
731
|
return {
|
|
731
732
|
location: {
|
|
732
|
-
channelId
|
|
733
|
+
channelId,
|
|
733
734
|
accountId: frame.address.workspaceId ?? runnerId,
|
|
734
735
|
peer: { id: userId, kind: "user" },
|
|
735
736
|
...frame.address.threadId !== void 0 ? { thread: { id: frame.address.threadId } } : frame.address.conversationId !== void 0 ? { thread: { id: frame.address.conversationId } } : {}
|
|
@@ -810,8 +811,8 @@ var consoleModule = {
|
|
|
810
811
|
};
|
|
811
812
|
return { ok: true, config };
|
|
812
813
|
},
|
|
813
|
-
create(config) {
|
|
814
|
-
return new ConsoleAdapter(config);
|
|
814
|
+
create(config, instanceId) {
|
|
815
|
+
return new ConsoleAdapter(config, instanceId);
|
|
815
816
|
}
|
|
816
817
|
};
|
|
817
818
|
function isLoopbackUrl(url) {
|
|
@@ -1520,9 +1521,9 @@ function buildCancelText(reason) {
|
|
|
1520
1521
|
}
|
|
1521
1522
|
|
|
1522
1523
|
// src/gateway/adapters/telegram/adapter.ts
|
|
1523
|
-
var
|
|
1524
|
+
var TELEGRAM_DEFAULT_ID = "telegram";
|
|
1524
1525
|
var TelegramAdapter = class {
|
|
1525
|
-
id
|
|
1526
|
+
id;
|
|
1526
1527
|
capabilities = {
|
|
1527
1528
|
chat: true,
|
|
1528
1529
|
threads: true,
|
|
@@ -1538,8 +1539,9 @@ var TelegramAdapter = class {
|
|
|
1538
1539
|
lastInboundAt;
|
|
1539
1540
|
lastTransportOk = true;
|
|
1540
1541
|
ctx = null;
|
|
1541
|
-
constructor(opts) {
|
|
1542
|
+
constructor(opts, id = TELEGRAM_DEFAULT_ID) {
|
|
1542
1543
|
this.opts = opts;
|
|
1544
|
+
this.id = id;
|
|
1543
1545
|
this.relay = new TelegramRelay({
|
|
1544
1546
|
resolveTarget: () => {
|
|
1545
1547
|
if (this.opts.defaultChatId === void 0) return null;
|
|
@@ -1638,7 +1640,7 @@ var TelegramAdapter = class {
|
|
|
1638
1640
|
this.markHealth(true);
|
|
1639
1641
|
continue;
|
|
1640
1642
|
}
|
|
1641
|
-
const inbound = normalizeInbound2(update, allow);
|
|
1643
|
+
const inbound = normalizeInbound2(update, allow, this.id);
|
|
1642
1644
|
if (!inbound) continue;
|
|
1643
1645
|
this.lastInboundAt = inbound.receivedAt;
|
|
1644
1646
|
this.markHealth(true);
|
|
@@ -1676,7 +1678,7 @@ var TelegramAdapter = class {
|
|
|
1676
1678
|
}
|
|
1677
1679
|
}
|
|
1678
1680
|
};
|
|
1679
|
-
function normalizeInbound2(update, allow) {
|
|
1681
|
+
function normalizeInbound2(update, allow, channelId) {
|
|
1680
1682
|
const message = update.message ?? update.edited_message;
|
|
1681
1683
|
if (!message) return null;
|
|
1682
1684
|
const text = message.text;
|
|
@@ -1691,7 +1693,7 @@ function normalizeInbound2(update, allow) {
|
|
|
1691
1693
|
const threadId = typeof message.message_thread_id === "number" ? String(message.message_thread_id) : void 0;
|
|
1692
1694
|
return {
|
|
1693
1695
|
location: {
|
|
1694
|
-
channelId
|
|
1696
|
+
channelId,
|
|
1695
1697
|
accountId,
|
|
1696
1698
|
...isPrivate ? { peer: { id: chatId, kind: "user" } } : {
|
|
1697
1699
|
room: {
|
|
@@ -1746,8 +1748,8 @@ var telegramModule = {
|
|
|
1746
1748
|
};
|
|
1747
1749
|
return { ok: true, config };
|
|
1748
1750
|
},
|
|
1749
|
-
create(config) {
|
|
1750
|
-
return new TelegramAdapter(config);
|
|
1751
|
+
create(config, instanceId) {
|
|
1752
|
+
return new TelegramAdapter(config, instanceId);
|
|
1751
1753
|
}
|
|
1752
1754
|
};
|
|
1753
1755
|
|
|
@@ -1762,18 +1764,18 @@ function findAdapterModule(name) {
|
|
|
1762
1764
|
|
|
1763
1765
|
// src/gateway/adapters/factory.ts
|
|
1764
1766
|
function instantiateAdapter(sidecar) {
|
|
1765
|
-
const module = findAdapterModule(sidecar.
|
|
1767
|
+
const module = findAdapterModule(sidecar.kind);
|
|
1766
1768
|
if (!module) {
|
|
1767
|
-
return { ok: false, reason: `unknown channel: ${sidecar.
|
|
1769
|
+
return { ok: false, reason: `unknown channel kind: ${sidecar.kind}` };
|
|
1768
1770
|
}
|
|
1769
1771
|
const parsed = module.parseConfig({
|
|
1770
1772
|
options: sidecar.options,
|
|
1771
1773
|
allowedUserIds: sidecar.allowedUserIds
|
|
1772
1774
|
});
|
|
1773
1775
|
if (!parsed.ok) {
|
|
1774
|
-
return { ok: false, reason: `${sidecar.
|
|
1776
|
+
return { ok: false, reason: `${sidecar.instanceId}: ${parsed.reason}` };
|
|
1775
1777
|
}
|
|
1776
|
-
return { ok: true, adapter: module.create(parsed.config) };
|
|
1778
|
+
return { ok: true, adapter: module.create(parsed.config, sidecar.instanceId) };
|
|
1777
1779
|
}
|
|
1778
1780
|
|
|
1779
1781
|
// src/gateway/channelManager.ts
|
|
@@ -2088,7 +2090,7 @@ var cachedVersion = null;
|
|
|
2088
2090
|
function readVersion() {
|
|
2089
2091
|
if (cachedVersion !== null) return cachedVersion;
|
|
2090
2092
|
try {
|
|
2091
|
-
const injected = "0.4.
|
|
2093
|
+
const injected = "0.4.5";
|
|
2092
2094
|
if (typeof injected === "string" && injected.length > 0) {
|
|
2093
2095
|
cachedVersion = injected;
|
|
2094
2096
|
return cachedVersion;
|
|
@@ -3094,6 +3096,64 @@ function acquireLock(lockPath) {
|
|
|
3094
3096
|
throw new Error(`failed to acquire gateway lock at ${lockPath}`);
|
|
3095
3097
|
}
|
|
3096
3098
|
|
|
3099
|
+
// src/gateway/relay/pendingRegistry.ts
|
|
3100
|
+
var PendingRegistry = class {
|
|
3101
|
+
entries = /* @__PURE__ */ new Map();
|
|
3102
|
+
inspect(channelRequestId, kind, fingerprint, runtimeId) {
|
|
3103
|
+
const existing = this.entries.get(channelRequestId);
|
|
3104
|
+
if (!existing) return { kind: "absent" };
|
|
3105
|
+
if (existing.kind !== kind) return { kind: "collision", reason: "kind" };
|
|
3106
|
+
if (existing.fingerprint !== fingerprint) {
|
|
3107
|
+
return { kind: "collision", reason: "payload" };
|
|
3108
|
+
}
|
|
3109
|
+
if (existing.runtimeId !== runtimeId) {
|
|
3110
|
+
return { kind: "collision", reason: "owner" };
|
|
3111
|
+
}
|
|
3112
|
+
return { kind: "attach", entry: existing };
|
|
3113
|
+
}
|
|
3114
|
+
register(entry) {
|
|
3115
|
+
this.entries.set(entry.channelRequestId, entry);
|
|
3116
|
+
}
|
|
3117
|
+
settle(channelRequestId, result) {
|
|
3118
|
+
const entry = this.entries.get(channelRequestId);
|
|
3119
|
+
if (!entry || entry.settled) return false;
|
|
3120
|
+
entry.settled = true;
|
|
3121
|
+
this.entries.delete(channelRequestId);
|
|
3122
|
+
clearTimeout(entry.timer);
|
|
3123
|
+
for (const ctrl of entry.controllers) {
|
|
3124
|
+
if (!ctrl.signal.aborted) ctrl.abort();
|
|
3125
|
+
}
|
|
3126
|
+
entry.resolve(result);
|
|
3127
|
+
return true;
|
|
3128
|
+
}
|
|
3129
|
+
cancel(channelRequestId, reason, expectedRuntimeId) {
|
|
3130
|
+
const entry = this.entries.get(channelRequestId);
|
|
3131
|
+
if (!entry) return false;
|
|
3132
|
+
if (expectedRuntimeId !== void 0 && entry.runtimeId !== void 0 && entry.runtimeId !== expectedRuntimeId) {
|
|
3133
|
+
return false;
|
|
3134
|
+
}
|
|
3135
|
+
return this.settle(channelRequestId, { kind: "cancelled", reason });
|
|
3136
|
+
}
|
|
3137
|
+
disposeAll(reason) {
|
|
3138
|
+
for (const id of [...this.entries.keys()]) {
|
|
3139
|
+
this.cancel(id, reason, void 0);
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
count() {
|
|
3143
|
+
return this.entries.size;
|
|
3144
|
+
}
|
|
3145
|
+
};
|
|
3146
|
+
function collisionMessage(channelRequestId, reason, newKind) {
|
|
3147
|
+
if (reason === "owner") {
|
|
3148
|
+
return `channel_request_owner_mismatch: ${channelRequestId} owned by a different runtime`;
|
|
3149
|
+
}
|
|
3150
|
+
if (reason === "kind") {
|
|
3151
|
+
const otherKind = newKind === "permission" ? "question" : "permission";
|
|
3152
|
+
return `channel_request_id_collision: ${channelRequestId} is bound to a ${otherKind} relay`;
|
|
3153
|
+
}
|
|
3154
|
+
return `channel_request_id_collision: ${channelRequestId} payload mismatch`;
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3097
3157
|
// src/gateway/relay/coordinator.ts
|
|
3098
3158
|
var DEFAULT_RELAY_TTL_MS = 5 * 6e4;
|
|
3099
3159
|
var RelayCoordinator = class {
|
|
@@ -3101,7 +3161,7 @@ var RelayCoordinator = class {
|
|
|
3101
3161
|
defaultTtlMs;
|
|
3102
3162
|
idFactory;
|
|
3103
3163
|
log;
|
|
3104
|
-
|
|
3164
|
+
registry = new PendingRegistry();
|
|
3105
3165
|
constructor(opts) {
|
|
3106
3166
|
this.adapters = opts.adapters;
|
|
3107
3167
|
this.defaultTtlMs = opts.defaultTtlMs ?? DEFAULT_RELAY_TTL_MS;
|
|
@@ -3110,180 +3170,151 @@ var RelayCoordinator = class {
|
|
|
3110
3170
|
}
|
|
3111
3171
|
requestPermission(req) {
|
|
3112
3172
|
const channelRequestId = req.channelRequestId ?? this.idFactory();
|
|
3113
|
-
const ttlMs = req.ttlMs ?? this.defaultTtlMs;
|
|
3114
3173
|
const targets = this.adapters().filter(
|
|
3115
3174
|
(a) => a.capabilities.relayPermission && typeof a.requestPermissionVerdict === "function"
|
|
3116
3175
|
);
|
|
3117
3176
|
if (targets.length === 0) {
|
|
3118
|
-
return {
|
|
3119
|
-
channelRequestId,
|
|
3120
|
-
result: Promise.resolve({ kind: "no_relay" })
|
|
3121
|
-
};
|
|
3177
|
+
return { channelRequestId, result: Promise.resolve({ kind: "no_relay" }) };
|
|
3122
3178
|
}
|
|
3123
3179
|
const fingerprint = permissionFingerprint(req);
|
|
3124
|
-
const
|
|
3125
|
-
if (existing) {
|
|
3126
|
-
if (existing.kind !== "permission") {
|
|
3127
|
-
throw new Error(
|
|
3128
|
-
`channel_request_id_collision: ${channelRequestId} is bound to a question relay`
|
|
3129
|
-
);
|
|
3130
|
-
}
|
|
3131
|
-
if (existing.fingerprint !== fingerprint) {
|
|
3132
|
-
throw new Error(
|
|
3133
|
-
`channel_request_id_collision: ${channelRequestId} payload mismatch`
|
|
3134
|
-
);
|
|
3135
|
-
}
|
|
3136
|
-
if (existing.runtimeId !== req.runtimeId) {
|
|
3137
|
-
throw new Error(
|
|
3138
|
-
`channel_request_owner_mismatch: ${channelRequestId} owned by a different runtime`
|
|
3139
|
-
);
|
|
3140
|
-
}
|
|
3141
|
-
return { channelRequestId, result: existing.result };
|
|
3142
|
-
}
|
|
3143
|
-
const controllers = targets.map(() => new AbortController());
|
|
3144
|
-
let resolveFn;
|
|
3145
|
-
const result = new Promise((resolve) => {
|
|
3146
|
-
resolveFn = resolve;
|
|
3147
|
-
});
|
|
3148
|
-
const timer = setTimeout(() => {
|
|
3149
|
-
this.settle(channelRequestId, { kind: "cancelled", reason: "timeout" });
|
|
3150
|
-
}, ttlMs);
|
|
3151
|
-
if (typeof timer.unref === "function") timer.unref();
|
|
3152
|
-
const entry = {
|
|
3153
|
-
kind: "permission",
|
|
3180
|
+
const inspect = this.registry.inspect(
|
|
3154
3181
|
channelRequestId,
|
|
3182
|
+
"permission",
|
|
3155
3183
|
fingerprint,
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
}
|
|
3163
|
-
|
|
3184
|
+
req.runtimeId
|
|
3185
|
+
);
|
|
3186
|
+
if (inspect.kind === "collision") {
|
|
3187
|
+
throw new Error(
|
|
3188
|
+
collisionMessage(channelRequestId, inspect.reason, "permission")
|
|
3189
|
+
);
|
|
3190
|
+
}
|
|
3191
|
+
if (inspect.kind === "attach") {
|
|
3192
|
+
return {
|
|
3193
|
+
channelRequestId,
|
|
3194
|
+
result: inspect.entry.result
|
|
3195
|
+
};
|
|
3196
|
+
}
|
|
3164
3197
|
const fullReq = {
|
|
3165
3198
|
channelRequestId,
|
|
3166
3199
|
toolName: req.toolName,
|
|
3167
3200
|
description: req.description,
|
|
3168
3201
|
inputPreview: req.inputPreview
|
|
3169
3202
|
};
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
});
|
|
3203
|
+
const result = this.broadcast({
|
|
3204
|
+
kind: "permission",
|
|
3205
|
+
channelRequestId,
|
|
3206
|
+
ttlMs: req.ttlMs ?? this.defaultTtlMs,
|
|
3207
|
+
runtimeId: req.runtimeId,
|
|
3208
|
+
fingerprint,
|
|
3209
|
+
targets,
|
|
3210
|
+
perAdapter: async (adapter, signal) => {
|
|
3211
|
+
const res = await adapter.requestPermissionVerdict(fullReq, signal);
|
|
3212
|
+
return res.kind === "verdict" ? { ...res, channelId: adapter.id } : null;
|
|
3213
|
+
}
|
|
3182
3214
|
});
|
|
3183
3215
|
return { channelRequestId, result };
|
|
3184
3216
|
}
|
|
3185
3217
|
requestQuestion(req) {
|
|
3186
3218
|
const channelRequestId = req.channelRequestId ?? this.idFactory();
|
|
3187
|
-
const ttlMs = req.ttlMs ?? this.defaultTtlMs;
|
|
3188
3219
|
const targets = this.adapters().filter(
|
|
3189
3220
|
(a) => a.capabilities.relayQuestion && typeof a.requestQuestionAnswer === "function"
|
|
3190
3221
|
);
|
|
3191
3222
|
if (targets.length === 0) {
|
|
3223
|
+
return { channelRequestId, result: Promise.resolve({ kind: "no_relay" }) };
|
|
3224
|
+
}
|
|
3225
|
+
const fingerprint = questionFingerprint(req);
|
|
3226
|
+
const inspect = this.registry.inspect(
|
|
3227
|
+
channelRequestId,
|
|
3228
|
+
"question",
|
|
3229
|
+
fingerprint,
|
|
3230
|
+
req.runtimeId
|
|
3231
|
+
);
|
|
3232
|
+
if (inspect.kind === "collision") {
|
|
3233
|
+
throw new Error(
|
|
3234
|
+
collisionMessage(channelRequestId, inspect.reason, "question")
|
|
3235
|
+
);
|
|
3236
|
+
}
|
|
3237
|
+
if (inspect.kind === "attach") {
|
|
3192
3238
|
return {
|
|
3193
3239
|
channelRequestId,
|
|
3194
|
-
result:
|
|
3240
|
+
result: inspect.entry.result
|
|
3195
3241
|
};
|
|
3196
3242
|
}
|
|
3197
|
-
const
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
`channel_request_owner_mismatch: ${channelRequestId} owned by a different runtime`
|
|
3213
|
-
);
|
|
3243
|
+
const fullReq = {
|
|
3244
|
+
channelRequestId,
|
|
3245
|
+
title: req.title,
|
|
3246
|
+
questions: req.questions
|
|
3247
|
+
};
|
|
3248
|
+
const result = this.broadcast({
|
|
3249
|
+
kind: "question",
|
|
3250
|
+
channelRequestId,
|
|
3251
|
+
ttlMs: req.ttlMs ?? this.defaultTtlMs,
|
|
3252
|
+
runtimeId: req.runtimeId,
|
|
3253
|
+
fingerprint,
|
|
3254
|
+
targets,
|
|
3255
|
+
perAdapter: async (adapter, signal) => {
|
|
3256
|
+
const res = await adapter.requestQuestionAnswer(fullReq, signal);
|
|
3257
|
+
return res.kind === "answer" ? { ...res, channelId: adapter.id } : null;
|
|
3214
3258
|
}
|
|
3215
|
-
|
|
3216
|
-
}
|
|
3259
|
+
});
|
|
3260
|
+
return { channelRequestId, result };
|
|
3261
|
+
}
|
|
3262
|
+
cancel(channelRequestId, reason, expectedRuntimeId) {
|
|
3263
|
+
return this.registry.cancel(channelRequestId, reason, expectedRuntimeId);
|
|
3264
|
+
}
|
|
3265
|
+
pendingCount() {
|
|
3266
|
+
return this.registry.count();
|
|
3267
|
+
}
|
|
3268
|
+
disposeAll(reason = "auto_resolved") {
|
|
3269
|
+
this.registry.disposeAll(reason);
|
|
3270
|
+
}
|
|
3271
|
+
broadcast(args) {
|
|
3272
|
+
const {
|
|
3273
|
+
kind,
|
|
3274
|
+
channelRequestId,
|
|
3275
|
+
ttlMs,
|
|
3276
|
+
runtimeId,
|
|
3277
|
+
fingerprint,
|
|
3278
|
+
targets,
|
|
3279
|
+
perAdapter
|
|
3280
|
+
} = args;
|
|
3217
3281
|
const controllers = targets.map(() => new AbortController());
|
|
3218
3282
|
let resolveFn;
|
|
3219
3283
|
const result = new Promise((resolve) => {
|
|
3220
3284
|
resolveFn = resolve;
|
|
3221
3285
|
});
|
|
3222
3286
|
const timer = setTimeout(() => {
|
|
3223
|
-
this.settle(channelRequestId, {
|
|
3287
|
+
this.registry.settle(channelRequestId, {
|
|
3288
|
+
kind: "cancelled",
|
|
3289
|
+
reason: "timeout"
|
|
3290
|
+
});
|
|
3224
3291
|
}, ttlMs);
|
|
3225
3292
|
if (typeof timer.unref === "function") timer.unref();
|
|
3226
|
-
|
|
3227
|
-
kind
|
|
3293
|
+
this.registry.register({
|
|
3294
|
+
kind,
|
|
3228
3295
|
channelRequestId,
|
|
3229
3296
|
fingerprint,
|
|
3230
|
-
|
|
3297
|
+
runtimeId,
|
|
3231
3298
|
controllers,
|
|
3232
3299
|
timer,
|
|
3233
3300
|
resolve: resolveFn,
|
|
3234
3301
|
result,
|
|
3235
3302
|
settled: false
|
|
3236
|
-
};
|
|
3237
|
-
this.pending.set(channelRequestId, entry);
|
|
3238
|
-
const fullReq = {
|
|
3239
|
-
channelRequestId,
|
|
3240
|
-
title: req.title,
|
|
3241
|
-
questions: req.questions
|
|
3242
|
-
};
|
|
3303
|
+
});
|
|
3243
3304
|
targets.forEach((adapter, idx) => {
|
|
3244
3305
|
const ctrl = controllers[idx];
|
|
3245
|
-
Promise.resolve().then(() => adapter
|
|
3246
|
-
if (res
|
|
3247
|
-
this.settle(channelRequestId,
|
|
3306
|
+
Promise.resolve().then(() => perAdapter(adapter, ctrl.signal)).then((res) => {
|
|
3307
|
+
if (res !== null) {
|
|
3308
|
+
this.registry.settle(channelRequestId, res);
|
|
3248
3309
|
}
|
|
3249
3310
|
}).catch((err) => {
|
|
3250
3311
|
this.log?.(
|
|
3251
3312
|
"warn",
|
|
3252
|
-
`adapter ${adapter.id}
|
|
3313
|
+
`adapter ${adapter.id} ${kind} relay failed: ${err instanceof Error ? err.message : String(err)}`
|
|
3253
3314
|
);
|
|
3254
3315
|
});
|
|
3255
3316
|
});
|
|
3256
|
-
return
|
|
3257
|
-
}
|
|
3258
|
-
cancel(channelRequestId, reason, expectedRuntimeId) {
|
|
3259
|
-
const entry = this.pending.get(channelRequestId);
|
|
3260
|
-
if (!entry) return false;
|
|
3261
|
-
if (expectedRuntimeId !== void 0 && entry.runtimeId !== void 0 && entry.runtimeId !== expectedRuntimeId) {
|
|
3262
|
-
return false;
|
|
3263
|
-
}
|
|
3264
|
-
this.settle(channelRequestId, { kind: "cancelled", reason });
|
|
3265
|
-
return true;
|
|
3266
|
-
}
|
|
3267
|
-
pendingCount() {
|
|
3268
|
-
return this.pending.size;
|
|
3269
|
-
}
|
|
3270
|
-
disposeAll(reason = "auto_resolved") {
|
|
3271
|
-
for (const id of [...this.pending.keys()]) {
|
|
3272
|
-
this.cancel(id, reason);
|
|
3273
|
-
}
|
|
3274
|
-
}
|
|
3275
|
-
settle(channelRequestId, result) {
|
|
3276
|
-
const entry = this.pending.get(channelRequestId);
|
|
3277
|
-
if (!entry || entry.settled) return;
|
|
3278
|
-
entry.settled = true;
|
|
3279
|
-
this.pending.delete(channelRequestId);
|
|
3280
|
-
clearTimeout(entry.timer);
|
|
3281
|
-
for (const ctrl of entry.controllers) {
|
|
3282
|
-
if (!ctrl.signal.aborted) ctrl.abort();
|
|
3283
|
-
}
|
|
3284
|
-
entry.resolve(
|
|
3285
|
-
result
|
|
3286
|
-
);
|
|
3317
|
+
return result;
|
|
3287
3318
|
}
|
|
3288
3319
|
};
|
|
3289
3320
|
function permissionFingerprint(req) {
|
|
@@ -3650,7 +3681,7 @@ async function startDaemon(opts) {
|
|
|
3650
3681
|
reason: err.reason
|
|
3651
3682
|
});
|
|
3652
3683
|
}
|
|
3653
|
-
const sidecarIds = new Set(sidecars.map((s) => s.
|
|
3684
|
+
const sidecarIds = new Set(sidecars.map((s) => s.instanceId));
|
|
3654
3685
|
for (const channel of channelManager.listChannels()) {
|
|
3655
3686
|
if (sidecarIds.has(channel.id)) continue;
|
|
3656
3687
|
try {
|
|
@@ -3670,13 +3701,13 @@ async function startDaemon(opts) {
|
|
|
3670
3701
|
}
|
|
3671
3702
|
}
|
|
3672
3703
|
for (const sidecar of sidecars) {
|
|
3673
|
-
const existed = channelManager.listChannels().some((channel) => channel.id === sidecar.
|
|
3704
|
+
const existed = channelManager.listChannels().some((channel) => channel.id === sidecar.instanceId);
|
|
3674
3705
|
if (existed) {
|
|
3675
3706
|
try {
|
|
3676
|
-
await channelManager.unregister(sidecar.
|
|
3707
|
+
await channelManager.unregister(sidecar.instanceId, "shutdown");
|
|
3677
3708
|
} catch (err) {
|
|
3678
3709
|
results.push({
|
|
3679
|
-
id: sidecar.
|
|
3710
|
+
id: sidecar.instanceId,
|
|
3680
3711
|
ok: false,
|
|
3681
3712
|
action: "failed",
|
|
3682
3713
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -3687,7 +3718,7 @@ async function startDaemon(opts) {
|
|
|
3687
3718
|
const built = instantiateAdapter(sidecar);
|
|
3688
3719
|
if (!built.ok) {
|
|
3689
3720
|
results.push({
|
|
3690
|
-
id: sidecar.
|
|
3721
|
+
id: sidecar.instanceId,
|
|
3691
3722
|
ok: false,
|
|
3692
3723
|
action: "failed",
|
|
3693
3724
|
reason: built.reason
|
|
@@ -3697,17 +3728,19 @@ async function startDaemon(opts) {
|
|
|
3697
3728
|
try {
|
|
3698
3729
|
await channelManager.register(built.adapter);
|
|
3699
3730
|
results.push({
|
|
3700
|
-
id: sidecar.
|
|
3731
|
+
id: sidecar.instanceId,
|
|
3701
3732
|
ok: true,
|
|
3702
3733
|
action: existed ? "replaced" : "registered"
|
|
3703
3734
|
});
|
|
3704
3735
|
if (!opts.silent) {
|
|
3705
|
-
process.stdout.write(
|
|
3706
|
-
`
|
|
3736
|
+
process.stdout.write(
|
|
3737
|
+
`athena-gateway: registered ${sidecar.instanceId}
|
|
3738
|
+
`
|
|
3739
|
+
);
|
|
3707
3740
|
}
|
|
3708
3741
|
} catch (err) {
|
|
3709
3742
|
results.push({
|
|
3710
|
-
id: sidecar.
|
|
3743
|
+
id: sidecar.instanceId,
|
|
3711
3744
|
ok: false,
|
|
3712
3745
|
action: "failed",
|
|
3713
3746
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -3728,7 +3761,7 @@ async function startDaemon(opts) {
|
|
|
3728
3761
|
const built = instantiateAdapter(sidecar);
|
|
3729
3762
|
if (!built.ok) {
|
|
3730
3763
|
process.stderr.write(
|
|
3731
|
-
`athena-gateway: ${sidecar.
|
|
3764
|
+
`athena-gateway: ${sidecar.instanceId}: ${built.reason}
|
|
3732
3765
|
`
|
|
3733
3766
|
);
|
|
3734
3767
|
continue;
|
|
@@ -3736,12 +3769,14 @@ async function startDaemon(opts) {
|
|
|
3736
3769
|
try {
|
|
3737
3770
|
await channelManager.register(built.adapter);
|
|
3738
3771
|
if (!opts.silent) {
|
|
3739
|
-
process.stdout.write(
|
|
3740
|
-
`
|
|
3772
|
+
process.stdout.write(
|
|
3773
|
+
`athena-gateway: registered ${sidecar.instanceId}
|
|
3774
|
+
`
|
|
3775
|
+
);
|
|
3741
3776
|
}
|
|
3742
3777
|
} catch (err) {
|
|
3743
3778
|
process.stderr.write(
|
|
3744
|
-
`athena-gateway: register ${sidecar.
|
|
3779
|
+
`athena-gateway: register ${sidecar.instanceId} failed: ${err instanceof Error ? err.message : String(err)}
|
|
3745
3780
|
`
|
|
3746
3781
|
);
|
|
3747
3782
|
}
|
|
@@ -139,14 +139,26 @@ function loadOne(name, filePath) {
|
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
+
const kindRaw = obj["kind"];
|
|
143
|
+
if (kindRaw !== void 0 && (typeof kindRaw !== "string" || kindRaw.length === 0)) {
|
|
144
|
+
return { ok: false, reason: "kind must be a non-empty string" };
|
|
145
|
+
}
|
|
146
|
+
const kind = kindRaw ?? name;
|
|
147
|
+
const instanceIdRaw = obj["instance_id"];
|
|
148
|
+
if (instanceIdRaw !== void 0 && (typeof instanceIdRaw !== "string" || instanceIdRaw.length === 0)) {
|
|
149
|
+
return { ok: false, reason: "instance_id must be a non-empty string" };
|
|
150
|
+
}
|
|
151
|
+
const instanceId = instanceIdRaw ?? kind;
|
|
142
152
|
const options = {};
|
|
143
153
|
for (const [key, value] of Object.entries(obj)) {
|
|
144
|
-
if (key === "allowed_user_ids")
|
|
154
|
+
if (key === "allowed_user_ids" || key === "kind" || key === "instance_id") {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
145
157
|
options[key] = value;
|
|
146
158
|
}
|
|
147
159
|
return {
|
|
148
160
|
ok: true,
|
|
149
|
-
sidecar: { name, path: filePath, allowedUserIds, options }
|
|
161
|
+
sidecar: { name, path: filePath, kind, instanceId, allowedUserIds, options }
|
|
150
162
|
};
|
|
151
163
|
}
|
|
152
164
|
|
|
@@ -158,4 +170,4 @@ export {
|
|
|
158
170
|
channelSidecarDir,
|
|
159
171
|
loadChannelSidecars
|
|
160
172
|
};
|
|
161
|
-
//# sourceMappingURL=chunk-
|
|
173
|
+
//# sourceMappingURL=chunk-M44KEGM7.js.map
|