@senpi/runtime 3.0.22 → 3.0.23
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 +7 -4
- package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
- package/dist/actions/close-position/close-position.action.js +8 -6
- package/dist/actions/close-position/close-position.action.js.map +1 -1
- package/dist/actions/decision-error-notification.d.ts +14 -0
- package/dist/actions/decision-error-notification.d.ts.map +1 -0
- package/dist/actions/decision-error-notification.js +36 -0
- package/dist/actions/decision-error-notification.js.map +1 -0
- package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
- package/dist/actions/open-position/open-position.action.js +8 -6
- package/dist/actions/open-position/open-position.action.js.map +1 -1
- package/dist/actions/types.d.ts +2 -0
- package/dist/actions/types.d.ts.map +1 -1
- package/dist/cli/guide-commands.d.ts.map +1 -1
- package/dist/cli/guide-commands.js +5 -7
- package/dist/cli/guide-commands.js.map +1 -1
- package/dist/cli/senpi-cli-config.d.ts +0 -17
- package/dist/cli/senpi-cli-config.d.ts.map +1 -1
- package/dist/cli/senpi-cli-config.js +0 -30
- package/dist/cli/senpi-cli-config.js.map +1 -1
- package/dist/cli/senpi-config-commands.d.ts +1 -1
- package/dist/cli/senpi-config-commands.d.ts.map +1 -1
- package/dist/cli/senpi-config-commands.js +1 -16
- package/dist/cli/senpi-config-commands.js.map +1 -1
- package/dist/constants/dsl/index.d.ts +1 -5
- package/dist/constants/dsl/index.d.ts.map +1 -1
- package/dist/constants/dsl/index.js +1 -5
- package/dist/constants/dsl/index.js.map +1 -1
- package/dist/dsl/engine-client/event-mapping.d.ts +1 -1
- package/dist/dsl/engine-client/event-mapping.d.ts.map +1 -1
- package/dist/dsl/events/build-closed-event.d.ts +1 -1
- package/dist/dsl/events/build-closed-event.js +1 -1
- package/dist/dsl/events/handlers.js +1 -1
- package/dist/dsl/monitor/process-one-position.js +3 -3
- package/dist/dsl/monitor/process-one-position.js.map +1 -1
- package/dist/dsl/notifications/format-utils.d.ts +1 -11
- package/dist/dsl/notifications/format-utils.d.ts.map +1 -1
- package/dist/dsl/notifications/format-utils.js +1 -48
- package/dist/dsl/notifications/format-utils.js.map +1 -1
- package/dist/dsl/notifications/formatter.d.ts +9 -25
- package/dist/dsl/notifications/formatter.d.ts.map +1 -1
- package/dist/dsl/notifications/formatter.js +20 -105
- package/dist/dsl/notifications/formatter.js.map +1 -1
- package/dist/dsl/notifications/index.d.ts +2 -8
- package/dist/dsl/notifications/index.d.ts.map +1 -1
- package/dist/dsl/notifications/index.js +60 -57
- package/dist/dsl/notifications/index.js.map +1 -1
- package/dist/dsl/plugin/index.d.ts.map +1 -1
- package/dist/dsl/plugin/index.js +1 -27
- package/dist/dsl/plugin/index.js.map +1 -1
- package/dist/dsl/plugin/options.d.ts +3 -2
- package/dist/dsl/plugin/options.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -122
- package/dist/index.js.map +1 -1
- package/dist/prompt/session-context-seed-hook.d.ts +11 -0
- package/dist/prompt/session-context-seed-hook.d.ts.map +1 -0
- package/dist/prompt/session-context-seed-hook.js +99 -0
- package/dist/prompt/session-context-seed-hook.js.map +1 -0
- package/dist/runtime/auto-update/coordinator.d.ts +5 -6
- package/dist/runtime/auto-update/coordinator.d.ts.map +1 -1
- package/dist/runtime/auto-update/coordinator.js +19 -20
- package/dist/runtime/auto-update/coordinator.js.map +1 -1
- package/dist/runtime/create-action-context.d.ts.map +1 -1
- package/dist/runtime/create-action-context.js +1 -0
- package/dist/runtime/create-action-context.js.map +1 -1
- package/dist/runtime/create-runtime-context.d.ts +1 -0
- package/dist/runtime/create-runtime-context.d.ts.map +1 -1
- package/dist/runtime/create-runtime-context.js +1 -0
- package/dist/runtime/create-runtime-context.js.map +1 -1
- package/dist/runtime/decision-errors.d.ts +41 -53
- package/dist/runtime/decision-errors.d.ts.map +1 -1
- package/dist/runtime/decision-errors.js +48 -111
- package/dist/runtime/decision-errors.js.map +1 -1
- package/dist/runtime/notifications.d.ts +21 -14
- package/dist/runtime/notifications.d.ts.map +1 -1
- package/dist/runtime/notifications.js +192 -59
- package/dist/runtime/notifications.js.map +1 -1
- package/dist/runtime/runtime.d.ts +16 -2
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +106 -26
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/strategy-lifecycle.d.ts +5 -5
- package/dist/runtime/strategy-lifecycle.d.ts.map +1 -1
- package/dist/runtime/strategy-lifecycle.js +96 -28
- package/dist/runtime/strategy-lifecycle.js.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js +3 -3
- package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
- package/dist/runtime-api/lifecycle.d.ts +1 -1
- package/dist/runtime-api/lifecycle.js +1 -1
- package/dist/scripts/run-dsl-standalone-live.d.ts +7 -6
- package/dist/scripts/run-dsl-standalone-live.d.ts.map +1 -1
- package/dist/scripts/run-dsl-standalone-live.js +25 -21
- package/dist/scripts/run-dsl-standalone-live.js.map +1 -1
- package/dist/skills-manager/coordinator.d.ts +2 -2
- package/dist/skills-manager/coordinator.js +2 -2
- package/dist/test-setup.d.ts +2 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +23 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/types/dsl/index.d.ts +1 -1
- package/dist/types/notification.d.ts +95 -1
- package/dist/types/notification.d.ts.map +1 -1
- package/dist/types/notification.js +76 -1
- package/dist/types/notification.js.map +1 -1
- package/dist/types/runtime.d.ts +6 -0
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/session-context.d.ts +19 -0
- package/dist/types/session-context.d.ts.map +1 -0
- package/dist/types/session-context.js +20 -0
- package/dist/types/session-context.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -18
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +2 -40
- package/dist/utils/logger.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/actions/notifications/formatter.d.ts +0 -39
- package/dist/actions/notifications/formatter.d.ts.map +0 -1
- package/dist/actions/notifications/formatter.js +0 -68
- package/dist/actions/notifications/formatter.js.map +0 -1
- package/dist/actions/notifications/index.d.ts +0 -37
- package/dist/actions/notifications/index.d.ts.map +0 -1
- package/dist/actions/notifications/index.js +0 -89
- package/dist/actions/notifications/index.js.map +0 -1
- package/dist/dsl/notifications/close-resolver.d.ts +0 -92
- package/dist/dsl/notifications/close-resolver.d.ts.map +0 -1
- package/dist/dsl/notifications/close-resolver.js +0 -309
- package/dist/dsl/notifications/close-resolver.js.map +0 -1
- package/dist/dsl/notifications/types.d.ts +0 -27
- package/dist/dsl/notifications/types.d.ts.map +0 -1
- package/dist/dsl/notifications/types.js +0 -5
- package/dist/dsl/notifications/types.js.map +0 -1
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subscribes to action hook events on the bus and forwards formatted strings to NotificationService.
|
|
3
|
-
*/
|
|
4
|
-
import { HOOK_EVENT } from "../../types/hooks.js";
|
|
5
|
-
import { isHookEvent } from "../../dsl/events/guards.js";
|
|
6
|
-
import { createLogger } from "../../utils/logger.js";
|
|
7
|
-
import { formatOrderSubmitted, formatPositionClosed, } from "./formatter.js";
|
|
8
|
-
const logger = createLogger("[senpi-core][action-notifications]");
|
|
9
|
-
function safeNotify(notifier, message) {
|
|
10
|
-
try {
|
|
11
|
-
const result = notifier.notify(message);
|
|
12
|
-
if (result != null && typeof result.then === "function") {
|
|
13
|
-
void result.catch((err) => logger.warn("[action-notifications] notify rejected", { err, message }));
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
catch (err) {
|
|
17
|
-
logger.warn("[action-notifications] notify threw synchronously", { err, message });
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
/** Ensures formatter + notify never throw back into `bus.emit` (would break hook emitters). */
|
|
21
|
-
function runNotificationHandler(fn) {
|
|
22
|
-
try {
|
|
23
|
-
fn();
|
|
24
|
-
}
|
|
25
|
-
catch (err) {
|
|
26
|
-
logger.warn("[action-notifications] handler error (isolated from hooks)", { err });
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* When `notifications.action_lifecycle` is `false`, do not register the subscriber; callers should
|
|
31
|
-
* skip {@link createActionNotificationSubscriber} entirely. This helper documents the default
|
|
32
|
-
* (`true` when the key is omitted).
|
|
33
|
-
*
|
|
34
|
-
* @param notifications - Top-level YAML `notifications` object, if any
|
|
35
|
-
* @returns `false` only when `action_lifecycle` is explicitly `false`
|
|
36
|
-
*/
|
|
37
|
-
export function isActionLifecycleNotificationsEnabled(notifications) {
|
|
38
|
-
return notifications?.action_lifecycle !== false;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Listens for `on_open_order_submitted` and `on_position_closed` on the runtime bus and sends
|
|
42
|
-
* Telegram notifications. Position-tracker closes (`data.reason === 'position_tracker'`) are
|
|
43
|
-
* suppressed so DSL / tracker copy stays authoritative for those paths.
|
|
44
|
-
*
|
|
45
|
-
* @param bus - Runtime event bus
|
|
46
|
-
* @param notifier - Telegram notification service
|
|
47
|
-
* @param options - Optional recipe name prefix
|
|
48
|
-
* @returns Handle with `dispose()` to remove listeners
|
|
49
|
-
*/
|
|
50
|
-
export function createActionNotificationSubscriber(bus, notifier, options) {
|
|
51
|
-
const prefix = options?.strategyName ? `[${options.strategyName}] ` : "";
|
|
52
|
-
function notify(message) {
|
|
53
|
-
safeNotify(notifier, `${prefix}${message}`);
|
|
54
|
-
}
|
|
55
|
-
const onOpenSubmitted = (payload) => {
|
|
56
|
-
runNotificationHandler(() => {
|
|
57
|
-
// Only HookSystem-fired envelopes; ignore any other shape on this bus name.
|
|
58
|
-
if (!isHookEvent(payload) || payload.type !== HOOK_EVENT.ON_OPEN_ORDER_SUBMITTED)
|
|
59
|
-
return;
|
|
60
|
-
const data = payload.data;
|
|
61
|
-
notify(formatOrderSubmitted(data));
|
|
62
|
-
});
|
|
63
|
-
};
|
|
64
|
-
const onPositionClosed = (payload) => {
|
|
65
|
-
runNotificationHandler(() => {
|
|
66
|
-
/**
|
|
67
|
-
* The same event name is reused for two payload shapes: (1) HookEvent from actions /
|
|
68
|
-
* position-tracker via `hookSystem.fire`, and (2) flat objects from the DSL monitor and
|
|
69
|
-
* reconcile paths via `bus.emit(EVENTS.POSITION_CLOSED, { ... })`. Only (1) is
|
|
70
|
-
* action-layer Telegram; (2) is covered by `dsl.closed` + DSL notification subscriber.
|
|
71
|
-
*/
|
|
72
|
-
if (!isHookEvent(payload) || payload.type !== HOOK_EVENT.ON_POSITION_CLOSED)
|
|
73
|
-
return;
|
|
74
|
-
const data = payload.data;
|
|
75
|
-
if (data.reason === "position_tracker")
|
|
76
|
-
return;
|
|
77
|
-
notify(formatPositionClosed(data));
|
|
78
|
-
});
|
|
79
|
-
};
|
|
80
|
-
bus.on(HOOK_EVENT.ON_OPEN_ORDER_SUBMITTED, onOpenSubmitted);
|
|
81
|
-
bus.on(HOOK_EVENT.ON_POSITION_CLOSED, onPositionClosed);
|
|
82
|
-
return {
|
|
83
|
-
dispose() {
|
|
84
|
-
bus.off(HOOK_EVENT.ON_OPEN_ORDER_SUBMITTED, onOpenSubmitted);
|
|
85
|
-
bus.off(HOOK_EVENT.ON_POSITION_CLOSED, onPositionClosed);
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/actions/notifications/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Deferred close notifications: match `discovery_get_trader_history` rows to closed DSL positions
|
|
3
|
-
* and send enriched PnL / exit / fees, with a timeout fallback when history lags.
|
|
4
|
-
*/
|
|
5
|
-
import type { DslClosedEvent } from "../../types/dsl/index.js";
|
|
6
|
-
import type { PastTrade } from "../../types/strategy.js";
|
|
7
|
-
import type { StrategyState } from "../../types/strategy.js";
|
|
8
|
-
import type { PendingCloseNotification } from "./types.js";
|
|
9
|
-
/**
|
|
10
|
-
* Match tolerance (ms) between DSL timestamps and trade history `openTime` / `closedTime`.
|
|
11
|
-
*
|
|
12
|
-
* `MATCH_OPEN_TIME_MS` is wide (7 days) because scaled-in positions reset `createdAt` in
|
|
13
|
-
* DSL state while the exchange keeps the original `openTime`. This is safe: a wallet holds
|
|
14
|
-
* at most one directional position per asset, so `closedTime + coin + direction` is unique.
|
|
15
|
-
* `MATCH_CLOSE_TIME_MS` (2 min) is the real discriminator.
|
|
16
|
-
*/
|
|
17
|
-
export declare const MATCH_OPEN_TIME_MS: number;
|
|
18
|
-
export declare const MATCH_CLOSE_TIME_MS = 120000;
|
|
19
|
-
export interface CloseNotificationResolverOptions {
|
|
20
|
-
/** Directory for `pending-close-notifications/*.json` (caller passes `{stateDir}/pending-close-notifications`). */
|
|
21
|
-
pendingDir: string;
|
|
22
|
-
getStrategy: (address: string) => StrategyState | undefined;
|
|
23
|
-
/** Already includes `[recipe] ` prefix when strategy name is set. */
|
|
24
|
-
notify: (message: string) => void;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Finds the trade row that corresponds to a closed DSL position (coin/dex/direction + open/close times).
|
|
28
|
-
*
|
|
29
|
-
* Edge case: two closes for the same coin/direction within {@link MATCH_OPEN_TIME_MS} / {@link MATCH_CLOSE_TIME_MS}
|
|
30
|
-
* could both score the same row; follow-up could track claimed trade IDs per resolver pass if needed.
|
|
31
|
-
*/
|
|
32
|
-
export declare function matchTrade(pending: PendingCloseNotification, trades: PastTrade[]): PastTrade | undefined;
|
|
33
|
-
/** Builds a pending record from a bus payload (also used for immediate fallback when no resolver). */
|
|
34
|
-
export declare function buildPendingCloseFromEvent(e: DslClosedEvent, id: string): PendingCloseNotification;
|
|
35
|
-
/**
|
|
36
|
-
* Polls trade history and sends Telegram lines when a pending close is enriched or times out.
|
|
37
|
-
*/
|
|
38
|
-
export declare class CloseNotificationResolver {
|
|
39
|
-
private readonly pendingDir;
|
|
40
|
-
private readonly getStrategy;
|
|
41
|
-
private readonly notify;
|
|
42
|
-
private readonly pending;
|
|
43
|
-
private timer;
|
|
44
|
-
private pollMs;
|
|
45
|
-
/** Prevents overlapping `tick()` runs when a poll takes longer than `pollMs` (await yields). */
|
|
46
|
-
private tickInFlight;
|
|
47
|
-
constructor(opts: CloseNotificationResolverOptions);
|
|
48
|
-
/**
|
|
49
|
-
* Loads pending JSON from disk and starts the polling loop.
|
|
50
|
-
* Awaits the first {@link tick} so callers (tests, plugin init) do not observe stale in-memory state.
|
|
51
|
-
*/
|
|
52
|
-
start(pollIntervalMs?: number): Promise<void>;
|
|
53
|
-
/**
|
|
54
|
-
* Runs one poll pass; swallows errors so `setInterval` callbacks never surface as unhandled
|
|
55
|
-
* rejections. The initial call from {@link start} is awaited so the first `tick` completes
|
|
56
|
-
* before `start` resolves. Skips if the previous tick is still in progress so slow MCP calls
|
|
57
|
-
* cannot overlap and double-notify.
|
|
58
|
-
*/
|
|
59
|
-
private runTickSafe;
|
|
60
|
-
stop(): void;
|
|
61
|
-
/**
|
|
62
|
-
* Queue a close for enrichment (writes disk, in-memory map).
|
|
63
|
-
*
|
|
64
|
-
* On disk failure after the in-memory enqueue, the row stays in `pending` so polling can still
|
|
65
|
-
* resolve or time out; failures are logged and never propagate (subscriber uses fire-and-forget).
|
|
66
|
-
*/
|
|
67
|
-
enqueue(event: DslClosedEvent): Promise<void>;
|
|
68
|
-
private hydrateFromDisk;
|
|
69
|
-
private persist;
|
|
70
|
-
private removeFile;
|
|
71
|
-
private tick;
|
|
72
|
-
/**
|
|
73
|
-
* Increments retry count and sends the no-PnL fallback once the enqueue age exceeds the timeout.
|
|
74
|
-
* Used after unexpected errors so a pending row cannot wedge the resolver forever.
|
|
75
|
-
*/
|
|
76
|
-
private bumpRetryAndMaybeFallback;
|
|
77
|
-
/**
|
|
78
|
-
* Paginates `fetchPastTrades` (sorted by closedTime DESC) until a match is found or
|
|
79
|
-
* trades fall before the position's open time. Returns the matched trade, `undefined`
|
|
80
|
-
* when no match was found across all pages, or `"error"` on fetch failure.
|
|
81
|
-
*
|
|
82
|
-
* NOTE: offset-based pagination with descending closedTime can skip or duplicate a row
|
|
83
|
-
* when a new trade lands between page fetches (row shifts down by one). Cursor-style
|
|
84
|
-
* pagination (closedTime < lastSeen) would avoid this but the upstream API does not
|
|
85
|
-
* support it. At typical trade cadence and the ±120s match tolerance this is unlikely
|
|
86
|
-
* to cause a missed notification.
|
|
87
|
-
*/
|
|
88
|
-
private fetchAndMatch;
|
|
89
|
-
private resolveOne;
|
|
90
|
-
private finish;
|
|
91
|
-
}
|
|
92
|
-
//# sourceMappingURL=close-resolver.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"close-resolver.d.ts","sourceRoot":"","sources":["../../../src/dsl/notifications/close-resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAO7D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAK3D;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAA0B,CAAC;AAC1D,eAAO,MAAM,mBAAmB,SAAU,CAAC;AAO3C,MAAM,WAAW,gCAAgC;IAC/C,mHAAmH;IACnH,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;IAC5D,qEAAqE;IACrE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE,SAAS,EAAE,GAClB,SAAS,GAAG,SAAS,CAuBvB;AAED,sGAAsG;AACtG,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,wBAAwB,CA2BlG;AAED;;GAEG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiD;IAC7E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+C;IACvE,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,MAAM,CAAiC;IAC/C,gGAAgG;IAChG,OAAO,CAAC,YAAY,CAAS;gBAEjB,IAAI,EAAE,gCAAgC;IAMlD;;;OAGG;IACG,KAAK,CAAC,cAAc,GAAE,MAA8B,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E;;;;;OAKG;YACW,WAAW;IAYzB,IAAI,IAAI,IAAI;IAOZ;;;;;OAKG;IACG,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;YAerC,eAAe;YAuBf,OAAO;YAKP,UAAU;YAIV,IAAI;IAalB;;;OAGG;YACW,yBAAyB;IASvC;;;;;;;;;;OAUG;YACW,aAAa;YAsCb,UAAU;YAwCV,MAAM;CAKrB"}
|
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Deferred close notifications: match `discovery_get_trader_history` rows to closed DSL positions
|
|
3
|
-
* and send enriched PnL / exit / fees, with a timeout fallback when history lags.
|
|
4
|
-
*/
|
|
5
|
-
import { randomUUID } from "node:crypto";
|
|
6
|
-
import { mkdir, readdir, readFile, unlink, writeFile } from "node:fs/promises";
|
|
7
|
-
import { join } from "node:path";
|
|
8
|
-
import { CLOSE_RESOLVE_POLL_MS, CLOSE_RESOLVE_TIMEOUT_MS, } from "../../constants/dsl/index.js";
|
|
9
|
-
import { normalizeDslCoinDex } from "../../utils/perp-coin.js";
|
|
10
|
-
import { createLogger } from "../../utils/logger.js";
|
|
11
|
-
import { formatDslClosedEnriched, formatDslClosedFallback } from "./formatter.js";
|
|
12
|
-
const logger = createLogger("[senpi-core][dsl-close-resolver]");
|
|
13
|
-
/**
|
|
14
|
-
* Match tolerance (ms) between DSL timestamps and trade history `openTime` / `closedTime`.
|
|
15
|
-
*
|
|
16
|
-
* `MATCH_OPEN_TIME_MS` is wide (7 days) because scaled-in positions reset `createdAt` in
|
|
17
|
-
* DSL state while the exchange keeps the original `openTime`. This is safe: a wallet holds
|
|
18
|
-
* at most one directional position per asset, so `closedTime + coin + direction` is unique.
|
|
19
|
-
* `MATCH_CLOSE_TIME_MS` (2 min) is the real discriminator.
|
|
20
|
-
*/
|
|
21
|
-
export const MATCH_OPEN_TIME_MS = 7 * 24 * 60 * 60 * 1000;
|
|
22
|
-
export const MATCH_CLOSE_TIME_MS = 120_000;
|
|
23
|
-
/** Page size for paginated trade-history fetches. */
|
|
24
|
-
const TRADE_PAGE_SIZE = 20;
|
|
25
|
-
/** Safety cap on pages to prevent runaway pagination against a misbehaving API. */
|
|
26
|
-
const MAX_TRADE_PAGES = 10;
|
|
27
|
-
/**
|
|
28
|
-
* Finds the trade row that corresponds to a closed DSL position (coin/dex/direction + open/close times).
|
|
29
|
-
*
|
|
30
|
-
* Edge case: two closes for the same coin/direction within {@link MATCH_OPEN_TIME_MS} / {@link MATCH_CLOSE_TIME_MS}
|
|
31
|
-
* could both score the same row; follow-up could track claimed trade IDs per resolver pass if needed.
|
|
32
|
-
*/
|
|
33
|
-
export function matchTrade(pending, trades) {
|
|
34
|
-
const p = normalizeDslCoinDex(pending.asset, pending.dex);
|
|
35
|
-
const createdMs = Date.parse(pending.createdAt);
|
|
36
|
-
const closedMs = Date.parse(pending.closedAt);
|
|
37
|
-
if (!Number.isFinite(createdMs) || !Number.isFinite(closedMs))
|
|
38
|
-
return undefined;
|
|
39
|
-
let best;
|
|
40
|
-
let bestScore = Infinity;
|
|
41
|
-
for (const t of trades) {
|
|
42
|
-
const tcd = normalizeDslCoinDex(t.coin, t.dex ?? "");
|
|
43
|
-
if (tcd.coin !== p.coin || tcd.dex !== p.dex)
|
|
44
|
-
continue;
|
|
45
|
-
if (t.direction !== pending.direction)
|
|
46
|
-
continue;
|
|
47
|
-
const openDelta = Math.abs(t.openTime * 1000 - createdMs);
|
|
48
|
-
const closeDelta = Math.abs(t.closedTime * 1000 - closedMs);
|
|
49
|
-
if (openDelta > MATCH_OPEN_TIME_MS || closeDelta > MATCH_CLOSE_TIME_MS)
|
|
50
|
-
continue;
|
|
51
|
-
const score = openDelta + closeDelta;
|
|
52
|
-
if (score < bestScore) {
|
|
53
|
-
bestScore = score;
|
|
54
|
-
best = t;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return best;
|
|
58
|
-
}
|
|
59
|
-
/** Builds a pending record from a bus payload (also used for immediate fallback when no resolver). */
|
|
60
|
-
export function buildPendingCloseFromEvent(e, id) {
|
|
61
|
-
const margin = e.margin ??
|
|
62
|
-
(e.leverage && e.leverage > 0 && e.entryPrice != null && e.size != null
|
|
63
|
-
? (e.size * e.entryPrice) / e.leverage
|
|
64
|
-
: 0);
|
|
65
|
-
return {
|
|
66
|
-
id,
|
|
67
|
-
address: e.address,
|
|
68
|
-
asset: e.asset,
|
|
69
|
-
dex: e.dex ?? "",
|
|
70
|
-
direction: e.direction ?? "LONG",
|
|
71
|
-
entryPrice: e.entryPrice ?? 0,
|
|
72
|
-
leverage: e.leverage ?? 1,
|
|
73
|
-
margin,
|
|
74
|
-
size: e.size ?? 0,
|
|
75
|
-
closeReason: e.closeReason,
|
|
76
|
-
createdAt: e.createdAt ?? e.timestamp,
|
|
77
|
-
closedAt: e.timestamp,
|
|
78
|
-
lastPrice: e.lastPrice ?? 0,
|
|
79
|
-
currentROE: e.currentROE ?? 0,
|
|
80
|
-
peakROE: e.peakROE ?? 0,
|
|
81
|
-
currentTierIndex: e.currentTierIndex ?? null,
|
|
82
|
-
enqueuedAt: Date.now(),
|
|
83
|
-
retryCount: 0,
|
|
84
|
-
resolved: false,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Polls trade history and sends Telegram lines when a pending close is enriched or times out.
|
|
89
|
-
*/
|
|
90
|
-
export class CloseNotificationResolver {
|
|
91
|
-
pendingDir;
|
|
92
|
-
getStrategy;
|
|
93
|
-
notify;
|
|
94
|
-
pending = new Map();
|
|
95
|
-
timer = null;
|
|
96
|
-
pollMs = CLOSE_RESOLVE_POLL_MS;
|
|
97
|
-
/** Prevents overlapping `tick()` runs when a poll takes longer than `pollMs` (await yields). */
|
|
98
|
-
tickInFlight = false;
|
|
99
|
-
constructor(opts) {
|
|
100
|
-
this.pendingDir = opts.pendingDir;
|
|
101
|
-
this.getStrategy = opts.getStrategy;
|
|
102
|
-
this.notify = opts.notify;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Loads pending JSON from disk and starts the polling loop.
|
|
106
|
-
* Awaits the first {@link tick} so callers (tests, plugin init) do not observe stale in-memory state.
|
|
107
|
-
*/
|
|
108
|
-
async start(pollIntervalMs = CLOSE_RESOLVE_POLL_MS) {
|
|
109
|
-
this.pollMs = pollIntervalMs;
|
|
110
|
-
await mkdir(this.pendingDir, { recursive: true });
|
|
111
|
-
await this.hydrateFromDisk();
|
|
112
|
-
if (this.timer)
|
|
113
|
-
return;
|
|
114
|
-
this.timer = setInterval(() => {
|
|
115
|
-
void this.runTickSafe();
|
|
116
|
-
}, this.pollMs);
|
|
117
|
-
await this.runTickSafe();
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Runs one poll pass; swallows errors so `setInterval` callbacks never surface as unhandled
|
|
121
|
-
* rejections. The initial call from {@link start} is awaited so the first `tick` completes
|
|
122
|
-
* before `start` resolves. Skips if the previous tick is still in progress so slow MCP calls
|
|
123
|
-
* cannot overlap and double-notify.
|
|
124
|
-
*/
|
|
125
|
-
async runTickSafe() {
|
|
126
|
-
if (this.tickInFlight)
|
|
127
|
-
return;
|
|
128
|
-
this.tickInFlight = true;
|
|
129
|
-
try {
|
|
130
|
-
await this.tick();
|
|
131
|
-
}
|
|
132
|
-
catch (err) {
|
|
133
|
-
logger.warn("[dsl-close-resolver] tick failed", { err });
|
|
134
|
-
}
|
|
135
|
-
finally {
|
|
136
|
-
this.tickInFlight = false;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
stop() {
|
|
140
|
-
if (this.timer) {
|
|
141
|
-
clearInterval(this.timer);
|
|
142
|
-
this.timer = null;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Queue a close for enrichment (writes disk, in-memory map).
|
|
147
|
-
*
|
|
148
|
-
* On disk failure after the in-memory enqueue, the row stays in `pending` so polling can still
|
|
149
|
-
* resolve or time out; failures are logged and never propagate (subscriber uses fire-and-forget).
|
|
150
|
-
*/
|
|
151
|
-
async enqueue(event) {
|
|
152
|
-
const id = randomUUID();
|
|
153
|
-
const rec = buildPendingCloseFromEvent(event, id);
|
|
154
|
-
this.pending.set(id, rec);
|
|
155
|
-
try {
|
|
156
|
-
await mkdir(this.pendingDir, { recursive: true });
|
|
157
|
-
await this.persist(rec);
|
|
158
|
-
}
|
|
159
|
-
catch (err) {
|
|
160
|
-
logger.warn("[dsl-close-resolver] enqueue disk write failed; pending close kept in memory", {
|
|
161
|
-
err,
|
|
162
|
-
id,
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
async hydrateFromDisk() {
|
|
167
|
-
let names;
|
|
168
|
-
try {
|
|
169
|
-
names = await readdir(this.pendingDir);
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
for (const name of names) {
|
|
175
|
-
if (!name.endsWith(".json"))
|
|
176
|
-
continue;
|
|
177
|
-
try {
|
|
178
|
-
const raw = await readFile(join(this.pendingDir, name), "utf-8");
|
|
179
|
-
const rec = JSON.parse(raw);
|
|
180
|
-
if (rec.resolved) {
|
|
181
|
-
await unlink(join(this.pendingDir, name)).catch(() => { });
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
this.pending.set(rec.id, rec);
|
|
185
|
-
}
|
|
186
|
-
catch (err) {
|
|
187
|
-
logger.warn("[dsl-close-resolver] skip bad pending file", { name, err });
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
async persist(rec) {
|
|
192
|
-
const path = join(this.pendingDir, `${rec.id}.json`);
|
|
193
|
-
await writeFile(path, JSON.stringify(rec, null, 2), "utf-8");
|
|
194
|
-
}
|
|
195
|
-
async removeFile(id) {
|
|
196
|
-
await unlink(join(this.pendingDir, `${id}.json`)).catch(() => { });
|
|
197
|
-
}
|
|
198
|
-
async tick() {
|
|
199
|
-
for (const id of [...this.pending.keys()]) {
|
|
200
|
-
const rec = this.pending.get(id);
|
|
201
|
-
if (!rec || rec.resolved)
|
|
202
|
-
continue;
|
|
203
|
-
try {
|
|
204
|
-
await this.resolveOne(rec);
|
|
205
|
-
}
|
|
206
|
-
catch (err) {
|
|
207
|
-
logger.warn("[dsl-close-resolver] resolveOne failed", { id: rec.id, err });
|
|
208
|
-
await this.bumpRetryAndMaybeFallback(rec);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Increments retry count and sends the no-PnL fallback once the enqueue age exceeds the timeout.
|
|
214
|
-
* Used after unexpected errors so a pending row cannot wedge the resolver forever.
|
|
215
|
-
*/
|
|
216
|
-
async bumpRetryAndMaybeFallback(rec) {
|
|
217
|
-
rec.retryCount += 1;
|
|
218
|
-
const elapsed = Date.now() - rec.enqueuedAt;
|
|
219
|
-
if (elapsed >= CLOSE_RESOLVE_TIMEOUT_MS && this.pending.has(rec.id) && !rec.resolved) {
|
|
220
|
-
this.notify(formatDslClosedFallback(rec));
|
|
221
|
-
await this.finish(rec);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Paginates `fetchPastTrades` (sorted by closedTime DESC) until a match is found or
|
|
226
|
-
* trades fall before the position's open time. Returns the matched trade, `undefined`
|
|
227
|
-
* when no match was found across all pages, or `"error"` on fetch failure.
|
|
228
|
-
*
|
|
229
|
-
* NOTE: offset-based pagination with descending closedTime can skip or duplicate a row
|
|
230
|
-
* when a new trade lands between page fetches (row shifts down by one). Cursor-style
|
|
231
|
-
* pagination (closedTime < lastSeen) would avoid this but the upstream API does not
|
|
232
|
-
* support it. At typical trade cadence and the ±120s match tolerance this is unlikely
|
|
233
|
-
* to cause a missed notification.
|
|
234
|
-
*/
|
|
235
|
-
async fetchAndMatch(strategy, rec) {
|
|
236
|
-
const cutoffMs = Date.parse(rec.createdAt) - MATCH_OPEN_TIME_MS;
|
|
237
|
-
let offset = 0;
|
|
238
|
-
for (let page = 0; page < MAX_TRADE_PAGES; page++) {
|
|
239
|
-
let trades;
|
|
240
|
-
try {
|
|
241
|
-
trades = await strategy.fetchPastTrades({
|
|
242
|
-
limit: TRADE_PAGE_SIZE,
|
|
243
|
-
offset,
|
|
244
|
-
sort_by: "CLOSED_TIME",
|
|
245
|
-
sort_direction: "DESC",
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
catch (err) {
|
|
249
|
-
logger.warn("[dsl-close-resolver] fetchPastTrades failed", { id: rec.id, page, err });
|
|
250
|
-
return "error";
|
|
251
|
-
}
|
|
252
|
-
if (!trades?.length)
|
|
253
|
-
return undefined;
|
|
254
|
-
const hit = matchTrade(rec, trades);
|
|
255
|
-
if (hit)
|
|
256
|
-
return hit;
|
|
257
|
-
// Oldest trade in this page — if it predates the position open window, stop.
|
|
258
|
-
const oldestClosedTimeMs = Math.min(...trades.map((t) => t.closedTime)) * 1000;
|
|
259
|
-
if (oldestClosedTimeMs < cutoffMs)
|
|
260
|
-
return undefined;
|
|
261
|
-
// Partial page means we've exhausted results.
|
|
262
|
-
if (trades.length < TRADE_PAGE_SIZE)
|
|
263
|
-
return undefined;
|
|
264
|
-
offset += TRADE_PAGE_SIZE;
|
|
265
|
-
}
|
|
266
|
-
return undefined;
|
|
267
|
-
}
|
|
268
|
-
async resolveOne(rec) {
|
|
269
|
-
const elapsed = Date.now() - rec.enqueuedAt;
|
|
270
|
-
const strategy = this.getStrategy(rec.address);
|
|
271
|
-
if (!strategy) {
|
|
272
|
-
rec.retryCount += 1;
|
|
273
|
-
if (elapsed >= CLOSE_RESOLVE_TIMEOUT_MS) {
|
|
274
|
-
this.notify(formatDslClosedFallback(rec));
|
|
275
|
-
await this.finish(rec);
|
|
276
|
-
}
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
const hit = await this.fetchAndMatch(strategy, rec);
|
|
280
|
-
if (hit === "error") {
|
|
281
|
-
rec.retryCount += 1;
|
|
282
|
-
if (elapsed >= CLOSE_RESOLVE_TIMEOUT_MS) {
|
|
283
|
-
this.notify(formatDslClosedFallback(rec));
|
|
284
|
-
await this.finish(rec);
|
|
285
|
-
}
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
if (hit) {
|
|
289
|
-
this.notify(formatDslClosedEnriched(rec, {
|
|
290
|
-
realizedPnl: hit.realizedPnl,
|
|
291
|
-
closePx: hit.closePx,
|
|
292
|
-
totalFees: hit.totalFees,
|
|
293
|
-
}));
|
|
294
|
-
await this.finish(rec);
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
rec.retryCount += 1;
|
|
298
|
-
if (elapsed >= CLOSE_RESOLVE_TIMEOUT_MS) {
|
|
299
|
-
this.notify(formatDslClosedFallback(rec));
|
|
300
|
-
await this.finish(rec);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
async finish(rec) {
|
|
304
|
-
rec.resolved = true;
|
|
305
|
-
this.pending.delete(rec.id);
|
|
306
|
-
await this.removeFile(rec.id);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
//# sourceMappingURL=close-resolver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"close-resolver.js","sourceRoot":"","sources":["../../../src/dsl/notifications/close-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pending close notification persisted while waiting for trade-history enrichment.
|
|
3
|
-
*/
|
|
4
|
-
export interface PendingCloseNotification {
|
|
5
|
-
id: string;
|
|
6
|
-
address: string;
|
|
7
|
-
asset: string;
|
|
8
|
-
dex: string;
|
|
9
|
-
direction: "LONG" | "SHORT";
|
|
10
|
-
entryPrice: number;
|
|
11
|
-
leverage: number;
|
|
12
|
-
margin: number;
|
|
13
|
-
size: number;
|
|
14
|
-
closeReason: string;
|
|
15
|
-
/** Position open time (ISO). */
|
|
16
|
-
createdAt: string;
|
|
17
|
-
/** Position close time (ISO). */
|
|
18
|
-
closedAt: string;
|
|
19
|
-
lastPrice: number;
|
|
20
|
-
currentROE: number;
|
|
21
|
-
peakROE: number;
|
|
22
|
-
currentTierIndex: number | null;
|
|
23
|
-
enqueuedAt: number;
|
|
24
|
-
retryCount: number;
|
|
25
|
-
resolved: boolean;
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/dsl/notifications/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/dsl/notifications/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|