@senpi/runtime 3.0.171 → 3.0.180
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/close-position/close-position.action.d.ts.map +1 -1
- package/dist/actions/close-position/close-position.action.js +48 -3
- package/dist/actions/close-position/close-position.action.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 +42 -6
- package/dist/actions/open-position/open-position.action.js.map +1 -1
- package/dist/actions/open-position/resolve-margin.d.ts +1 -1
- package/dist/actions/open-position/resolve-margin.d.ts.map +1 -1
- package/dist/actions/open-position/resolve-margin.js +7 -0
- package/dist/actions/open-position/resolve-margin.js.map +1 -1
- package/dist/approvals/manifest.d.ts.map +1 -1
- package/dist/approvals/manifest.js +0 -5
- package/dist/approvals/manifest.js.map +1 -1
- package/dist/approvals/tool-approval-gate.d.ts.map +1 -1
- package/dist/approvals/tool-approval-gate.js +0 -6
- package/dist/approvals/tool-approval-gate.js.map +1 -1
- package/dist/approvals/tool-approvals-manifest.json +0 -2
- package/dist/cli/guide-commands.d.ts.map +1 -1
- package/dist/cli/guide-commands.js +26 -5
- package/dist/cli/guide-commands.js.map +1 -1
- package/dist/cli/senpi-commands.d.ts.map +1 -1
- package/dist/cli/senpi-commands.js +20 -8
- package/dist/cli/senpi-commands.js.map +1 -1
- package/dist/constants/dsl/index.d.ts +2 -0
- package/dist/constants/dsl/index.d.ts.map +1 -1
- package/dist/constants/dsl/index.js +2 -0
- package/dist/constants/dsl/index.js.map +1 -1
- package/dist/constants/order-types.d.ts.map +1 -1
- package/dist/constants/order-types.js +4 -1
- package/dist/constants/order-types.js.map +1 -1
- package/dist/deploy/messages.d.ts +15 -1
- package/dist/deploy/messages.d.ts.map +1 -1
- package/dist/deploy/messages.js +78 -0
- package/dist/deploy/messages.js.map +1 -1
- package/dist/deploy/orchestrator.d.ts +11 -1
- package/dist/deploy/orchestrator.d.ts.map +1 -1
- package/dist/deploy/orchestrator.js +111 -15
- package/dist/deploy/orchestrator.js.map +1 -1
- package/dist/deploy/register.d.ts +7 -0
- package/dist/deploy/register.d.ts.map +1 -1
- package/dist/deploy/register.js +9 -0
- package/dist/deploy/register.js.map +1 -1
- package/dist/dsl/engine/exchange-stop.d.ts +21 -1
- package/dist/dsl/engine/exchange-stop.d.ts.map +1 -1
- package/dist/dsl/engine/exchange-stop.js +27 -1
- package/dist/dsl/engine/exchange-stop.js.map +1 -1
- package/dist/dsl/engine/floors.d.ts +2 -1
- package/dist/dsl/engine/floors.d.ts.map +1 -1
- package/dist/dsl/engine/floors.js +2 -1
- package/dist/dsl/engine/floors.js.map +1 -1
- package/dist/dsl/engine/index.d.ts +1 -1
- package/dist/dsl/engine/index.d.ts.map +1 -1
- package/dist/dsl/engine/index.js +1 -1
- package/dist/dsl/engine/index.js.map +1 -1
- package/dist/dsl/engine/tick.d.ts.map +1 -1
- package/dist/dsl/engine/tick.js +4 -3
- package/dist/dsl/engine/tick.js.map +1 -1
- package/dist/dsl/engine-client/config-mapping.d.ts +18 -0
- package/dist/dsl/engine-client/config-mapping.d.ts.map +1 -1
- package/dist/dsl/engine-client/config-mapping.js +29 -0
- package/dist/dsl/engine-client/config-mapping.js.map +1 -1
- package/dist/dsl/events/handlers.d.ts +7 -3
- package/dist/dsl/events/handlers.d.ts.map +1 -1
- package/dist/dsl/events/handlers.js +10 -4
- package/dist/dsl/events/handlers.js.map +1 -1
- package/dist/dsl/events/initial-state.d.ts.map +1 -1
- package/dist/dsl/events/initial-state.js +2 -0
- package/dist/dsl/events/initial-state.js.map +1 -1
- package/dist/dsl/monitor/exchange-sync.d.ts +1 -0
- package/dist/dsl/monitor/exchange-sync.d.ts.map +1 -1
- package/dist/dsl/monitor/exchange-sync.js +7 -14
- package/dist/dsl/monitor/exchange-sync.js.map +1 -1
- package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
- package/dist/dsl/monitor/process-one-position.js +108 -17
- package/dist/dsl/monitor/process-one-position.js.map +1 -1
- package/dist/dsl/notifications/formatter.d.ts +2 -1
- package/dist/dsl/notifications/formatter.d.ts.map +1 -1
- package/dist/dsl/notifications/formatter.js +18 -1
- package/dist/dsl/notifications/formatter.js.map +1 -1
- package/dist/health/types.d.ts +6 -1
- package/dist/health/types.d.ts.map +1 -1
- package/dist/health/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -26
- package/dist/index.js.map +1 -1
- package/dist/leverage/max-leverage-cache.d.ts +25 -0
- package/dist/leverage/max-leverage-cache.d.ts.map +1 -1
- package/dist/leverage/max-leverage-cache.js +77 -0
- package/dist/leverage/max-leverage-cache.js.map +1 -1
- package/dist/runtime/create-scanner-module.d.ts +1 -1
- package/dist/runtime/create-scanner-module.d.ts.map +1 -1
- package/dist/runtime/create-scanner-module.js +2 -1
- package/dist/runtime/create-scanner-module.js.map +1 -1
- package/dist/runtime/lifecycle-events.d.ts +1 -1
- package/dist/runtime/lifecycle-events.d.ts.map +1 -1
- package/dist/runtime/lifecycle-events.js +10 -1
- package/dist/runtime/lifecycle-events.js.map +1 -1
- package/dist/runtime/runtime-descriptor.d.ts +11 -2
- package/dist/runtime/runtime-descriptor.d.ts.map +1 -1
- package/dist/runtime/runtime-descriptor.js +11 -2
- package/dist/runtime/runtime-descriptor.js.map +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +4 -3
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/strategy-lifecycle.js +1 -1
- package/dist/runtime/strategy-lifecycle.js.map +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js +1 -1
- package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
- package/dist/runtime-api/intake/acceptance-record.d.ts +17 -3
- package/dist/runtime-api/intake/acceptance-record.d.ts.map +1 -1
- package/dist/runtime-api/intake/acceptance-record.js +57 -32
- package/dist/runtime-api/intake/acceptance-record.js.map +1 -1
- package/dist/runtime-api/intake/intake-events.d.ts +6 -5
- package/dist/runtime-api/intake/intake-events.d.ts.map +1 -1
- package/dist/runtime-api/intake/intake-events.js +9 -3
- package/dist/runtime-api/intake/intake-events.js.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.d.ts +1 -1
- package/dist/runtime-api/intake/process-signal-post.d.ts.map +1 -1
- package/dist/runtime-api/intake/process-signal-post.js +34 -31
- package/dist/runtime-api/intake/process-signal-post.js.map +1 -1
- package/dist/runtime-api/intake/scaffold-error-router.d.ts +8 -0
- package/dist/runtime-api/intake/scaffold-error-router.d.ts.map +1 -1
- package/dist/runtime-api/intake/scaffold-error-router.js +9 -0
- package/dist/runtime-api/intake/scaffold-error-router.js.map +1 -1
- package/dist/runtime-api/intake/types.d.ts +9 -0
- package/dist/runtime-api/intake/types.d.ts.map +1 -1
- package/dist/runtime-api/intake/types.js +5 -1
- package/dist/runtime-api/intake/types.js.map +1 -1
- package/dist/runtime-api/routes/signals.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.js +25 -1
- package/dist/runtime-api/routes/signals.js.map +1 -1
- package/dist/runtime-api/routes/signals.schema.d.ts +2 -0
- package/dist/runtime-api/routes/signals.schema.d.ts.map +1 -1
- package/dist/runtime-api/routes/signals.schema.js +4 -0
- package/dist/runtime-api/routes/signals.schema.js.map +1 -1
- package/dist/scanners/engine/data-providers.d.ts +6 -0
- package/dist/scanners/engine/data-providers.d.ts.map +1 -1
- package/dist/scanners/engine/data-providers.js.map +1 -1
- package/dist/scanners/engine/engine.d.ts +9 -0
- package/dist/scanners/engine/engine.d.ts.map +1 -1
- package/dist/scanners/engine/engine.js +29 -6
- package/dist/scanners/engine/engine.js.map +1 -1
- package/dist/scanners/external/scaffold/ctx.py +55 -1
- package/dist/scanners/external/scaffold/delivery.py +92 -28
- package/dist/scanners/external/scaffold/preflight.py +1 -1
- package/dist/scanners/external/scaffold/scaffold.py +75 -2
- package/dist/scanners/runtime-module.d.ts +2 -0
- package/dist/scanners/runtime-module.d.ts.map +1 -1
- package/dist/scanners/runtime-module.js +14 -0
- package/dist/scanners/runtime-module.js.map +1 -1
- package/dist/senpi/client.d.ts +11 -1
- package/dist/senpi/client.d.ts.map +1 -1
- package/dist/senpi/client.js +44 -8
- package/dist/senpi/client.js.map +1 -1
- package/dist/senpi/types.d.ts +54 -2
- package/dist/senpi/types.d.ts.map +1 -1
- package/dist/telemetry/metrics.d.ts +1 -1
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/metrics.js +1 -1
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/types/dsl/index.d.ts +4 -0
- package/dist/types/dsl/index.d.ts.map +1 -1
- package/dist/utils/event-catalog.d.ts +24 -5
- package/dist/utils/event-catalog.d.ts.map +1 -1
- package/dist/utils/event-catalog.js +4 -1
- package/dist/utils/event-catalog.js.map +1 -1
- package/dist/utils/perp-coin.d.ts.map +1 -1
- package/dist/utils/perp-coin.js +2 -1
- package/dist/utils/perp-coin.js.map +1 -1
- package/dist/utils/resolve-order-type.d.ts.map +1 -1
- package/dist/utils/resolve-order-type.js +5 -1
- package/dist/utils/resolve-order-type.js.map +1 -1
- package/dist/validate/codes.d.ts +2 -0
- package/dist/validate/codes.d.ts.map +1 -1
- package/dist/validate/codes.js +6 -0
- package/dist/validate/codes.js.map +1 -1
- package/dist/validate/index.d.ts +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +1 -1
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/recipe-checks.d.ts +7 -0
- package/dist/validate/recipe-checks.d.ts.map +1 -1
- package/dist/validate/recipe-checks.js +18 -0
- package/dist/validate/recipe-checks.js.map +1 -1
- package/dist/validate/recipe.d.ts.map +1 -1
- package/dist/validate/recipe.js +2 -1
- package/dist/validate/recipe.js.map +1 -1
- package/examples/strategies/README.md +2 -1
- package/examples/strategies/iguana/README.md +3 -3
- package/examples/strategies/raptor/README.md +3 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28,6 +28,7 @@ import { checkProofCoversRecipe, makeApplyToRuntime, makeWriteRegistry, runtimeC
|
|
|
28
28
|
import { INSTALL_DEADLINE_MS, WALLET_INSTALL_IN_FLIGHT_CODE } from "./deploy/deadlines.js";
|
|
29
29
|
import { AuditQueryError } from "./runtime/audit-query.types.js";
|
|
30
30
|
import { buildRuntimeStateDir, archiveStateDir } from "./runtime/state-layout.js";
|
|
31
|
+
import { KeyedMutex } from "./utils/keyed-mutex.js";
|
|
31
32
|
import { describeRuntimeEntry } from "./runtime/runtime-descriptor.js";
|
|
32
33
|
import { registerSenpiCli } from "./cli/senpi-commands.js";
|
|
33
34
|
import { readSenpiCliStore, resolveSenpiApiKeyFromStore, resolveSenpiBaseStateDir, } from "./cli/senpi-cli-config.js";
|
|
@@ -39,6 +40,7 @@ import { resolveAutoUpdateConfig } from "./runtime/auto-update/types.js";
|
|
|
39
40
|
import { SkillsCoordinatorUnavailableError, SkillsUpdateCoordinator, resolveSkillsManagerConfig, } from "./skills-manager/index.js";
|
|
40
41
|
import { createScannerProvidersForRun } from "./runtime/create-scanner-providers-for-run.js";
|
|
41
42
|
import { initDsl } from "./dsl/index.js";
|
|
43
|
+
import { exchangeStopClass } from "./dsl/engine/index.js";
|
|
42
44
|
import { initHealth } from "./health/index.js";
|
|
43
45
|
import { initRisk } from "./risk/index.js";
|
|
44
46
|
import { readRiskAuditEntries } from "./risk/risk-audit-log.js";
|
|
@@ -184,6 +186,12 @@ const WALLET_INSTALL_IN_FLIGHT = `[${WALLET_INSTALL_IN_FLIGHT_CODE}]`;
|
|
|
184
186
|
* anyone's money is being claimed, which is precisely why it must not answer with the wallet code.
|
|
185
187
|
*/
|
|
186
188
|
const RUNTIME_ID_TAKEN = "[E_RUNTIME_ID_TAKEN]";
|
|
189
|
+
/**
|
|
190
|
+
* One StrategyFacts send per runtime at a time, keyed on runtime id, across the whole process: a
|
|
191
|
+
* second `register()` in the same process shares it. Separate from `runtimeChangeLock`. Delete does
|
|
192
|
+
* not take it; an apply queues its send here and does not wait.
|
|
193
|
+
*/
|
|
194
|
+
const factsSendLock = new KeyedMutex();
|
|
187
195
|
/**
|
|
188
196
|
* OpenClaw plugin entry.
|
|
189
197
|
* Boots from internal registry (installed_runtimes.json) in stateDir; does not read runtime list from config.
|
|
@@ -487,7 +495,7 @@ const senpiRuntimePlugin = {
|
|
|
487
495
|
// PluginLogger surface (info/warn/error) lacks `debug`, while the
|
|
488
496
|
// Logger contract used by `runtime-api/` includes it.
|
|
489
497
|
const apiLogger = createLogger("[senpi-core][api]");
|
|
490
|
-
/** One line per instance for
|
|
498
|
+
/** One line per instance for each StrategyFacts send; see `queueFactsSend`. */
|
|
491
499
|
const factsLogger = createLogger("[senpi-core][strategy-facts]");
|
|
492
500
|
// A gateway seam failed to wire/launch a runtime's external scanner stack: the runtime is up but
|
|
493
501
|
// runs blind on internal scanners only. Two records, by design: a first-class `runtime.scanners_unwired`
|
|
@@ -759,26 +767,16 @@ const senpiRuntimePlugin = {
|
|
|
759
767
|
emitEvent(apiLogger, () => buildRuntimeBootSkippedEvent({ runtimeId: entry.id, address: entry.wallet ?? "", status }));
|
|
760
768
|
}
|
|
761
769
|
const started = [];
|
|
762
|
-
|
|
770
|
+
// Started runtimes with a facts plan, in boot order; their send runs detached after boot, below.
|
|
771
|
+
const factsRuntimeIds = [];
|
|
763
772
|
try {
|
|
764
773
|
for (const entry of entriesToBoot) {
|
|
765
|
-
const
|
|
766
|
-
|
|
767
|
-
if (hasPath && hasContent)
|
|
774
|
+
const inputs = factsPlanInputs(entry);
|
|
775
|
+
if (!inputs)
|
|
768
776
|
continue;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
const
|
|
772
|
-
const entryStateDir = buildRuntimeStateDir(baseStateDir, entry.id, entry.wallet ?? "");
|
|
773
|
-
// Local only (files, no network); the send itself runs detached after boot, below.
|
|
774
|
-
const factsPlan = await planInstanceFacts({
|
|
775
|
-
runtimeId: entry.id,
|
|
776
|
-
wallet: entry.wallet,
|
|
777
|
-
stateDir: entryStateDir,
|
|
778
|
-
pathOrContent,
|
|
779
|
-
fromPath: hasPath,
|
|
780
|
-
runtimeYamlDir: hasPath ? dirname(pathOrContent) : entry.runtimeYamlDir,
|
|
781
|
-
});
|
|
777
|
+
const { pathOrContent, fromPath: hasPath, stateDir: entryStateDir } = inputs;
|
|
778
|
+
// Local only (files, no network). Read here for the `factsSent` stamp on this start.
|
|
779
|
+
const factsPlan = await planInstanceFacts(inputs);
|
|
782
780
|
const handle = await run(pathOrContent, {
|
|
783
781
|
fromPath: hasPath,
|
|
784
782
|
stateDir: entryStateDir,
|
|
@@ -792,7 +790,7 @@ const senpiRuntimePlugin = {
|
|
|
792
790
|
runtimeHandles.set(entry.id, handle);
|
|
793
791
|
started.push(entry.id);
|
|
794
792
|
if (factsPlan)
|
|
795
|
-
|
|
793
|
+
factsRuntimeIds.push(entry.id);
|
|
796
794
|
// ── supervised scanner mount (additive; guarded) ──────────────────
|
|
797
795
|
// Boot path: used for runtimes already present in the registry at
|
|
798
796
|
// startup. A runtime installed live, after the API is listening,
|
|
@@ -885,8 +883,12 @@ const senpiRuntimePlugin = {
|
|
|
885
883
|
throw err;
|
|
886
884
|
}
|
|
887
885
|
pluginLogger.info(`[senpi-runtime] Started ${started.length} runtime${started.length === 1 ? "" : "s"}`);
|
|
888
|
-
// Detached: the facts send never holds boot or trading. One line per instance
|
|
889
|
-
|
|
886
|
+
// Detached: the facts send never holds boot or trading. One line per instance, one instance at
|
|
887
|
+
// a time, each planned again when its turn comes under the per-runtime facts lock.
|
|
888
|
+
void (async () => {
|
|
889
|
+
for (const runtimeId of factsRuntimeIds)
|
|
890
|
+
await queueFactsSend(runtimeId, bootStrategyIds);
|
|
891
|
+
})().catch((err) => {
|
|
890
892
|
factsLogger.warn("strategy facts send crashed", err);
|
|
891
893
|
});
|
|
892
894
|
// ── HTTP API ──────────────────────────────────────────────────────
|
|
@@ -1628,8 +1630,27 @@ const senpiRuntimePlugin = {
|
|
|
1628
1630
|
else
|
|
1629
1631
|
respond(false, undefined, result.error);
|
|
1630
1632
|
}, { scope: "operator.write" });
|
|
1631
|
-
// ── StrategyFacts
|
|
1632
|
-
/**
|
|
1633
|
+
// ── StrategyFacts send ─────────────────────────────────────────────────
|
|
1634
|
+
/**
|
|
1635
|
+
* The facts plan inputs for one registry entry, which are also the recipe and state dir boot
|
|
1636
|
+
* starts it with. Null when the entry holds both or neither of a recipe path and recipe content.
|
|
1637
|
+
*/
|
|
1638
|
+
function factsPlanInputs(entry) {
|
|
1639
|
+
const hasPath = typeof entry.runtimeYamlPath === "string" && entry.runtimeYamlPath.length > 0;
|
|
1640
|
+
const hasContent = typeof entry.runtimeYamlContent === "string";
|
|
1641
|
+
if (hasPath === hasContent)
|
|
1642
|
+
return null;
|
|
1643
|
+
const pathOrContent = entry.runtimeYamlPath ?? entry.runtimeYamlContent;
|
|
1644
|
+
return {
|
|
1645
|
+
runtimeId: entry.id,
|
|
1646
|
+
wallet: entry.wallet,
|
|
1647
|
+
stateDir: buildRuntimeStateDir(baseStateDir, entry.id, entry.wallet ?? ""),
|
|
1648
|
+
pathOrContent,
|
|
1649
|
+
fromPath: hasPath,
|
|
1650
|
+
runtimeYamlDir: hasPath ? dirname(pathOrContent) : entry.runtimeYamlDir,
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
/** The facts plan for one instance, or null (logged once as `failed`) when it cannot be made. */
|
|
1633
1654
|
async function planInstanceFacts(input) {
|
|
1634
1655
|
try {
|
|
1635
1656
|
const config = await loadRuntimeConfig(input.pathOrContent, { fromPath: input.fromPath });
|
|
@@ -1696,6 +1717,43 @@ const senpiRuntimePlugin = {
|
|
|
1696
1717
|
await session.client.disconnect().catch(() => { });
|
|
1697
1718
|
}
|
|
1698
1719
|
}
|
|
1720
|
+
/**
|
|
1721
|
+
* Send one runtime's facts under `factsSendLock`. The plan is made from the registry entry and
|
|
1722
|
+
* the state file as they are when the send runs, so the last send for a runtime carries its
|
|
1723
|
+
* current recipe. A runtime no longer in the registry, or whose entry cannot be planned, gets
|
|
1724
|
+
* no send. An unchanged plan makes no call.
|
|
1725
|
+
*
|
|
1726
|
+
* `strategyIds` is the boot's one batched status read (null when that read failed). Without it,
|
|
1727
|
+
* the strategy id is read for this one wallet; a failed read logs its reason and sends nothing.
|
|
1728
|
+
*/
|
|
1729
|
+
function queueFactsSend(runtimeId, strategyIds) {
|
|
1730
|
+
return factsSendLock.withKeyLock(runtimeId, async () => {
|
|
1731
|
+
const { readRegistry } = await import("./runtime/strategy-registry.js");
|
|
1732
|
+
const entry = (await readRegistry(baseStateDir)).runtimes.find((e) => e.id === runtimeId);
|
|
1733
|
+
const inputs = entry ? factsPlanInputs(entry) : null;
|
|
1734
|
+
if (!inputs)
|
|
1735
|
+
return;
|
|
1736
|
+
const plan = await planInstanceFacts(inputs);
|
|
1737
|
+
if (!plan)
|
|
1738
|
+
return;
|
|
1739
|
+
let ids = strategyIds ?? null;
|
|
1740
|
+
if (strategyIds === undefined && !plan.unchanged) {
|
|
1741
|
+
const read = await readBootWalletStatuses([plan.wallet.trim().toLowerCase()], (wallets, signal) => withSenpiClient((client) => client.listStrategies({ strategyAddresses: wallets }, { signal })));
|
|
1742
|
+
if (!read.ok) {
|
|
1743
|
+
factsLogger.warn("strategy facts failed: could not read the strategy id; retrying next boot", undefined, {
|
|
1744
|
+
runtimeId: plan.runtimeId,
|
|
1745
|
+
wallet: plan.wallet,
|
|
1746
|
+
hash: plan.hash.slice(0, 12),
|
|
1747
|
+
reason: read.reason,
|
|
1748
|
+
detail: read.message,
|
|
1749
|
+
});
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1752
|
+
ids = read.strategyIds;
|
|
1753
|
+
}
|
|
1754
|
+
await sendBootFacts([plan], ids);
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1699
1757
|
/** One connected SenpiClient per job; always disconnected, even on failure. */
|
|
1700
1758
|
async function withSenpiClient(fn) {
|
|
1701
1759
|
const client = mcpTransport ? new SenpiClient(mcpTransport) : new SenpiClient({ apiKey });
|
|
@@ -1908,6 +1966,13 @@ const senpiRuntimePlugin = {
|
|
|
1908
1966
|
...(info.slots !== undefined ? { slots: info.slots } : {}),
|
|
1909
1967
|
});
|
|
1910
1968
|
});
|
|
1969
|
+
// The apply swaps the recipe with no boot, so this send moves the backend's facts (what the
|
|
1970
|
+
// app shows) to the new recipe before the next boot. Detached: the apply has landed and must
|
|
1971
|
+
// not wait on, or fail over, the send. The send plans from the registry entry the apply has
|
|
1972
|
+
// written, and takes the wallet from that entry or its recipe.
|
|
1973
|
+
void queueFactsSend(info.runtimeId).catch((err) => {
|
|
1974
|
+
factsLogger.warn("strategy facts send crashed", err);
|
|
1975
|
+
});
|
|
1911
1976
|
},
|
|
1912
1977
|
});
|
|
1913
1978
|
registerDeployGatewayMethods(api, {
|
|
@@ -2055,6 +2120,7 @@ const senpiRuntimePlugin = {
|
|
|
2055
2120
|
const runtimeId = typeof ctx.params?.runtimeId === "string" ? ctx.params.runtimeId : undefined;
|
|
2056
2121
|
const address = typeof ctx.params?.address === "string" ? ctx.params.address : undefined;
|
|
2057
2122
|
pluginLogger.info("[senpi-runtime] senpi.getDslPositionState", { asset, runtimeId, address });
|
|
2123
|
+
// `exchangeStop` is derived from the state on each response and is not persisted.
|
|
2058
2124
|
const matches = [];
|
|
2059
2125
|
for (const [id, handle] of runtimeHandles) {
|
|
2060
2126
|
if (runtimeId && id !== runtimeId)
|
|
@@ -2065,12 +2131,18 @@ const senpiRuntimePlugin = {
|
|
|
2065
2131
|
if (address) {
|
|
2066
2132
|
const state = handle.dsl.getPositionState(address, asset);
|
|
2067
2133
|
if (state)
|
|
2068
|
-
matches.push({ runtimeId: id, address, state });
|
|
2134
|
+
matches.push({ runtimeId: id, address, state, exchangeStop: exchangeStopClass(state) });
|
|
2069
2135
|
}
|
|
2070
2136
|
else {
|
|
2071
2137
|
const found = handle.dsl.findPositionByAsset(asset);
|
|
2072
|
-
if (found)
|
|
2073
|
-
matches.push({
|
|
2138
|
+
if (found) {
|
|
2139
|
+
matches.push({
|
|
2140
|
+
runtimeId: id,
|
|
2141
|
+
address: found.address,
|
|
2142
|
+
state: found.state,
|
|
2143
|
+
exchangeStop: exchangeStopClass(found.state),
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2074
2146
|
}
|
|
2075
2147
|
}
|
|
2076
2148
|
catch (err) {
|