@senpi/runtime 3.0.102 → 3.0.106
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/actions/action-events.d.ts +7 -21
- package/dist/actions/action-events.d.ts.map +1 -1
- package/dist/actions/action-events.js +25 -56
- package/dist/actions/action-events.js.map +1 -1
- package/dist/actions/action-runtime-module.d.ts.map +1 -1
- package/dist/actions/action-runtime-module.js +1 -18
- package/dist/actions/action-runtime-module.js.map +1 -1
- package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
- package/dist/actions/close-position/close-position.action.js +12 -86
- package/dist/actions/close-position/close-position.action.js.map +1 -1
- package/dist/actions/event-derivation.d.ts +2 -40
- package/dist/actions/event-derivation.d.ts.map +1 -1
- package/dist/actions/event-derivation.js +9 -189
- package/dist/actions/event-derivation.js.map +1 -1
- package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
- package/dist/actions/open-position/open-position.action.js +17 -115
- package/dist/actions/open-position/open-position.action.js.map +1 -1
- package/dist/actions/position-tracker/position-tracker.action.d.ts +1 -2
- package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -1
- package/dist/actions/position-tracker/position-tracker.action.js +15 -50
- package/dist/actions/position-tracker/position-tracker.action.js.map +1 -1
- package/dist/dsl/engine-client/event-mapping.d.ts.map +1 -1
- package/dist/dsl/engine-client/event-mapping.js +0 -15
- package/dist/dsl/engine-client/event-mapping.js.map +1 -1
- package/dist/dsl/events/build-closed-event.d.ts +1 -16
- package/dist/dsl/events/build-closed-event.d.ts.map +1 -1
- package/dist/dsl/events/build-closed-event.js +0 -5
- package/dist/dsl/events/build-closed-event.js.map +1 -1
- package/dist/dsl/events/handlers.d.ts +0 -7
- package/dist/dsl/events/handlers.d.ts.map +1 -1
- package/dist/dsl/events/handlers.js +7 -49
- package/dist/dsl/events/handlers.js.map +1 -1
- package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
- package/dist/dsl/monitor/create-monitor.js +0 -7
- package/dist/dsl/monitor/create-monitor.js.map +1 -1
- package/dist/dsl/monitor/dsl-failure-events.d.ts +0 -2
- package/dist/dsl/monitor/dsl-failure-events.d.ts.map +1 -1
- package/dist/dsl/monitor/dsl-failure-events.js +1 -2
- package/dist/dsl/monitor/dsl-failure-events.js.map +1 -1
- package/dist/dsl/monitor/process-one-position.d.ts +0 -6
- package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
- package/dist/dsl/monitor/process-one-position.js +21 -55
- package/dist/dsl/monitor/process-one-position.js.map +1 -1
- package/dist/health/types.d.ts +0 -6
- package/dist/health/types.d.ts.map +1 -1
- package/dist/health/types.js.map +1 -1
- package/dist/index.d.ts +4 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -245
- package/dist/index.js.map +1 -1
- package/dist/runtime/domain-events.d.ts.map +1 -1
- package/dist/runtime/domain-events.js +0 -7
- package/dist/runtime/domain-events.js.map +1 -1
- package/dist/runtime/lifecycle-events.d.ts +1 -9
- package/dist/runtime/lifecycle-events.d.ts.map +1 -1
- package/dist/runtime/lifecycle-events.js +2 -11
- package/dist/runtime/lifecycle-events.js.map +1 -1
- package/dist/runtime/reconcile-run.d.ts +0 -2
- package/dist/runtime/reconcile-run.d.ts.map +1 -1
- package/dist/runtime/reconcile-run.js +1 -2
- package/dist/runtime/reconcile-run.js.map +1 -1
- package/dist/runtime/reconcile-state.d.ts +0 -8
- package/dist/runtime/reconcile-state.d.ts.map +1 -1
- package/dist/runtime/reconcile-state.js +1 -3
- package/dist/runtime/reconcile-state.js.map +1 -1
- package/dist/runtime/runtime.d.ts +5 -5
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +20 -44
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/strategy-registry.d.ts +1 -0
- package/dist/runtime/strategy-registry.d.ts.map +1 -1
- package/dist/runtime/strategy-registry.js +19 -0
- package/dist/runtime/strategy-registry.js.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.d.ts +0 -8
- package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js +0 -1
- package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
- package/dist/runtime/update-apply-deps.d.ts +6 -0
- package/dist/runtime/update-apply-deps.d.ts.map +1 -1
- package/dist/runtime/update-apply-deps.js +8 -19
- package/dist/runtime/update-apply-deps.js.map +1 -1
- package/dist/runtime-api/intake/intake-events.d.ts +3 -3
- package/dist/runtime-api/intake/intake-events.d.ts.map +1 -1
- package/dist/runtime-api/intake/intake-events.js +3 -21
- package/dist/runtime-api/intake/intake-events.js.map +1 -1
- package/dist/runtime-api/intake/intake-mount.d.ts +2 -0
- package/dist/runtime-api/intake/intake-mount.d.ts.map +1 -1
- package/dist/runtime-api/intake/intake-mount.js +10 -57
- package/dist/runtime-api/intake/intake-mount.js.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.d.ts +0 -11
- package/dist/runtime-api/intake/process-signal-post.d.ts.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.js +8 -39
- package/dist/runtime-api/intake/process-signal-post.js.map +1 -1
- package/dist/runtime-api/intake/scaffold-error-router.d.ts +43 -0
- package/dist/runtime-api/intake/scaffold-error-router.d.ts.map +1 -0
- package/dist/runtime-api/intake/scaffold-error-router.js +63 -0
- package/dist/runtime-api/intake/scaffold-error-router.js.map +1 -0
- package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
- package/dist/runtime-api/intake/scanner-launcher.js +0 -12
- package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
- package/dist/runtime-api/intake/types.d.ts +1 -22
- package/dist/runtime-api/intake/types.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.js +1 -7
- package/dist/runtime-api/routes/signals.js.map +1 -1
- package/dist/runtime-api/routes/signals.schema.d.ts +0 -1
- package/dist/runtime-api/routes/signals.schema.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.schema.js +0 -6
- package/dist/runtime-api/routes/signals.schema.js.map +1 -1
- package/dist/scanners/engine/engine.d.ts +0 -5
- package/dist/scanners/engine/engine.d.ts.map +1 -1
- package/dist/scanners/engine/engine.js +2 -30
- package/dist/scanners/engine/engine.js.map +1 -1
- package/dist/scanners/external/scaffold/delivery.py +12 -79
- package/dist/scanners/external/scaffold/scaffold.py +9 -63
- package/dist/scanners/external/scaffold/senpi_mcp.py +81 -10
- package/dist/scanners/external-scanner-receiver.d.ts +0 -11
- package/dist/scanners/external-scanner-receiver.d.ts.map +1 -1
- package/dist/scanners/external-scanner-receiver.js.map +1 -1
- package/dist/scanners/runtime-module.d.ts.map +1 -1
- package/dist/scanners/runtime-module.js +0 -5
- package/dist/scanners/runtime-module.js.map +1 -1
- package/dist/senpi/client.d.ts.map +1 -1
- package/dist/senpi/client.js +4 -12
- package/dist/senpi/client.js.map +1 -1
- package/dist/senpi/types.d.ts +0 -5
- package/dist/senpi/types.d.ts.map +1 -1
- package/dist/skills-manager/manifest.d.ts.map +1 -1
- package/dist/skills-manager/manifest.js +3 -12
- package/dist/skills-manager/manifest.js.map +1 -1
- package/dist/skills-manager/skills-manifest.json +3 -3
- package/dist/telemetry/event-builders.d.ts +6 -74
- package/dist/telemetry/event-builders.d.ts.map +1 -1
- package/dist/telemetry/event-builders.js +11 -108
- package/dist/telemetry/event-builders.js.map +1 -1
- package/dist/telemetry/event-store.d.ts +0 -6
- package/dist/telemetry/event-store.d.ts.map +1 -1
- package/dist/telemetry/event-store.js +6 -6
- package/dist/telemetry/event-store.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +2 -14
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/metrics.js +4 -19
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/telemetry/tracing.d.ts +0 -9
- package/dist/telemetry/tracing.d.ts.map +1 -1
- package/dist/telemetry/tracing.js +0 -36
- package/dist/telemetry/tracing.js.map +1 -1
- package/dist/types/dsl/index.d.ts +0 -11
- package/dist/types/dsl/index.d.ts.map +1 -1
- package/dist/types/scanner.d.ts +0 -9
- package/dist/types/scanner.d.ts.map +1 -1
- package/dist/utils/event-catalog.d.ts +0 -81
- package/dist/utils/event-catalog.d.ts.map +1 -1
- package/dist/utils/event-catalog.js +0 -1
- package/dist/utils/event-catalog.js.map +1 -1
- package/dist/utils/keyed-mutex.d.ts +1 -3
- package/dist/utils/keyed-mutex.d.ts.map +1 -1
- package/dist/utils/keyed-mutex.js +1 -3
- package/dist/utils/keyed-mutex.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/actions/skipped-signal-results.d.ts +0 -16
- package/dist/actions/skipped-signal-results.d.ts.map +0 -1
- package/dist/actions/skipped-signal-results.js +0 -47
- package/dist/actions/skipped-signal-results.js.map +0 -1
- package/dist/scanners/external/scaffold/ulid.py +0 -58
- package/dist/telemetry/live-telemetry.d.ts +0 -158
- package/dist/telemetry/live-telemetry.d.ts.map +0 -1
- package/dist/telemetry/live-telemetry.js +0 -581
- package/dist/telemetry/live-telemetry.js.map +0 -1
- package/dist/telemetry/scanner-stats.d.ts +0 -136
- package/dist/telemetry/scanner-stats.d.ts.map +0 -1
- package/dist/telemetry/scanner-stats.js +0 -304
- package/dist/telemetry/scanner-stats.js.map +0 -1
- package/dist/telemetry/strategy-topology.d.ts +0 -99
- package/dist/telemetry/strategy-topology.d.ts.map +0 -1
- package/dist/telemetry/strategy-topology.js +0 -93
- package/dist/telemetry/strategy-topology.js.map +0 -1
- package/dist/telemetry/telemetry-publisher.d.ts +0 -63
- package/dist/telemetry/telemetry-publisher.d.ts.map +0 -1
- package/dist/telemetry/telemetry-publisher.js +0 -229
- package/dist/telemetry/telemetry-publisher.js.map +0 -1
- package/dist/telemetry/timeline-buffer.d.ts +0 -95
- package/dist/telemetry/timeline-buffer.d.ts.map +0 -1
- package/dist/telemetry/timeline-buffer.js +0 -237
- package/dist/telemetry/timeline-buffer.js.map +0 -1
- package/dist/utils/ulid.d.ts +0 -9
- package/dist/utils/ulid.d.ts.map +0 -1
- package/dist/utils/ulid.js +0 -43
- package/dist/utils/ulid.js.map +0 -1
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-signal `results[]` rows synthesized for a batch-level early exit — the exits that return
|
|
3
|
-
* before the per-signal loop and would otherwise leave the scan's signals with no recorded outcome.
|
|
4
|
-
* Entry shape matches the loop's own rows so the derived per-signal telemetry is identical in
|
|
5
|
-
* structure: normalized `dex`, `direction`/`score` only when usable, and a zero-width work window
|
|
6
|
-
* (both stamps present — a half window is dropped downstream, and a missing one is
|
|
7
|
-
* indistinguishable from an unstamped legacy row).
|
|
8
|
-
*
|
|
9
|
-
* A signal with no usable asset is dropped: an outcome that names no asset is not attributable.
|
|
10
|
-
* Total by construction — it runs on the trading path and must never throw on a malformed entry.
|
|
11
|
-
*/
|
|
12
|
-
export function skippedSignalResults(signals, reason, nowMs, overrides) {
|
|
13
|
-
if (!Array.isArray(signals))
|
|
14
|
-
return [];
|
|
15
|
-
const rows = [];
|
|
16
|
-
for (const raw of signals) {
|
|
17
|
-
if (raw === null || typeof raw !== 'object')
|
|
18
|
-
continue;
|
|
19
|
-
const signal = raw;
|
|
20
|
-
const rawAsset = signal.asset;
|
|
21
|
-
// Kept verbatim (not trimmed) so it still joins the scanner signal it came from.
|
|
22
|
-
const asset = typeof rawAsset === 'string' ? rawAsset : typeof rawAsset === 'number' ? String(rawAsset) : '';
|
|
23
|
-
if (asset.trim() === '')
|
|
24
|
-
continue;
|
|
25
|
-
const direction = signal.direction;
|
|
26
|
-
const score = signal.score;
|
|
27
|
-
// A decision-payload signal carries the book top-level (the strategy hoists it there); a raw
|
|
28
|
-
// scanner signal carries it only on `meta`, since `Signal` has no `dex` field. Both call
|
|
29
|
-
// shapes reach this helper, so both are read — top-level first, matching the per-signal loop.
|
|
30
|
-
const meta = signal.meta;
|
|
31
|
-
const metaDex = meta !== null && typeof meta === 'object' ? meta.dex : undefined;
|
|
32
|
-
const dex = typeof signal.dex === 'string' && signal.dex.trim() !== '' ? signal.dex : metaDex;
|
|
33
|
-
rows.push({
|
|
34
|
-
asset,
|
|
35
|
-
...(direction === 'LONG' || direction === 'SHORT' ? { direction } : {}),
|
|
36
|
-
dex: typeof dex === 'string' && dex.trim() !== '' ? dex.trim() : 'main',
|
|
37
|
-
...(typeof score === 'number' && Number.isFinite(score) ? { score } : {}),
|
|
38
|
-
success: overrides?.success ?? true,
|
|
39
|
-
reason,
|
|
40
|
-
...(overrides?.error !== undefined ? { error: overrides.error } : {}),
|
|
41
|
-
startedAt: nowMs,
|
|
42
|
-
endedAt: nowMs,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
return rows;
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=skipped-signal-results.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skipped-signal-results.js","sourceRoot":"","sources":["../../src/actions/skipped-signal-results.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAuC,EACvC,MAAc,EACd,KAAa,EACb,SAAiD;IAEjD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,IAAI,GAAmC,EAAE,CAAC;IAChD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,SAAS;QACtD,MAAM,MAAM,GAAG,GAA8B,CAAC;QAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;QAC9B,iFAAiF;QACjF,MAAM,KAAK,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7G,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QAClC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,6FAA6F;QAC7F,yFAAyF;QACzF,8FAA8F;QAC9F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAgC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9G,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QAC9F,IAAI,CAAC,IAAI,CAAC;YACR,KAAK;YACL,GAAG,CAAC,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,EAAE,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM;YACvE,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI,IAAI;YACnC,MAAM;YACN,GAAG,CAAC,SAAS,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"""ULID minting: a 26-character, lexicographically sortable id — 48 bits of millisecond timestamp
|
|
2
|
-
followed by 80 bits of randomness, rendered in Crockford's base32. Sortable ids are what let two
|
|
3
|
-
ticks be ordered without carrying a second field, and 80 random bits make a collision between two
|
|
4
|
-
ticks of the same millisecond unreachable.
|
|
5
|
-
|
|
6
|
-
Mirrors src/utils/ulid.ts so a scaffold id and a runtime id are the same kind of value. The random
|
|
7
|
-
half is read out of a `uuid.uuid4()`, taking only the ten bytes that carry no version or variant
|
|
8
|
-
bits, so all 80 of them are random.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from __future__ import annotations
|
|
12
|
-
|
|
13
|
-
import math
|
|
14
|
-
import time
|
|
15
|
-
import uuid
|
|
16
|
-
|
|
17
|
-
# Crockford's base32: no I, L, O or U, so a transcribed id cannot be misread.
|
|
18
|
-
CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
|
19
|
-
|
|
20
|
-
TIME_CHARS = 10
|
|
21
|
-
RANDOM_CHARS = 16
|
|
22
|
-
MAX_TIME = 2 ** 48 - 1
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def _encode_time(ms) -> str:
|
|
26
|
-
"""Render `ms` as the 10-character time prefix.
|
|
27
|
-
|
|
28
|
-
Clamped, and never raised from: a clock that reads non-finite, negative, or past the 48-bit
|
|
29
|
-
ceiling must still yield a valid id rather than kill the tick that asked for one.
|
|
30
|
-
"""
|
|
31
|
-
try:
|
|
32
|
-
remaining = min(max(math.floor(ms), 0), MAX_TIME)
|
|
33
|
-
except (OverflowError, ValueError, TypeError):
|
|
34
|
-
remaining = 0
|
|
35
|
-
out = ""
|
|
36
|
-
for _ in range(TIME_CHARS):
|
|
37
|
-
out = CROCKFORD[remaining % 32] + out
|
|
38
|
-
remaining //= 32
|
|
39
|
-
return out
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _encode_random() -> str:
|
|
43
|
-
"""Render 80 random bits as the 16-character suffix, five bits at a time."""
|
|
44
|
-
# uuid4 holds its version and variant in bytes 6 and 8; the ten bytes taken here are the
|
|
45
|
-
# fully random ones.
|
|
46
|
-
raw = uuid.uuid4().bytes
|
|
47
|
-
acc = int.from_bytes(raw[:6] + raw[9:13], "big")
|
|
48
|
-
return "".join(
|
|
49
|
-
CROCKFORD[(acc >> shift) & 31]
|
|
50
|
-
for shift in range(RANDOM_CHARS * 5 - 5, -1, -5)
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def new_ulid(now_ms: int | None = None) -> str:
|
|
55
|
-
"""Mint a ULID. `now_ms` is injectable so a caller can pin the time half in a test."""
|
|
56
|
-
if now_ms is None:
|
|
57
|
-
now_ms = int(time.time() * 1000)
|
|
58
|
-
return _encode_time(now_ms) + _encode_random()
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The publisher: the piece that turns the buffer and the three builders into frames on the gateway
|
|
3
|
-
* websocket, plus the snapshot a client reads when it connects.
|
|
4
|
-
*
|
|
5
|
-
* Two things about the transport shape the whole module:
|
|
6
|
-
* - The only route to the websocket is a captured `context.broadcast`, and `context` exists only
|
|
7
|
-
* inside a gateway RPC handler — the plugin api object has no push surface at all. So the handle is
|
|
8
|
-
* captured from the FIRST request of ANY kind, not only from the subscribe method: a box whose
|
|
9
|
-
* client never calls subscribe would otherwise hold nothing to publish through, silently.
|
|
10
|
-
* - The gateway drops any event name that does not start with `plugin.`, and closes the socket with
|
|
11
|
-
* 1008 for a slow client unless the call passes `dropIfSlow`. Both are enforced here rather than at
|
|
12
|
-
* each call site, because either mistake is invisible until a client is missing frames.
|
|
13
|
-
*
|
|
14
|
-
* Three cadences, because the three payloads cost different things to build:
|
|
15
|
-
* - timeline, on the flush tick — a drain plus a filter, cheap, and the one a live screen feels.
|
|
16
|
-
* - stats, on the sample tick — a scan of the whole held window and an async read of every runtime's
|
|
17
|
-
* health and system state, so it runs an order of magnitude less often.
|
|
18
|
-
* - topology, on the sample tick but published only when it changes — it rides the same gather as
|
|
19
|
-
* stats, and nothing in the plugin signals a topology change, so "on change" means polled and
|
|
20
|
-
* diffed rather than pushed.
|
|
21
|
-
*
|
|
22
|
-
* The snapshot is what stops a client that joins mid-life from seeing an empty screen: it is read
|
|
23
|
-
* from the buffer's held window, which the flush drain never evicts.
|
|
24
|
-
*
|
|
25
|
-
* Everything that leaves the box is scrubbed here. `logger.event` redacts its `redact` slot and not
|
|
26
|
-
* its `attributes`, which is sound for the disk ring — that never leaves — but not for a stream a
|
|
27
|
-
* browser reads. Both outbound paths funnel through {@link toWireRecord}, so that is where the
|
|
28
|
-
* scrub sits; it is what makes the flush tick asynchronous and gives it an in-flight guard.
|
|
29
|
-
*/
|
|
30
|
-
import type { EventName } from "../utils/event-catalog.js";
|
|
31
|
-
import { type TimelineBuffer } from "./timeline-buffer.js";
|
|
32
|
-
import { type ScannerStateSnapshot, type ScannerStatsPayload } from "./scanner-stats.js";
|
|
33
|
-
import { type IdMembership, type RuntimeHealthLike, type StrategyTopologyPayload, type TopologyStrategySource } from "./strategy-topology.js";
|
|
34
|
-
/** The gateway drops any broadcast whose name does not carry this prefix, with no error. */
|
|
35
|
-
export declare const EVENT_TIMELINE = "plugin.senpi.timeline";
|
|
36
|
-
export declare const EVENT_STATS = "plugin.senpi.scanner.stats";
|
|
37
|
-
export declare const EVENT_TOPOLOGY = "plugin.senpi.strategies";
|
|
38
|
-
/**
|
|
39
|
-
* Byte ceiling for one frame. The bridge's north read limit is 256 KiB and a breach closes the
|
|
40
|
-
* client socket with 1009, so the budget is set at half of it: the payload envelope the gateway wraps
|
|
41
|
-
* around ours, and the growth of a single record's attribute bag, both have to fit inside the margin.
|
|
42
|
-
*/
|
|
43
|
-
export declare const MAX_FRAME_BYTES: number;
|
|
44
|
-
/** Flush cadence for the timeline. A live screen feels this number. */
|
|
45
|
-
export declare const DEFAULT_FLUSH_INTERVAL_MS = 1000;
|
|
46
|
-
/**
|
|
47
|
-
* Sample cadence for stats and topology. Both are built from one async read of every runtime's health
|
|
48
|
-
* and system state, so they share a tick. Five seconds is roughly a third of the default bucket width
|
|
49
|
-
* — fast enough that a counter visibly moves and a hung scan is seen while it is still running, slow
|
|
50
|
-
* enough that the per-scanner store read behind the system state is not a poll loop.
|
|
51
|
-
*/
|
|
52
|
-
export declare const DEFAULT_SAMPLE_INTERVAL_MS = 5000;
|
|
53
|
-
/**
|
|
54
|
-
* The PUBLICATION list: what leaves on the timeline event. A name being on this list AND on the
|
|
55
|
-
* admission list is the normal case, not a duplication — `signal.outcome` is the decision row the feed
|
|
56
|
-
* is built around and the source of `opens`/`closes`/`skips`, and the two `scaffold.tick_*` names are
|
|
57
|
-
* the source of `errors` and the rows behind the Errors filter. A failing external scanner has to
|
|
58
|
-
* leave a visible line, not only a number that silently goes up.
|
|
59
|
-
*
|
|
60
|
-
* The two lists are separate so admission can be widened for a counter the feed does not display,
|
|
61
|
-
* which is the direction that has to stay open: the display filter belongs here at publish time,
|
|
62
|
-
* where it is still recoverable, never at append time, where it is not. Today nothing is admitted for
|
|
63
|
-
* counting alone, so the sets are equal — the seam is what matters, not the difference.
|
|
64
|
-
*/
|
|
65
|
-
export declare const PUBLISHED_EVENT_NAMES: ReadonlySet<EventName>;
|
|
66
|
-
/**
|
|
67
|
-
* The share of its own interval a tick may take before it is warned about. A fraction rather than a
|
|
68
|
-
* constant, so a deployment that changes a cadence gets a proportional threshold: 250ms on the
|
|
69
|
-
* one-second timeline flush, 1.25s on the five-second sample.
|
|
70
|
-
*
|
|
71
|
-
* A quarter, not a whole interval. Both ticks share an event loop with the serial trading path, so a
|
|
72
|
-
* tick holding it for a quarter of its own period is already adding latency to trading; and a tick
|
|
73
|
-
* that fills its interval has already started stacking on the next one, which is too late to be told.
|
|
74
|
-
*/
|
|
75
|
-
export declare const SLOW_TICK_FRACTION = 0.25;
|
|
76
|
-
/**
|
|
77
|
-
* How often the timing summary is logged, and the floor between two slow-tick warns of the same kind.
|
|
78
|
-
* The flush tick runs every second, so a line per tick would be tens of thousands a day for numbers
|
|
79
|
-
* that only mean anything aggregated — and a repeating tick that is slow is slow every time.
|
|
80
|
-
*/
|
|
81
|
-
export declare const TIMING_REPORT_INTERVAL_MS = 60000;
|
|
82
|
-
export interface GatewayBroadcastOpts {
|
|
83
|
-
dropIfSlow?: boolean;
|
|
84
|
-
stateVersion?: number;
|
|
85
|
-
}
|
|
86
|
-
export type GatewayBroadcastFn = (event: string, payload: unknown, opts?: GatewayBroadcastOpts) => void;
|
|
87
|
-
/** One record as it goes on the wire. */
|
|
88
|
-
export interface TimelineWireRecord {
|
|
89
|
-
seq: number;
|
|
90
|
-
ts: number;
|
|
91
|
-
name: string;
|
|
92
|
-
level: string;
|
|
93
|
-
address: string;
|
|
94
|
-
scannerId?: string;
|
|
95
|
-
body: string;
|
|
96
|
-
attrs: Record<string, string | number | boolean>;
|
|
97
|
-
}
|
|
98
|
-
export interface TimelinePayload {
|
|
99
|
-
v: 1;
|
|
100
|
-
epoch: string;
|
|
101
|
-
batchSeq: number;
|
|
102
|
-
records: TimelineWireRecord[];
|
|
103
|
-
}
|
|
104
|
-
export interface TelemetrySnapshot {
|
|
105
|
-
epoch: string;
|
|
106
|
-
topology: StrategyTopologyPayload;
|
|
107
|
-
stats: ScannerStatsPayload;
|
|
108
|
-
recent: TimelinePayload;
|
|
109
|
-
/**
|
|
110
|
-
* The client asked to resume from a cursor inside THIS epoch whose successor is no longer held, or
|
|
111
|
-
* the window it is owed did not fit one frame. Either way there is a gap this response cannot fill,
|
|
112
|
-
* and only the box knows it: `recent.records` alone looks like a normal short window.
|
|
113
|
-
*
|
|
114
|
-
* A cursor from another epoch is not truncation. It buys nothing, so the whole retained window is
|
|
115
|
-
* served — which is the most this box could ever serve, and so nothing was withheld.
|
|
116
|
-
*/
|
|
117
|
-
truncated: boolean;
|
|
118
|
-
}
|
|
119
|
-
/** Everything the two builders need that the buffer cannot supply, gathered once per tick. */
|
|
120
|
-
export interface TelemetryFacts {
|
|
121
|
-
strategies: TopologyStrategySource[];
|
|
122
|
-
runningRuntimeIds: IdMembership;
|
|
123
|
-
unwiredRuntimeIds: IdMembership;
|
|
124
|
-
readHealth?: (runtimeId: string) => RuntimeHealthLike | undefined;
|
|
125
|
-
scannerState: ScannerStateSnapshot[];
|
|
126
|
-
}
|
|
127
|
-
export interface LiveTelemetryOptions {
|
|
128
|
-
/** Defaults to the process buffer — one per process, shared by every address. */
|
|
129
|
-
buffer?: TimelineBuffer;
|
|
130
|
-
collectFacts: () => Promise<TelemetryFacts>;
|
|
131
|
-
flushIntervalMs?: number;
|
|
132
|
-
sampleIntervalMs?: number;
|
|
133
|
-
now?: () => number;
|
|
134
|
-
/**
|
|
135
|
-
* Monotonic millisecond reader for tick durations. Defaults to `performance.now`; `now` is wall
|
|
136
|
-
* clock and can step backwards under NTP, which would report a negative tick.
|
|
137
|
-
*/
|
|
138
|
-
monotonicMs?: () => number;
|
|
139
|
-
}
|
|
140
|
-
export interface LiveTelemetry {
|
|
141
|
-
readonly epoch: string;
|
|
142
|
-
/** Take the broadcast handle off a gateway request context if we do not hold one yet. */
|
|
143
|
-
captureBroadcast(ctx: unknown, methodName: string): void;
|
|
144
|
-
/** `afterSeq` counts only when `afterEpoch` is the epoch this box is running. */
|
|
145
|
-
snapshot(params?: {
|
|
146
|
-
afterEpoch?: unknown;
|
|
147
|
-
afterSeq?: unknown;
|
|
148
|
-
}): Promise<TelemetrySnapshot>;
|
|
149
|
-
/** One flush tick: drain, filter to the publication list, scrub, frame, broadcast. */
|
|
150
|
-
flushTimeline(): Promise<void>;
|
|
151
|
-
/** One sample tick: stats always, topology when it changed. */
|
|
152
|
-
sample(): Promise<void>;
|
|
153
|
-
start(): void;
|
|
154
|
-
/** Clear both timers, drop the captured handle, and empty the buffer. */
|
|
155
|
-
stop(): void;
|
|
156
|
-
}
|
|
157
|
-
export declare function createLiveTelemetry(options: LiveTelemetryOptions): LiveTelemetry;
|
|
158
|
-
//# sourceMappingURL=live-telemetry.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"live-telemetry.d.ts","sourceRoot":"","sources":["../../src/telemetry/live-telemetry.ts"],"names":[],"mappings":"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"}
|