mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-08 22:00:50 +08:00
Expose resolveSessionPeer on ctx.dshIm for ops schedulers (ops.23).
WhatsApp registers a peer resolver so cron_create can default IM delivery to the calling session's bot/target. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6d2229acd2
commit
41f13bb90c
3 changed files with 42 additions and 2 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "dsh-im-ops",
|
||||
"version": "4.9.1-ops.22",
|
||||
"description": "Ops fork of dsh-im (all channels kept). Based on @xmanrui/dsh-im@4.9.1 — access/session policies owned here.",
|
||||
"version": "4.9.1-ops.23",
|
||||
"description": "Ops fork of dsh-im (all channels kept). Based on @xmanrui/dsh-im@4.9.1 �access/session policies owned here.",
|
||||
"keywords": [
|
||||
"deepseek-harness",
|
||||
"dsh",
|
||||
|
|
|
|||
|
|
@ -17,7 +17,20 @@ export async function apply(ctx, config = {}) {
|
|||
config.rpcOptions,
|
||||
config.rpcAuthority,
|
||||
);
|
||||
let unregisterPeer = () => {};
|
||||
try {
|
||||
const dshIm = typeof ctx.get === 'function' ? ctx.get('dshIm') : undefined;
|
||||
if (dshIm && typeof dshIm.registerPeerResolver === 'function'
|
||||
&& typeof production.controller?.resolveChannelPeer === 'function') {
|
||||
unregisterPeer = dshIm.registerPeerResolver((sessionId) => (
|
||||
production.controller.resolveChannelPeer(sessionId)
|
||||
));
|
||||
}
|
||||
} catch {
|
||||
// dshIm optional during partial boots
|
||||
}
|
||||
ctx.effect(() => async () => {
|
||||
unregisterPeer?.();
|
||||
await unregisterDelivery?.();
|
||||
await production.close();
|
||||
}, 'dsh-im: close WhatsApp Web connections');
|
||||
|
|
|
|||
|
|
@ -62,12 +62,39 @@ export function createImHostPlugin(internals = {}) {
|
|||
inject,
|
||||
async apply(ctx, config = {}) {
|
||||
const deliveryService = makeDeliveryService();
|
||||
const peerResolvers = [];
|
||||
if (typeof ctx?.provide === 'function') {
|
||||
ctx.provide('dshIm', Object.freeze({
|
||||
send: (botId, targetId, text, options) => (
|
||||
deliveryService.send(botId, targetId, text, options)
|
||||
),
|
||||
listTargets: async (botId) => (await deliveryService.listTargets(botId)).targets,
|
||||
/**
|
||||
* Resolve the IM channel peer for a Harness session (botId + conversationKey).
|
||||
* Used by ops schedulers to default proactive delivery back to the caller.
|
||||
*/
|
||||
resolveSessionPeer: async (sessionId) => {
|
||||
const id = typeof sessionId === 'string' ? sessionId.trim() : '';
|
||||
if (!id) return null;
|
||||
for (const resolve of peerResolvers) {
|
||||
try {
|
||||
const peer = await resolve(id);
|
||||
if (peer && typeof peer.botId === 'string' && peer.botId.trim()) return peer;
|
||||
} catch {
|
||||
// try next channel
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
/** @param {(sessionId: string) => Promise<object|null>} resolve */
|
||||
registerPeerResolver: (resolve) => {
|
||||
if (typeof resolve !== 'function') return () => {};
|
||||
peerResolvers.push(resolve);
|
||||
return () => {
|
||||
const index = peerResolvers.indexOf(resolve);
|
||||
if (index >= 0) peerResolvers.splice(index, 1);
|
||||
};
|
||||
},
|
||||
}));
|
||||
}
|
||||
const activate = async (readyCtx) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue