@senpi/runtime 3.0.162 → 3.0.168

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.
Files changed (96) hide show
  1. package/dist/deploy/orchestrator.d.ts +14 -0
  2. package/dist/deploy/orchestrator.d.ts.map +1 -1
  3. package/dist/deploy/orchestrator.js +33 -1
  4. package/dist/deploy/orchestrator.js.map +1 -1
  5. package/dist/deploy/register.d.ts +7 -0
  6. package/dist/deploy/register.d.ts.map +1 -1
  7. package/dist/deploy/register.js +1 -0
  8. package/dist/deploy/register.js.map +1 -1
  9. package/dist/dsl/events/handlers.d.ts.map +1 -1
  10. package/dist/dsl/events/handlers.js +4 -0
  11. package/dist/dsl/events/handlers.js.map +1 -1
  12. package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
  13. package/dist/dsl/monitor/process-one-position.js +6 -2
  14. package/dist/dsl/monitor/process-one-position.js.map +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +114 -14
  17. package/dist/index.js.map +1 -1
  18. package/dist/runtime/boot-skip.d.ts +3 -0
  19. package/dist/runtime/boot-skip.d.ts.map +1 -1
  20. package/dist/runtime/boot-skip.js +7 -3
  21. package/dist/runtime/boot-skip.js.map +1 -1
  22. package/dist/runtime/lifecycle-events.d.ts +6 -0
  23. package/dist/runtime/lifecycle-events.d.ts.map +1 -1
  24. package/dist/runtime/lifecycle-events.js +1 -0
  25. package/dist/runtime/lifecycle-events.js.map +1 -1
  26. package/dist/runtime/reconcile-state.d.ts.map +1 -1
  27. package/dist/runtime/reconcile-state.js +4 -0
  28. package/dist/runtime/reconcile-state.js.map +1 -1
  29. package/dist/runtime/run.d.ts +2 -0
  30. package/dist/runtime/run.d.ts.map +1 -1
  31. package/dist/runtime/run.js +1 -0
  32. package/dist/runtime/run.js.map +1 -1
  33. package/dist/runtime/runtime-schema.d.ts +100 -100
  34. package/dist/runtime/runtime.d.ts +8 -3
  35. package/dist/runtime/runtime.d.ts.map +1 -1
  36. package/dist/runtime/runtime.js +14 -6
  37. package/dist/runtime/runtime.js.map +1 -1
  38. package/dist/scanners/engine/engine.d.ts +2 -0
  39. package/dist/scanners/engine/engine.d.ts.map +1 -1
  40. package/dist/scanners/engine/engine.js +6 -0
  41. package/dist/scanners/engine/engine.js.map +1 -1
  42. package/dist/scanners/runtime-module.d.ts +2 -0
  43. package/dist/scanners/runtime-module.d.ts.map +1 -1
  44. package/dist/scanners/runtime-module.js +3 -0
  45. package/dist/scanners/runtime-module.js.map +1 -1
  46. package/dist/senpi/client.d.ts +9 -1
  47. package/dist/senpi/client.d.ts.map +1 -1
  48. package/dist/senpi/client.js +25 -0
  49. package/dist/senpi/client.js.map +1 -1
  50. package/dist/senpi/types.d.ts +19 -0
  51. package/dist/senpi/types.d.ts.map +1 -1
  52. package/dist/senpi/types.js +0 -1
  53. package/dist/senpi/types.js.map +1 -1
  54. package/dist/skills-manager/bootstrap.d.ts +5 -2
  55. package/dist/skills-manager/bootstrap.d.ts.map +1 -1
  56. package/dist/skills-manager/bootstrap.js +24 -4
  57. package/dist/skills-manager/bootstrap.js.map +1 -1
  58. package/dist/skills-manager/coordinator.d.ts +32 -3
  59. package/dist/skills-manager/coordinator.d.ts.map +1 -1
  60. package/dist/skills-manager/coordinator.js +317 -29
  61. package/dist/skills-manager/coordinator.js.map +1 -1
  62. package/dist/skills-manager/install-error.d.ts +34 -0
  63. package/dist/skills-manager/install-error.d.ts.map +1 -0
  64. package/dist/skills-manager/install-error.js +31 -0
  65. package/dist/skills-manager/install-error.js.map +1 -0
  66. package/dist/skills-manager/types.d.ts +55 -7
  67. package/dist/skills-manager/types.d.ts.map +1 -1
  68. package/dist/skills-manager/utils.d.ts +8 -0
  69. package/dist/skills-manager/utils.d.ts.map +1 -1
  70. package/dist/skills-manager/utils.js +15 -0
  71. package/dist/skills-manager/utils.js.map +1 -1
  72. package/dist/skills-manager/writer.d.ts.map +1 -1
  73. package/dist/skills-manager/writer.js +35 -14
  74. package/dist/skills-manager/writer.js.map +1 -1
  75. package/dist/strategy/__tests__/fixtures/hawk-facts.d.ts +4 -0
  76. package/dist/strategy/__tests__/fixtures/hawk-facts.d.ts.map +1 -0
  77. package/dist/strategy/__tests__/fixtures/hawk-facts.js +29 -0
  78. package/dist/strategy/__tests__/fixtures/hawk-facts.js.map +1 -0
  79. package/dist/strategy/facts-sync.d.ts +79 -0
  80. package/dist/strategy/facts-sync.d.ts.map +1 -0
  81. package/dist/strategy/facts-sync.js +184 -0
  82. package/dist/strategy/facts-sync.js.map +1 -0
  83. package/dist/strategy/facts.d.ts +79 -0
  84. package/dist/strategy/facts.d.ts.map +1 -0
  85. package/dist/strategy/facts.js +184 -0
  86. package/dist/strategy/facts.js.map +1 -0
  87. package/dist/strategy/index.d.ts +1 -0
  88. package/dist/strategy/index.d.ts.map +1 -1
  89. package/dist/strategy/index.js +1 -0
  90. package/dist/strategy/index.js.map +1 -1
  91. package/dist/utils/event-catalog.d.ts +143 -0
  92. package/dist/utils/event-catalog.d.ts.map +1 -1
  93. package/dist/utils/event-catalog.js +12 -0
  94. package/dist/utils/event-catalog.js.map +1 -1
  95. package/openclaw.plugin.json +1 -1
  96. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hawk-facts.js","sourceRoot":"","sources":["../../../../src/strategy/__tests__/fixtures/hawk-facts.ts"],"names":[],"mappings":"AAEA,sGAAsG;AACtG,MAAM,CAAC,MAAM,UAAU,GAAkB;IACvC,CAAC,EAAE,CAAC;IACJ,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC7B,QAAQ,EAAE,QAAQ;IAClB,SAAS,EAAE,YAAY;IACvB,gBAAgB,EAAE,CAAC;IACnB,YAAY,EAAE,CAAC;IACf,UAAU,EAAE,EAAE;IACd,cAAc,EAAE,IAAI;IACpB,KAAK,EAAE,CAAC;IACR,eAAe,EAAE,GAAG;IACpB,IAAI,EAAE;QACJ,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;QACpB,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,IAAI;QACnB,eAAe,EAAE,IAAI;KACtB;IACD,MAAM,EAAE;QACN,mBAAmB,EAAE,CAAC;QACtB,cAAc,EAAE,EAAE;QAClB,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;QACxC,iBAAiB,EAAE,EAAE;QACrB,kBAAkB,EAAE,KAAK;KAC1B;CACF,CAAC"}
@@ -0,0 +1,79 @@
1
+ import type { RuntimeConfig } from "../runtime/runtime-schema.js";
2
+ import { type StrategyFacts, type StrategyManifestLike } from "./facts.js";
3
+ export declare const FACTS_STATE_FILE = "strategy-facts.json";
4
+ /** Bound on one boot facts send (connect excluded; the SDK bounds that). Detached from boot either way. */
5
+ export declare const BOOT_FACTS_CALL_TIMEOUT_MS = 30000;
6
+ /** What this runtime last settled with the backend. */
7
+ export interface FactsSyncState {
8
+ v: 1;
9
+ /** Hash of the last facts the backend accepted (`sent`) or refused for good (`refused`). */
10
+ hash: string;
11
+ outcome: "sent" | "refused";
12
+ /** The last facts the backend accepted, kept for the boot merge. Null when none ever was. */
13
+ sent: StrategyFacts | null;
14
+ }
15
+ export interface FactsPlan {
16
+ runtimeId: string;
17
+ wallet: string;
18
+ stateDir: string;
19
+ /** What this boot would send: the instance's facts, merged over the last accepted ones. */
20
+ facts: StrategyFacts;
21
+ hash: string;
22
+ /** This hash was already settled (sent or refused): nothing to send. */
23
+ unchanged: boolean;
24
+ /** The backend holds exactly these facts. Stamped on `runtime.started` as `senpi.strategy.facts_sent`. */
25
+ delivered: boolean;
26
+ previous: FactsSyncState | null;
27
+ }
28
+ /** The answer of one `strategy_patch_metadata` call, as `SenpiClient.patchStrategyMetadata` reads it. */
29
+ export interface FactsPatchResult {
30
+ success: boolean;
31
+ errorCode?: string;
32
+ message?: string;
33
+ retryable?: boolean;
34
+ }
35
+ export interface FactsSyncDeps {
36
+ /** The strategy id for a wallet, from the boot status read; undefined when that read did not say. */
37
+ strategyIdFor(wallet: string): string | undefined;
38
+ patch(strategyId: string, facts: StrategyFacts): Promise<FactsPatchResult>;
39
+ }
40
+ export type FactsSyncOutcome = "sent" | "unchanged" | "refused" | "failed";
41
+ export interface FactsSyncResult {
42
+ outcome: FactsSyncOutcome;
43
+ /** Why it was refused or failed. */
44
+ detail?: string;
45
+ }
46
+ export declare function factsHash(facts: StrategyFacts): string;
47
+ /**
48
+ * The package manifest of a runtime, best-effort. Stock packages are `<pkg>/strategy.yaml` beside
49
+ * `<pkg>/<instance>/runtime.yaml`; flat ones keep both in `<pkg>/`. So look in the runtime's own
50
+ * dir, then its parent, and take the parent's only when it declares this instance. Null when none
51
+ * is found or it will not parse; never throws. The files can change after deploy, and
52
+ * `runtime create` installs have no package at all.
53
+ */
54
+ export declare function readPackageManifest(runtimeYamlDir: string | undefined): Promise<StrategyManifestLike | null>;
55
+ /**
56
+ * Boot facts over the last accepted ones. A boot that cannot read the manifest loses the catalog
57
+ * fallback for assets and direction; it must not overwrite what the deploy sent with nulls. The
58
+ * boot's values win wherever they are non-null. Assets are carried over only when the boot does
59
+ * not know the universe either: a scanner that ranks a live board has no asset list by design.
60
+ */
61
+ export declare function mergeBootFacts(boot: StrategyFacts, lastSent: StrategyFacts | null): StrategyFacts;
62
+ /** The stored state, or null when there is none or it is unreadable (read as "never sent"). */
63
+ export declare function readFactsState(stateDir: string): Promise<FactsSyncState | null>;
64
+ /** Record facts the backend already holds (the deploy sent them on create), so boot does not resend. */
65
+ export declare function recordFactsSent(stateDir: string, facts: StrategyFacts): Promise<void>;
66
+ /** What this boot would send for one instance. Local only: files, no network. */
67
+ export declare function planBootFacts(input: {
68
+ runtimeId: string;
69
+ wallet: string;
70
+ stateDir: string;
71
+ config: RuntimeConfig;
72
+ runtimeYamlDir?: string;
73
+ }): Promise<FactsPlan>;
74
+ /**
75
+ * Send one instance's planned facts, at most once. Never throws. A state write that fails after a
76
+ * send only costs a resend on the next boot.
77
+ */
78
+ export declare function syncBootFacts(plan: FactsPlan, deps: FactsSyncDeps): Promise<FactsSyncResult>;
79
+ //# sourceMappingURL=facts-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts-sync.d.ts","sourceRoot":"","sources":["../../src/strategy/facts-sync.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,EAAiB,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE1F,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AACtD,2GAA2G;AAC3G,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAGjD,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,CAAC,CAAC;IACL,4FAA4F;IAC5F,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,6FAA6F;IAC7F,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,2FAA2F;IAC3F,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,SAAS,EAAE,OAAO,CAAC;IACnB,0GAA0G;IAC1G,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;CACjC;AAED,yGAAyG;AACzG,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,qGAAqG;IACrG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAClD,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC5E;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAEtD;AAuBD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CASlH;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,GAAG,aAAa,CAOjG;AAkBD,+FAA+F;AAC/F,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAOrF;AAUD,wGAAwG;AACxG,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3F;AAED,iFAAiF;AACjF,wBAAsB,aAAa,CAAC,KAAK,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,SAAS,CAAC,CAerB;AAaD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAgClG"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Boot-time StrategyFacts sync: at every boot, each running instance sends its facts to the backend
3
+ * (MCP `strategy_patch_metadata`) once, and only when they differ from what it last settled.
4
+ *
5
+ * The package files live only on the user's box, so sending at boot as well as at deploy gives
6
+ * every live package facts after one image rollout, without waiting for a redeploy.
7
+ *
8
+ * What "last settled" means is kept in the runtime's own state dir (`strategy-facts.json`): the
9
+ * hash of the last facts the backend accepted or refused for good. A refusal is final for that hash
10
+ * (the box does not retry it every boot); anything transient (UNAVAILABLE, a thrown call, an
11
+ * unknown strategy id) writes nothing, so the next boot tries once more. Nothing here loops, and
12
+ * nothing here may block boot or trading: the caller runs the send detached, after the runtimes
13
+ * are up.
14
+ */
15
+ import { randomUUID } from "node:crypto";
16
+ import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
17
+ import { dirname, join, resolve } from "node:path";
18
+ import { parse as parseYaml } from "yaml";
19
+ import { z } from "zod";
20
+ import { errorText } from "../deploy/error-text.js";
21
+ import { computeConfigHash } from "../telemetry/identity.js";
22
+ import { strategyFacts } from "./facts.js";
23
+ export const FACTS_STATE_FILE = "strategy-facts.json";
24
+ /** Bound on one boot facts send (connect excluded; the SDK bounds that). Detached from boot either way. */
25
+ export const BOOT_FACTS_CALL_TIMEOUT_MS = 30_000;
26
+ const MANIFEST_FILE = "strategy.yaml";
27
+ export function factsHash(facts) {
28
+ return computeConfigHash(facts) ?? "";
29
+ }
30
+ function isMap(value) {
31
+ return value !== null && typeof value === "object" && !Array.isArray(value);
32
+ }
33
+ async function readYamlMap(path) {
34
+ try {
35
+ const parsed = parseYaml(await readFile(path, "utf8"));
36
+ return isMap(parsed) ? parsed : null;
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ /** Does this manifest declare an instance whose runtime.yaml lives in `runtimeYamlDir`? */
43
+ function declaresDir(manifest, packageDir, runtimeYamlDir) {
44
+ const instances = Array.isArray(manifest.instances) ? manifest.instances : [];
45
+ return instances.some((inst) => isMap(inst) && typeof inst.runtime === "string" && dirname(resolve(packageDir, inst.runtime)) === runtimeYamlDir);
46
+ }
47
+ /**
48
+ * The package manifest of a runtime, best-effort. Stock packages are `<pkg>/strategy.yaml` beside
49
+ * `<pkg>/<instance>/runtime.yaml`; flat ones keep both in `<pkg>/`. So look in the runtime's own
50
+ * dir, then its parent, and take the parent's only when it declares this instance. Null when none
51
+ * is found or it will not parse; never throws. The files can change after deploy, and
52
+ * `runtime create` installs have no package at all.
53
+ */
54
+ export async function readPackageManifest(runtimeYamlDir) {
55
+ if (!runtimeYamlDir)
56
+ return null;
57
+ const dir = resolve(runtimeYamlDir);
58
+ const own = await readYamlMap(join(dir, MANIFEST_FILE));
59
+ if (own)
60
+ return { catalog: own.catalog };
61
+ const parentDir = dirname(dir);
62
+ const parent = await readYamlMap(join(parentDir, MANIFEST_FILE));
63
+ if (parent && declaresDir(parent, parentDir, dir))
64
+ return { catalog: parent.catalog };
65
+ return null;
66
+ }
67
+ /**
68
+ * Boot facts over the last accepted ones. A boot that cannot read the manifest loses the catalog
69
+ * fallback for assets and direction; it must not overwrite what the deploy sent with nulls. The
70
+ * boot's values win wherever they are non-null. Assets are carried over only when the boot does
71
+ * not know the universe either: a scanner that ranks a live board has no asset list by design.
72
+ */
73
+ export function mergeBootFacts(boot, lastSent) {
74
+ if (!lastSent)
75
+ return boot;
76
+ return {
77
+ ...boot,
78
+ assets: boot.assets ?? (boot.universe === null ? lastSent.assets : null),
79
+ direction: boot.direction ?? lastSent.direction,
80
+ };
81
+ }
82
+ function statePath(stateDir) {
83
+ return join(stateDir, FACTS_STATE_FILE);
84
+ }
85
+ /**
86
+ * The state file's shape. `sent` is checked as far as the MCP checks facts (`v: 1`): it was written
87
+ * by this module from a `StrategyFacts`, and a hand-edited one is merged and hashed, never trusted
88
+ * further than the backend would.
89
+ */
90
+ const factsSyncStateSchema = z.object({
91
+ v: z.literal(1),
92
+ hash: z.string(),
93
+ outcome: z.enum(["sent", "refused"]),
94
+ sent: z.object({ v: z.literal(1) }).passthrough().nullable(),
95
+ });
96
+ /** The stored state, or null when there is none or it is unreadable (read as "never sent"). */
97
+ export async function readFactsState(stateDir) {
98
+ try {
99
+ const parsed = factsSyncStateSchema.safeParse(JSON.parse(await readFile(statePath(stateDir), "utf8")));
100
+ return parsed.success ? ({ ...parsed.data, sent: parsed.data.sent }) : null;
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ }
106
+ async function writeFactsState(stateDir, state) {
107
+ await mkdir(stateDir, { recursive: true });
108
+ const target = statePath(stateDir);
109
+ const tmp = `${target}.${process.pid}.${randomUUID()}.tmp`;
110
+ await writeFile(tmp, JSON.stringify(state, null, 2), "utf8");
111
+ await rename(tmp, target);
112
+ }
113
+ /** Record facts the backend already holds (the deploy sent them on create), so boot does not resend. */
114
+ export async function recordFactsSent(stateDir, facts) {
115
+ await writeFactsState(stateDir, { v: 1, hash: factsHash(facts), outcome: "sent", sent: facts });
116
+ }
117
+ /** What this boot would send for one instance. Local only: files, no network. */
118
+ export async function planBootFacts(input) {
119
+ const manifest = await readPackageManifest(input.runtimeYamlDir);
120
+ const previous = await readFactsState(input.stateDir);
121
+ const facts = mergeBootFacts(strategyFacts(input.config, manifest), previous?.sent ?? null);
122
+ const hash = factsHash(facts);
123
+ return {
124
+ runtimeId: input.runtimeId,
125
+ wallet: input.wallet,
126
+ stateDir: input.stateDir,
127
+ facts,
128
+ hash,
129
+ unchanged: previous?.hash === hash,
130
+ delivered: previous?.outcome === "sent" && previous.hash === hash,
131
+ previous,
132
+ };
133
+ }
134
+ /**
135
+ * Codes that say nothing about the facts, so the next boot tries again whatever `retryable` says:
136
+ * UNAVAILABLE (transport) and SERR032 (the box's token expired; 124 marks it `retryable: false`).
137
+ */
138
+ const RETRY_NEXT_BOOT_CODES = new Set(["UNAVAILABLE", "SERR032"]);
139
+ /** A refusal the backend will repeat for these facts: a code that is neither retryable nor the box's own state. */
140
+ function isFinalRefusal(result) {
141
+ return result.errorCode !== undefined && !RETRY_NEXT_BOOT_CODES.has(result.errorCode) && result.retryable !== true;
142
+ }
143
+ /**
144
+ * Send one instance's planned facts, at most once. Never throws. A state write that fails after a
145
+ * send only costs a resend on the next boot.
146
+ */
147
+ export async function syncBootFacts(plan, deps) {
148
+ if (plan.unchanged)
149
+ return { outcome: "unchanged" };
150
+ const strategyId = deps.strategyIdFor(plan.wallet);
151
+ if (!strategyId)
152
+ return { outcome: "failed", detail: "no strategy id known for this wallet" };
153
+ let result;
154
+ try {
155
+ result = await deps.patch(strategyId, plan.facts);
156
+ }
157
+ catch (err) {
158
+ return { outcome: "failed", detail: errorText(err) };
159
+ }
160
+ const detail = result.errorCode
161
+ ? `${result.errorCode}: ${result.message ?? "no message"}`
162
+ : "no error code in the answer";
163
+ let settled;
164
+ let state;
165
+ if (result.success) {
166
+ settled = { outcome: "sent" };
167
+ state = { v: 1, hash: plan.hash, outcome: "sent", sent: plan.facts };
168
+ }
169
+ else if (isFinalRefusal(result)) {
170
+ settled = { outcome: "refused", detail };
171
+ state = { v: 1, hash: plan.hash, outcome: "refused", sent: plan.previous?.sent ?? null };
172
+ }
173
+ else {
174
+ return { outcome: "failed", detail };
175
+ }
176
+ try {
177
+ await writeFactsState(plan.stateDir, state);
178
+ }
179
+ catch (err) {
180
+ return { ...settled, detail: `${settled.detail ? `${settled.detail}; ` : ""}state not saved: ${errorText(err)}` };
181
+ }
182
+ return settled;
183
+ }
184
+ //# sourceMappingURL=facts-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts-sync.js","sourceRoot":"","sources":["../../src/strategy/facts-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * StrategyFacts v1: what one runtime instance does, read from its own files. One value per
3
+ * instance, because each instance owns its own wallet.
4
+ *
5
+ * Facts only. No wording, no model, no scanner-input names or "what it looks for" hints: the same
6
+ * input means opposite things across packages (`minTraderCount` is "the crowd agrees" in Beaver and
7
+ * "the crowd is crowded, fade it" in Dog), so the only inputs read are ticker lists, a universe
8
+ * shape, an explicit long/short leg, and leverage/margin numbers. Rendering belongs to the backend.
9
+ *
10
+ * Pure: no I/O, never throws. Every field is null when the files do not say, never a guess. The
11
+ * exit block is read THROUGH THE ENGINE'S OWN READER (`mapRuntimeExitToDslConfig` + `parsePreset`,
12
+ * as `loadRuntimeConfig` and `runtime-descriptor.ts` do), so a fact here is what the DSL enforces.
13
+ *
14
+ * Port of the runtime-file fields of the pages-v2 prototype `strategy-describer/describe.py`.
15
+ */
16
+ import type { RuntimeConfig } from "../runtime/runtime-schema.js";
17
+ export type StrategyDirection = "long" | "short" | "long_short";
18
+ export interface StrategyExitFacts {
19
+ /** Max loss as % of margin. Enforced as the absolute floor even with phase 1 off (`floors.ts` phase1BaseFloor). */
20
+ loss_cap_pct: number;
21
+ time_cap_min: number | null;
22
+ /** [trigger_pct, lock_hw_pct] of the first profit-lock tier; null when phase 2 is off. */
23
+ first_lock: [number, number] | null;
24
+ /** Number of profit-lock tiers the engine acts on; 0 when phase 2 is off. */
25
+ lock_steps: number;
26
+ weak_peak_cut: {
27
+ after_min: number;
28
+ under_pct: number;
29
+ } | null;
30
+ dead_weight_cut: {
31
+ after_min: number;
32
+ } | null;
33
+ }
34
+ export interface StrategyLimitFacts {
35
+ max_entries_per_day: number | null;
36
+ daily_loss_pct: number | null;
37
+ /** Gate 3 runs only when both are set (`risk/guardrail.types.ts`), so it is both or null. */
38
+ loss_streak: {
39
+ count: number;
40
+ pause_s: number;
41
+ } | null;
42
+ drawdown_halt_pct: number | null;
43
+ same_market_wait_s: number | null;
44
+ }
45
+ /** Wire shape, snake_case, versioned. */
46
+ export interface StrategyFacts {
47
+ v: 1;
48
+ /** Static ticker list from the entry scanner's inputs, else the manifest's `catalog.assets`. */
49
+ assets: string[] | null;
50
+ /** "static" when the scanner names its tickers, "dynamic" when it picks from a live board. */
51
+ universe: "static" | "dynamic" | null;
52
+ /** Scanner `direction`/`leg` input when it is long or short, else the manifest's `catalog.direction`. */
53
+ direction: StrategyDirection | null;
54
+ leverage_default: number | null;
55
+ leverage_max: number | null;
56
+ margin_pct: number | null;
57
+ margin_pct_max: number | null;
58
+ slots: number | null;
59
+ scan_interval_s: number | null;
60
+ exit: StrategyExitFacts | null;
61
+ limits: StrategyLimitFacts | null;
62
+ }
63
+ /** The part of a package manifest (`strategy.yaml`) read here. `DeployPackage` satisfies it. */
64
+ export interface StrategyManifestLike {
65
+ catalog?: unknown;
66
+ }
67
+ /** The catalog copy the backend reads from `strategyMetadata.catalog` (ticket 116). */
68
+ export interface StrategyCatalogCopy {
69
+ name: string;
70
+ tagline: string;
71
+ belief_plain: string;
72
+ }
73
+ /**
74
+ * `{name, tagline, belief_plain}` out of a manifest's `catalog:` block, or null unless all three are
75
+ * non-empty strings: the MCP stores the catalog only whole, so a partial one would be dropped there.
76
+ */
77
+ export declare function catalogCopy(catalog: unknown): StrategyCatalogCopy | null;
78
+ export declare function strategyFacts(config: RuntimeConfig, manifest?: StrategyManifestLike | null): StrategyFacts;
79
+ //# sourceMappingURL=facts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.d.ts","sourceRoot":"","sources":["../../src/strategy/facts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,aAAa,EAA+B,MAAM,8BAA8B,CAAC;AAM/F,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,mHAAmH;IACnH,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,0FAA0F;IAC1F,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACpC,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,eAAe,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6FAA6F;IAC7F,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,CAAC,CAAC;IACL,gGAAgG;IAChG,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,8FAA8F;IAC9F,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,CAAC;IACtC,yGAAyG;IACzG,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACnC;AAED,gGAAgG;AAChG,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,uFAAuF;AACvF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAKxE;AA6JD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,oBAAoB,GAAG,IAAI,GAAG,aAAa,CAgB1G"}
@@ -0,0 +1,184 @@
1
+ import { mapRuntimeExitToDslConfig } from "../runtime/map-exit-config.js";
2
+ import { parsePreset } from "../dsl/config/parse-preset.js";
3
+ import { DEFAULT_INTERVAL_MS, EXIT_DSL_PRESET_PATH } from "../constants/dsl/index.js";
4
+ /**
5
+ * `{name, tagline, belief_plain}` out of a manifest's `catalog:` block, or null unless all three are
6
+ * non-empty strings: the MCP stores the catalog only whole, so a partial one would be dropped there.
7
+ */
8
+ export function catalogCopy(catalog) {
9
+ if (!isMap(catalog))
10
+ return null;
11
+ const { name, tagline, belief_plain } = catalog;
12
+ const filled = (value) => typeof value === "string" && value.trim().length > 0;
13
+ return filled(name) && filled(tagline) && filled(belief_plain) ? { name, tagline, belief_plain } : null;
14
+ }
15
+ /** Input keys whose value is the scanner's own ticker list (or a single ticker), in priority order. */
16
+ const ASSET_KEYS = ["universe", "allowedAssets", "assets", "whitelist", "trackedAssets", "asset", "coin", "hedgeUniverse"];
17
+ /** Keys that hold a ticker list only as a list (never a single string). */
18
+ const LIST_ONLY_ASSET_KEYS = ["equities", "trackedCrypto", "riskAssets"];
19
+ /** Inputs that size a live, ranked universe instead of naming one. */
20
+ const DYNAMIC_UNIVERSE_KEYS = [
21
+ "universeVolFloorUsd", "universeMaxNames", "universeTopN", "topN", "maxUniverse", "universeSize",
22
+ "maxUniverseNames", "maxMainNames", "volFloorUsd", "leaderboardLimit", "shortlistByVol", "minOiUsd",
23
+ "xyzVolFloorUsd", "trackedXyz",
24
+ ];
25
+ const TICKER = /^(xyz:)?[A-Za-z0-9]{2,10}$/;
26
+ function num(value) {
27
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
28
+ }
29
+ function isMap(value) {
30
+ return value !== null && typeof value === "object" && !Array.isArray(value);
31
+ }
32
+ function tickers(value) {
33
+ if (!Array.isArray(value) || value.length === 0)
34
+ return null;
35
+ return value.every((x) => typeof x === "string" && TICKER.test(x)) ? value : null;
36
+ }
37
+ /** Every finite number inside a (possibly nested) tier map such as `leverageTiers`. */
38
+ function tierNumbers(value) {
39
+ if (num(value) !== null)
40
+ return [value];
41
+ if (Array.isArray(value))
42
+ return value.flatMap(tierNumbers);
43
+ if (isMap(value))
44
+ return Object.values(value).flatMap(tierNumbers);
45
+ return [];
46
+ }
47
+ function firstNum(inputs, keys) {
48
+ for (const k of keys) {
49
+ const n = num(inputs[k]);
50
+ if (n !== null)
51
+ return n;
52
+ }
53
+ return null;
54
+ }
55
+ function normalizeDirection(value) {
56
+ if (typeof value !== "string")
57
+ return null;
58
+ switch (value.trim().toLowerCase()) {
59
+ case "long":
60
+ case "long_only":
61
+ return "long";
62
+ case "short":
63
+ case "short_only":
64
+ return "short";
65
+ case "long_short":
66
+ return "long_short";
67
+ default:
68
+ return null;
69
+ }
70
+ }
71
+ function universeFacts(inputs, catalog) {
72
+ for (const k of ASSET_KEYS) {
73
+ const v = inputs[k];
74
+ const list = tickers(typeof v === "string" ? [v] : v);
75
+ if (list)
76
+ return { assets: list, universe: "static" };
77
+ }
78
+ for (const k of LIST_ONLY_ASSET_KEYS) {
79
+ const list = tickers(inputs[k]);
80
+ if (list)
81
+ return { assets: list, universe: "static" };
82
+ }
83
+ const dex = typeof inputs.dex === "string" ? inputs.dex.toLowerCase() : "";
84
+ if (dex === "xyz" || DYNAMIC_UNIVERSE_KEYS.some((k) => k in inputs))
85
+ return { assets: null, universe: "dynamic" };
86
+ // Declared, not observed: the manifest says which tickers, but not whether the scanner is held to them.
87
+ return { assets: tickers(catalog.assets), universe: null };
88
+ }
89
+ function directionFact(inputs, catalog) {
90
+ return (normalizeDirection(inputs.direction) ?? normalizeDirection(inputs.leg) ?? normalizeDirection(catalog.direction));
91
+ }
92
+ function leverageMax(inputs) {
93
+ const explicit = firstNum(inputs, ["maxLeverage", "leverageMax", "max_leverage"]);
94
+ if (explicit !== null)
95
+ return explicit;
96
+ const tiers = tierNumbers(inputs.leverageTiers);
97
+ if (tiers.length > 0)
98
+ return Math.max(...tiers);
99
+ return num(inputs.leverage);
100
+ }
101
+ function marginFacts(strategy, inputs) {
102
+ let marginPct = num(strategy.margin_pct);
103
+ let marginPctMax = null;
104
+ if (marginPct === null) {
105
+ marginPct = firstNum(inputs, ["marginPct", "marginPctBase", "margin_pct", "marginPctMax"]);
106
+ const tiers = tierNumbers(inputs.marginPctTiers);
107
+ if (marginPct === null && tiers.length > 0) {
108
+ marginPct = Math.min(...tiers);
109
+ marginPctMax = Math.max(...tiers);
110
+ }
111
+ }
112
+ if (marginPctMax === null) {
113
+ const cap = firstNum(inputs, ["maxMarginPct", "marginPctMax", "marginPctCap"]);
114
+ if (cap !== null && cap !== marginPct)
115
+ marginPctMax = cap;
116
+ }
117
+ return { margin_pct: marginPct, margin_pct_max: marginPctMax };
118
+ }
119
+ /** The preset the DSL monitor would run, or null when there is none or the engine refuses it. */
120
+ function enginePreset(exit) {
121
+ try {
122
+ const block = mapRuntimeExitToDslConfig(exit);
123
+ if (!isMap(block.dsl_preset))
124
+ return null;
125
+ // Same clamp floor `parseDslPluginConfig` passes: the exit poll interval, in minutes.
126
+ return parsePreset(EXIT_DSL_PRESET_PATH, block.dsl_preset, (block.interval_seconds ?? DEFAULT_INTERVAL_MS / 1000) / 60);
127
+ }
128
+ catch {
129
+ return null;
130
+ }
131
+ }
132
+ function exitFacts(exit) {
133
+ const preset = enginePreset(exit);
134
+ if (preset === null)
135
+ return null;
136
+ const tiers = preset.phase2Enabled ? preset.tiers : [];
137
+ const first = tiers[0];
138
+ return {
139
+ loss_cap_pct: preset.maxLossPct,
140
+ time_cap_min: preset.hardTimeout?.intervalInMinutes ?? null,
141
+ first_lock: first ? [first.triggerPct, first.lockHwPct] : null,
142
+ lock_steps: tiers.length,
143
+ weak_peak_cut: preset.weakPeakCut
144
+ ? { after_min: preset.weakPeakCut.intervalInMinutes, under_pct: preset.weakPeakCut.minValue }
145
+ : null,
146
+ dead_weight_cut: preset.deadWeightCut ? { after_min: preset.deadWeightCut.intervalInMinutes } : null,
147
+ };
148
+ }
149
+ function limitFacts(config) {
150
+ const gr = config.risk?.guard_rails;
151
+ if (!gr)
152
+ return null;
153
+ const count = num(gr.max_consecutive_losses);
154
+ const pause = num(gr.cooldown_seconds);
155
+ return {
156
+ max_entries_per_day: num(gr.max_entries_per_day),
157
+ daily_loss_pct: num(gr.daily_loss_limit_pct),
158
+ loss_streak: count !== null && pause !== null ? { count, pause_s: pause } : null,
159
+ drawdown_halt_pct: num(gr.drawdown_halt_pct),
160
+ same_market_wait_s: num(gr.per_asset_cooldown_seconds),
161
+ };
162
+ }
163
+ /** The scanner that produces entries: the first `external_scanner`. */
164
+ function entryScanner(config) {
165
+ return config.scanners?.find((s) => s.type === "external_scanner");
166
+ }
167
+ export function strategyFacts(config, manifest) {
168
+ const scanner = entryScanner(config);
169
+ const inputs = isMap(scanner?.inputs) ? scanner.inputs : {};
170
+ const catalog = isMap(manifest?.catalog) ? manifest.catalog : {};
171
+ return {
172
+ v: 1,
173
+ ...universeFacts(inputs, catalog),
174
+ direction: directionFact(inputs, catalog),
175
+ leverage_default: num(config.strategy.default_leverage),
176
+ leverage_max: leverageMax(inputs),
177
+ ...marginFacts(config.strategy, inputs),
178
+ slots: num(config.strategy.slots),
179
+ scan_interval_s: num(scanner?.interval_seconds),
180
+ exit: exitFacts(config.exit),
181
+ limits: limitFacts(config),
182
+ };
183
+ }
184
+ //# sourceMappingURL=facts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facts.js","sourceRoot":"","sources":["../../src/strategy/facts.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  export { StrategyStateImpl } from './strategy-state.js';
2
+ export { strategyFacts, type StrategyFacts, type StrategyExitFacts, type StrategyLimitFacts, type StrategyDirection, type StrategyManifestLike, } from './facts.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,YAAY,CAAC"}
@@ -1,2 +1,3 @@
1
1
  export { StrategyStateImpl } from './strategy-state.js';
2
+ export { strategyFacts, } from './facts.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/strategy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,aAAa,GAMd,MAAM,YAAY,CAAC"}