@senpi/runtime 3.0.180 → 3.0.182
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/llm-decision/openclaw-llm-decision.d.ts +8 -0
- package/dist/actions/llm-decision/openclaw-llm-decision.d.ts.map +1 -1
- package/dist/actions/llm-decision/openclaw-llm-decision.js +56 -1
- package/dist/actions/llm-decision/openclaw-llm-decision.js.map +1 -1
- package/dist/approvals/approval-store.d.ts +37 -7
- package/dist/approvals/approval-store.d.ts.map +1 -1
- package/dist/approvals/approval-store.js +127 -23
- package/dist/approvals/approval-store.js.map +1 -1
- package/dist/approvals/telemetry.d.ts +27 -3
- package/dist/approvals/telemetry.d.ts.map +1 -1
- package/dist/approvals/telemetry.js +8 -4
- package/dist/approvals/telemetry.js.map +1 -1
- package/dist/approvals/tool-approval-gate.d.ts +79 -0
- package/dist/approvals/tool-approval-gate.d.ts.map +1 -1
- package/dist/approvals/tool-approval-gate.js +184 -15
- package/dist/approvals/tool-approval-gate.js.map +1 -1
- package/dist/approvals/turn-context.d.ts +271 -0
- package/dist/approvals/turn-context.d.ts.map +1 -0
- package/dist/approvals/turn-context.js +551 -0
- package/dist/approvals/turn-context.js.map +1 -0
- package/dist/cli/guide-commands.d.ts.map +1 -1
- package/dist/cli/guide-commands.js +17 -3
- 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 +71 -4
- package/dist/cli/senpi-commands.js.map +1 -1
- package/dist/deploy/job.d.ts +32 -0
- package/dist/deploy/job.d.ts.map +1 -1
- package/dist/deploy/job.js +72 -7
- package/dist/deploy/job.js.map +1 -1
- package/dist/deploy/register.d.ts +11 -0
- package/dist/deploy/register.d.ts.map +1 -1
- package/dist/deploy/register.js +84 -2
- package/dist/deploy/register.js.map +1 -1
- package/dist/host/openclaw-host.d.ts +138 -0
- package/dist/host/openclaw-host.d.ts.map +1 -0
- package/dist/host/openclaw-host.js +177 -0
- package/dist/host/openclaw-host.js.map +1 -0
- package/dist/index.d.ts +46 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +220 -12
- package/dist/index.js.map +1 -1
- package/dist/runtime/auto-update/coordinator.d.ts +203 -0
- package/dist/runtime/auto-update/coordinator.d.ts.map +1 -1
- package/dist/runtime/auto-update/coordinator.js +621 -12
- package/dist/runtime/auto-update/coordinator.js.map +1 -1
- package/dist/runtime/auto-update/gateway-restart.d.ts +60 -1
- package/dist/runtime/auto-update/gateway-restart.d.ts.map +1 -1
- package/dist/runtime/auto-update/gateway-restart.js +95 -21
- package/dist/runtime/auto-update/gateway-restart.js.map +1 -1
- package/dist/runtime/auto-update/idle-gate.d.ts +139 -0
- package/dist/runtime/auto-update/idle-gate.d.ts.map +1 -0
- package/dist/runtime/auto-update/idle-gate.js +217 -0
- package/dist/runtime/auto-update/idle-gate.js.map +1 -0
- package/dist/runtime/auto-update/install-results.d.ts +130 -0
- package/dist/runtime/auto-update/install-results.d.ts.map +1 -0
- package/dist/runtime/auto-update/install-results.js +264 -0
- package/dist/runtime/auto-update/install-results.js.map +1 -0
- package/dist/runtime/auto-update/money-call-tracker.d.ts +36 -0
- package/dist/runtime/auto-update/money-call-tracker.d.ts.map +1 -0
- package/dist/runtime/auto-update/money-call-tracker.js +129 -0
- package/dist/runtime/auto-update/money-call-tracker.js.map +1 -0
- package/dist/runtime/auto-update/register-idle-gate.d.ts +70 -0
- package/dist/runtime/auto-update/register-idle-gate.d.ts.map +1 -0
- package/dist/runtime/auto-update/register-idle-gate.js +123 -0
- package/dist/runtime/auto-update/register-idle-gate.js.map +1 -0
- package/dist/runtime/auto-update/run-update-command.d.ts +13 -0
- package/dist/runtime/auto-update/run-update-command.d.ts.map +1 -1
- package/dist/runtime/auto-update/run-update-command.js +18 -0
- package/dist/runtime/auto-update/run-update-command.js.map +1 -1
- package/dist/runtime/auto-update/state-store.d.ts +14 -1
- package/dist/runtime/auto-update/state-store.d.ts.map +1 -1
- package/dist/runtime/auto-update/state-store.js +37 -3
- package/dist/runtime/auto-update/state-store.js.map +1 -1
- package/dist/runtime/auto-update/types.d.ts +51 -0
- package/dist/runtime/auto-update/types.d.ts.map +1 -1
- package/dist/runtime/auto-update/types.js.map +1 -1
- package/dist/runtime/auto-update/update-marker.d.ts +95 -0
- package/dist/runtime/auto-update/update-marker.d.ts.map +1 -0
- package/dist/runtime/auto-update/update-marker.js +185 -0
- package/dist/runtime/auto-update/update-marker.js.map +1 -0
- package/dist/runtime/auto-update/update-schedule.d.ts +57 -0
- package/dist/runtime/auto-update/update-schedule.d.ts.map +1 -0
- package/dist/runtime/auto-update/update-schedule.js +75 -0
- package/dist/runtime/auto-update/update-schedule.js.map +1 -0
- package/dist/runtime/decision-errors.d.ts +7 -0
- package/dist/runtime/decision-errors.d.ts.map +1 -1
- package/dist/runtime/decision-errors.js +15 -0
- package/dist/runtime/decision-errors.js.map +1 -1
- package/dist/senpi/client.d.ts +25 -0
- package/dist/senpi/client.d.ts.map +1 -1
- package/dist/senpi/client.js +56 -0
- package/dist/senpi/client.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +14 -0
- package/dist/telemetry/metrics.d.ts.map +1 -1
- package/dist/telemetry/metrics.js +24 -0
- package/dist/telemetry/metrics.js.map +1 -1
- package/dist/telemetry/otel-sdk.d.ts +12 -0
- package/dist/telemetry/otel-sdk.d.ts.map +1 -1
- package/dist/telemetry/otel-sdk.js +47 -1
- package/dist/telemetry/otel-sdk.js.map +1 -1
- package/dist/telemetry/spans/span-hooks.d.ts +18 -1
- package/dist/telemetry/spans/span-hooks.d.ts.map +1 -1
- package/dist/telemetry/spans/span-hooks.js +306 -96
- package/dist/telemetry/spans/span-hooks.js.map +1 -1
- package/dist/telemetry/tool-plane.d.ts +2 -0
- package/dist/telemetry/tool-plane.d.ts.map +1 -1
- package/dist/telemetry/tool-plane.js +1 -0
- package/dist/telemetry/tool-plane.js.map +1 -1
- package/dist/tool-surface/crib-cache.d.ts +21 -0
- package/dist/tool-surface/crib-cache.d.ts.map +1 -0
- package/dist/tool-surface/crib-cache.js +54 -0
- package/dist/tool-surface/crib-cache.js.map +1 -0
- package/dist/tool-surface/crib-hook.d.ts +78 -0
- package/dist/tool-surface/crib-hook.d.ts.map +1 -0
- package/dist/tool-surface/crib-hook.js +217 -0
- package/dist/tool-surface/crib-hook.js.map +1 -0
- package/dist/tool-surface/crib-sheet.d.ts +56 -0
- package/dist/tool-surface/crib-sheet.d.ts.map +1 -0
- package/dist/tool-surface/crib-sheet.js +129 -0
- package/dist/tool-surface/crib-sheet.js.map +1 -0
- package/dist/tool-surface/mcp-tool-source.d.ts +64 -0
- package/dist/tool-surface/mcp-tool-source.d.ts.map +1 -0
- package/dist/tool-surface/mcp-tool-source.js +189 -0
- package/dist/tool-surface/mcp-tool-source.js.map +1 -0
- package/dist/utils/event-catalog.d.ts +117 -5
- package/dist/utils/event-catalog.d.ts.map +1 -1
- package/dist/utils/event-catalog.js +19 -0
- package/dist/utils/event-catalog.js.map +1 -1
- package/dist/widgets/tool.d.ts +9 -0
- package/dist/widgets/tool.d.ts.map +1 -1
- package/dist/widgets/tool.js +1 -0
- package/dist/widgets/tool.js.map +1 -1
- package/openclaw.plugin.json +11 -1
- package/package.json +5 -2
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facts about the OpenClaw host the runtime plugin is loaded into.
|
|
3
|
+
*
|
|
4
|
+
* The runtime ships one build to a mixed fleet: OpenClaw 2026.5.7 (protocol 3),
|
|
5
|
+
* 2026.5.12 (protocol 4, still the legacy plugin runtime) and 2026.10.x (the
|
|
6
|
+
* "modern" line). Several surfaces differ between the lines (the config write
|
|
7
|
+
* helpers, the `subagent_spawning` hook, tool search and its dispatcher), so
|
|
8
|
+
* every version-specific change in the runtime branches on the answers here.
|
|
9
|
+
*
|
|
10
|
+
* Everything in this module is pure or reads only what the host hands the
|
|
11
|
+
* plugin at registration. It does no I/O.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* First OpenClaw release treated as "modern" (strict config schema,
|
|
15
|
+
* `runtime.config.mutateConfigFile` only, tool search, no
|
|
16
|
+
* `subagent_spawning`). It is the same threshold the senpi-agent wrapper uses
|
|
17
|
+
* (`src/lib/openclawVersion.js`, `MODERN_SINCE = [2026, 8, 1]`), so the
|
|
18
|
+
* wrapper and the runtime always agree on which line a box runs.
|
|
19
|
+
*/
|
|
20
|
+
export const MODERN_OPENCLAW_SINCE = "2026.8.1";
|
|
21
|
+
const MODERN_SINCE_PARTS = [2026, 8, 1];
|
|
22
|
+
/**
|
|
23
|
+
* Parses the leading `YYYY.M.D` of an OpenClaw version string.
|
|
24
|
+
*
|
|
25
|
+
* Accepts an optional `v` prefix and any suffix (`-beta.3`, build metadata),
|
|
26
|
+
* so `2026.10.4`, `2026.10.4-beta.1` and `v2026.10.4` all parse to
|
|
27
|
+
* `[2026, 10, 4]`.
|
|
28
|
+
*
|
|
29
|
+
* @param raw - The version string, as `api.runtime.version` reports it.
|
|
30
|
+
* @returns The three numeric parts, or `null` when the string does not start
|
|
31
|
+
* with a date-shaped version.
|
|
32
|
+
*/
|
|
33
|
+
function parseOpenClawVersion(raw) {
|
|
34
|
+
const m = raw.trim().match(/^v?(\d{4})\.(\d{1,2})\.(\d{1,3})/);
|
|
35
|
+
if (!m)
|
|
36
|
+
return null;
|
|
37
|
+
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether a host version is on the modern line (`>= 2026.8.1`).
|
|
41
|
+
*
|
|
42
|
+
* A missing or unparsable version is treated as legacy on purpose: legacy
|
|
43
|
+
* behaviour is what the runtime did before it knew about 10.x, and a wrong
|
|
44
|
+
* "modern" guess on a 5.x box would switch off paths 5.x relies on (for
|
|
45
|
+
* example the `writeConfigFile` restart).
|
|
46
|
+
*
|
|
47
|
+
* @param version - Host version, typically from {@link hostOpenClawVersion}.
|
|
48
|
+
* @returns `true` only for a parsable version at or above
|
|
49
|
+
* {@link MODERN_OPENCLAW_SINCE}.
|
|
50
|
+
*/
|
|
51
|
+
export function isModernOpenClawHost(version) {
|
|
52
|
+
if (typeof version !== "string")
|
|
53
|
+
return false;
|
|
54
|
+
const parts = parseOpenClawVersion(version);
|
|
55
|
+
if (!parts)
|
|
56
|
+
return false;
|
|
57
|
+
for (let i = 0; i < 3; i++) {
|
|
58
|
+
if (parts[i] !== MODERN_SINCE_PARTS[i])
|
|
59
|
+
return parts[i] > MODERN_SINCE_PARTS[i];
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns the host's OpenClaw version as the plugin runtime reports it
|
|
65
|
+
* (`api.runtime.version`: 5.7 `src/plugins/runtime/types-core.ts:96`, 10.10
|
|
66
|
+
* `:344`).
|
|
67
|
+
*
|
|
68
|
+
* @param api - The plugin API, or any object with the same shape.
|
|
69
|
+
* @returns The version string, or `undefined` when the host does not expose
|
|
70
|
+
* one (or exposes a non-string).
|
|
71
|
+
*/
|
|
72
|
+
export function hostOpenClawVersion(api) {
|
|
73
|
+
const version = api.runtime?.version;
|
|
74
|
+
return typeof version === "string" ? version : undefined;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Reads the host's **live** OpenClaw config.
|
|
78
|
+
*
|
|
79
|
+
* `api.config` is the snapshot taken when the plugin registered, so it goes
|
|
80
|
+
* stale after a hot reload or a `config.patch`. `api.runtime.config.current()`
|
|
81
|
+
* returns the config the gateway is running with right now (present on 5.7,
|
|
82
|
+
* 5.12 and 10.x). This prefers `current()` and falls back to the snapshot only
|
|
83
|
+
* when `current` is missing or throws (a test double, or a host mid-reload).
|
|
84
|
+
*
|
|
85
|
+
* @param api - The plugin API.
|
|
86
|
+
* @returns The live config object, or the registration snapshot, or
|
|
87
|
+
* `undefined` when neither exists. The value is the host's own object and
|
|
88
|
+
* must be treated as read-only.
|
|
89
|
+
*/
|
|
90
|
+
export function readLiveHostConfig(api) {
|
|
91
|
+
const current = api.runtime?.config?.current;
|
|
92
|
+
if (typeof current === "function") {
|
|
93
|
+
try {
|
|
94
|
+
return current.call(api.runtime?.config);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// fall through to the registration snapshot
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return api.config;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Small local record guard, matching OpenClaw's `isRecord` (a non-null,
|
|
104
|
+
* non-array object).
|
|
105
|
+
*/
|
|
106
|
+
function isRecord(value) {
|
|
107
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Resolves the tool-search mode from a whole OpenClaw config, mirroring the
|
|
111
|
+
* host's own resolver (10.10 `src/agents/tool-search-config.ts:12-42`; same
|
|
112
|
+
* semantics as 10.4, where the boolean shortcut was written out).
|
|
113
|
+
*
|
|
114
|
+
* - `tools.toolSearch` `undefined` or `true` → `"tools"`; `false` → `"off"`.
|
|
115
|
+
* - An object: `enabled` is the boolean when given, else true only when some
|
|
116
|
+
* key other than `enabled` is set (so `{}` is `"off"`); `mode` is
|
|
117
|
+
* `"directory"` only when it equals `"directory"`, else `"tools"`.
|
|
118
|
+
* - Any other value (string, array, number) → `"off"`.
|
|
119
|
+
*
|
|
120
|
+
* On a 5.x host the key does not exist and the result is meaningless; callers
|
|
121
|
+
* gate on {@link isModernOpenClawHost} first.
|
|
122
|
+
*
|
|
123
|
+
* @param config - The whole OpenClaw config (for example from
|
|
124
|
+
* {@link readLiveHostConfig}).
|
|
125
|
+
* @returns The mode the host would resolve for this config.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveToolSearchMode(config) {
|
|
128
|
+
const tools = isRecord(config) && isRecord(config.tools) ? config.tools : undefined;
|
|
129
|
+
const toolSearch = tools?.toolSearch;
|
|
130
|
+
let raw;
|
|
131
|
+
if (toolSearch === undefined || typeof toolSearch === "boolean") {
|
|
132
|
+
raw = { enabled: toolSearch ?? true };
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
raw = isRecord(toolSearch) ? toolSearch : {};
|
|
136
|
+
}
|
|
137
|
+
const configured = Object.keys(raw).some((key) => key !== "enabled");
|
|
138
|
+
const enabled = typeof raw.enabled === "boolean" ? raw.enabled : configured;
|
|
139
|
+
if (!enabled)
|
|
140
|
+
return "off";
|
|
141
|
+
return raw.mode === "directory" ? "directory" : "tools";
|
|
142
|
+
}
|
|
143
|
+
let hostFacts;
|
|
144
|
+
/**
|
|
145
|
+
* Records the host facts for this process. Called once at the top of plugin
|
|
146
|
+
* registration, before any version-gated hook is registered.
|
|
147
|
+
*
|
|
148
|
+
* A second call (the gateway re-registers the plugin on a reload) replaces the
|
|
149
|
+
* record, so the facts always describe the api of the latest registration.
|
|
150
|
+
*
|
|
151
|
+
* @param api - The plugin API handed to `register(api)`.
|
|
152
|
+
* @returns The stored record.
|
|
153
|
+
*/
|
|
154
|
+
export function initOpenClawHost(api) {
|
|
155
|
+
const version = hostOpenClawVersion(api);
|
|
156
|
+
hostFacts = {
|
|
157
|
+
version,
|
|
158
|
+
modern: isModernOpenClawHost(version),
|
|
159
|
+
currentConfig: () => readLiveHostConfig(api),
|
|
160
|
+
};
|
|
161
|
+
return hostFacts;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Returns the host record stored by {@link initOpenClawHost}.
|
|
165
|
+
*
|
|
166
|
+
* @returns The record, or `undefined` before registration (unit tests, the
|
|
167
|
+
* standalone `run()` entry, scripts). Callers treat `undefined` as "not on
|
|
168
|
+
* an OpenClaw host" and keep their legacy behaviour.
|
|
169
|
+
*/
|
|
170
|
+
export function getOpenClawHost() {
|
|
171
|
+
return hostFacts;
|
|
172
|
+
}
|
|
173
|
+
/** Clears the process-wide host record. Tests only. */
|
|
174
|
+
export function resetOpenClawHostForTests() {
|
|
175
|
+
hostFacts = undefined;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=openclaw-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-host.js","sourceRoot":"","sources":["../../src/host/openclaw-host.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,14 @@ export interface SenpiRuntimePluginConfig {
|
|
|
65
65
|
* tool is not registered at all.
|
|
66
66
|
*/
|
|
67
67
|
widgets?: Record<string, boolean>;
|
|
68
|
+
/**
|
|
69
|
+
* OpenClaw 10.x tool-surface aids (src/tool-surface/). `crib: false` turns
|
|
70
|
+
* off the `senpi__` crib sheet prepended in tool-search directory mode;
|
|
71
|
+
* absent or `true` keeps it on. Ignored on 5.x hosts.
|
|
72
|
+
*/
|
|
73
|
+
toolSurface?: {
|
|
74
|
+
crib?: boolean;
|
|
75
|
+
};
|
|
68
76
|
skillsManager?: {
|
|
69
77
|
enabled?: boolean;
|
|
70
78
|
/**
|
|
@@ -122,13 +130,47 @@ interface PluginApi {
|
|
|
122
130
|
pluginConfig?: Record<string, unknown>;
|
|
123
131
|
logger: PluginLogger;
|
|
124
132
|
config?: Record<string, unknown>;
|
|
133
|
+
/**
|
|
134
|
+
* Which registration pass this is (5.7 `src/plugins/types.ts:2242`, 10.10
|
|
135
|
+
* `src/plugins/plugin-registration.types.ts:503`). `"cli-metadata"` is the
|
|
136
|
+
* pass that only collects CLI command roots; on 10.x `runtime` throws on any
|
|
137
|
+
* read in it. Absent on hosts that predate the field.
|
|
138
|
+
*/
|
|
139
|
+
registrationMode?: string;
|
|
125
140
|
runtime: {
|
|
141
|
+
/**
|
|
142
|
+
* Host OpenClaw version (`PluginRuntimeCore.version`). Read once at
|
|
143
|
+
* registration by `initOpenClawHost` (src/host/openclaw-host.ts) to decide
|
|
144
|
+
* between the legacy (5.x) and modern (>= 2026.8.1) code paths.
|
|
145
|
+
*/
|
|
146
|
+
version?: string;
|
|
126
147
|
state: {
|
|
127
148
|
resolveStateDir(): string;
|
|
128
149
|
};
|
|
129
150
|
config?: {
|
|
130
|
-
|
|
131
|
-
|
|
151
|
+
/** Live config snapshot; present on 5.7, 5.12 and 10.x. */
|
|
152
|
+
current?(): unknown;
|
|
153
|
+
/**
|
|
154
|
+
* Focused config write with an explicit follow-up (10.10
|
|
155
|
+
* `src/plugins/runtime/types-core.ts:348-370`; `afterWrite` shape from
|
|
156
|
+
* `src/config/runtime-snapshot.ts:54-57`). The only write helper on 10.x.
|
|
157
|
+
*/
|
|
158
|
+
mutateConfigFile?(params: {
|
|
159
|
+
afterWrite: {
|
|
160
|
+
mode: "auto";
|
|
161
|
+
} | {
|
|
162
|
+
mode: "restart";
|
|
163
|
+
reason: string;
|
|
164
|
+
} | {
|
|
165
|
+
mode: "none";
|
|
166
|
+
reason: string;
|
|
167
|
+
};
|
|
168
|
+
mutate: (draft: Record<string, unknown>) => void;
|
|
169
|
+
}): Promise<unknown>;
|
|
170
|
+
/** 5.x only; removed on 10.x (first gone in 2026.7.2-beta.4). */
|
|
171
|
+
loadConfig?(): Promise<unknown>;
|
|
172
|
+
/** 5.x only; removed on 10.x (Box A on 10.10: `hasWriteConfigFile:false`). */
|
|
173
|
+
writeConfigFile?(config: unknown): Promise<void>;
|
|
132
174
|
};
|
|
133
175
|
};
|
|
134
176
|
registerService(service: {
|
|
@@ -172,6 +214,8 @@ interface PluginApi {
|
|
|
172
214
|
timeoutMs?: number;
|
|
173
215
|
}): void;
|
|
174
216
|
}
|
|
217
|
+
/** Clears {@link legacyTurnClassificationNoticeLogged}. Tests only. */
|
|
218
|
+
export declare function resetLegacyTurnClassificationNoticeForTests(): void;
|
|
175
219
|
/**
|
|
176
220
|
* OpenClaw plugin entry.
|
|
177
221
|
* Boots from internal registry (installed_runtimes.json) in stateDir; does not read runtime list from config.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
import { readFileSync } from "node:fs";
|
|
15
15
|
import { parse as parseYaml } from "yaml";
|
|
16
16
|
import { join, dirname } from "node:path";
|
|
17
|
-
import { SenpiClient } from "./senpi/client.js";
|
|
17
|
+
import { isMoneyCallTool, SenpiClient, senpiOrderCallsInFlight } from "./senpi/client.js";
|
|
18
|
+
import { MoneyCallTracker, registerMoneyCallHooks } from "./runtime/auto-update/money-call-tracker.js";
|
|
18
19
|
import { buildWalletStatusHint } from "./senpi/strategy-status.js";
|
|
19
20
|
import { bootSkippedStatusLabel, partitionByWalletStatus, readBootWalletStatuses, trackableWalletKeys, } from "./runtime/boot-skip.js";
|
|
20
21
|
import { DeployJobController } from "./deploy/job.js";
|
|
21
|
-
import { registerDeployGatewayMethods } from "./deploy/register.js";
|
|
22
|
+
import { DEPLOY_CAPABILITIES, registerDeployGatewayMethods } from "./deploy/register.js";
|
|
22
23
|
import { createQuantDesk } from "./quant/register.js";
|
|
23
24
|
import { registerUpdateGatewayMethod } from "./runtime/update-register.js";
|
|
24
25
|
import { createStrategiesPublisher } from "./runtime/strategies-telemetry.js";
|
|
@@ -48,15 +49,21 @@ import { readEvents } from "./telemetry/event-store.js";
|
|
|
48
49
|
import { VERSION } from "./version.js";
|
|
49
50
|
import { resolvePackageName } from "./runtime/auto-update/resolve-package-name.js";
|
|
50
51
|
import { runOpenClawPluginsUpdate } from "./runtime/auto-update/run-update-command.js";
|
|
52
|
+
import { UpdateIdleGate } from "./runtime/auto-update/idle-gate.js";
|
|
53
|
+
import { registerIdleGateHooks, resolveUpdateMid } from "./runtime/auto-update/register-idle-gate.js";
|
|
54
|
+
import { resolveUpdateMarkerPath } from "./runtime/auto-update/update-marker.js";
|
|
55
|
+
import { INSTALL_RESULTS_OTEL_FLUSH_MS, INSTALL_RESULTS_OTEL_READY_MS, resolveInstallResultsPath, } from "./runtime/auto-update/install-results.js";
|
|
51
56
|
import { registerSpanHooks } from "./telemetry/spans/index.js";
|
|
52
57
|
import { registerSessionContextSeedHook } from "./prompt/session-context-seed-hook.js";
|
|
53
58
|
import { registerSkillRouterHook } from "./prompt/skill-router-hook.js";
|
|
59
|
+
import { registerCribSheet } from "./tool-surface/crib-hook.js";
|
|
54
60
|
import { getDefaultPiiRedactor, initDefaultPiiRedactor } from "./telemetry/spans/redact-pii.js";
|
|
55
|
-
import { initOtelSdk, shutdownOtelSdk } from "./telemetry/otel-sdk.js";
|
|
61
|
+
import { flushOtelLogs, initOtelSdk, shutdownOtelSdk, waitForOtelInit } from "./telemetry/otel-sdk.js";
|
|
56
62
|
import { getLogLevel, getLogLevelSource, parseLogLevel, setLogLevel, } from "./utils/logger.js";
|
|
57
63
|
import { ExternalScannerIngestError, } from "./scanners/external-scanner-receiver.js";
|
|
58
64
|
import { createLogger } from "./utils/logger.js";
|
|
59
|
-
import { registerToolApprovalGate, resolveToolApprovalsMode, } from "./approvals/tool-approval-gate.js";
|
|
65
|
+
import { PendingApprovalTracker, registerToolApprovalGate, resolveToolApprovalsMode, } from "./approvals/tool-approval-gate.js";
|
|
66
|
+
import { registerTurnContextHooks, turnClassificationAvailable, TurnContextTracker, } from "./approvals/turn-context.js";
|
|
60
67
|
import { registerShowWidgetTool } from "./widgets/index.js";
|
|
61
68
|
import { registerQuantWidgetTurnCap } from "./widgets/turn-cap.js";
|
|
62
69
|
import { EVENT_NAME, SENPI_ERROR_CODE, eventAttrs, scannerUnwiredErrorCode } from "./utils/event-catalog.js";
|
|
@@ -74,6 +81,8 @@ import { ingestDispatchMutex, ingestDispatchKey } from "./runtime-api/intake/ing
|
|
|
74
81
|
import { buildScaffoldErrorRouter } from "./runtime-api/intake/scaffold-error-router.js";
|
|
75
82
|
import { loadRuntimeConfig } from "./runtime/load-runtime-config.js";
|
|
76
83
|
import { errorText } from "./deploy/error-text.js";
|
|
84
|
+
import { initOpenClawHost } from "./host/openclaw-host.js";
|
|
85
|
+
import { hostname } from "node:os";
|
|
77
86
|
import { BOOT_FACTS_CALL_TIMEOUT_MS, planBootFacts, syncBootFacts, } from "./strategy/facts-sync.js";
|
|
78
87
|
/** Initialize all core features (DSL, risk, health) on the given event bus. */
|
|
79
88
|
export function initCore(bus) {
|
|
@@ -192,6 +201,39 @@ const RUNTIME_ID_TAKEN = "[E_RUNTIME_ID_TAKEN]";
|
|
|
192
201
|
* not take it; an apply queues its send here and does not wait.
|
|
193
202
|
*/
|
|
194
203
|
const factsSendLock = new KeyedMutex();
|
|
204
|
+
/**
|
|
205
|
+
* Whether this process has already logged the 5.x "cannot classify runs" notice.
|
|
206
|
+
*
|
|
207
|
+
* Module-scoped so a gateway reload (which re-registers the plugin and restarts its service in the
|
|
208
|
+
* same process) does not repeat it. The 5.x case is a host-version limit with no config fix, so
|
|
209
|
+
* one info line per process is the whole message; the fixable 10.x case stays an ERROR at every
|
|
210
|
+
* registration and does not read this latch.
|
|
211
|
+
*/
|
|
212
|
+
let legacyTurnClassificationNoticeLogged = false;
|
|
213
|
+
/** Clears {@link legacyTurnClassificationNoticeLogged}. Tests only. */
|
|
214
|
+
export function resetLegacyTurnClassificationNoticeForTests() {
|
|
215
|
+
legacyTurnClassificationNoticeLogged = false;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* The whole of `register()` in the `"cli-metadata"` pass: the `senpi` CLI root, under the same
|
|
219
|
+
* preconditions and with the same metadata as the full pass, and nothing else.
|
|
220
|
+
*
|
|
221
|
+
* Reads no `api.runtime`: on 10.x that pass's runtime throws on any read, and the host prints the
|
|
222
|
+
* throw as `runtime failed during register` on every `openclaw senpi …` call (RT566-04). Logs
|
|
223
|
+
* nothing: a skipped precondition is reported by the full pass, which follows in the same process.
|
|
224
|
+
*/
|
|
225
|
+
function registerSenpiCliMetadata(api) {
|
|
226
|
+
const config = api.pluginConfig;
|
|
227
|
+
if (!config)
|
|
228
|
+
return;
|
|
229
|
+
const mcpTransport = api.mcpTransport;
|
|
230
|
+
const apiKey = resolveSenpiApiKeyFromStore(readSenpiCliStore(), typeof config.apiKey === "string" && config.apiKey.length > 0 ? config.apiKey : undefined);
|
|
231
|
+
if (!mcpTransport && !apiKey)
|
|
232
|
+
return;
|
|
233
|
+
api.registerCli((ctx) => {
|
|
234
|
+
registerSenpiCli(ctx.program);
|
|
235
|
+
}, { commands: ["senpi"] });
|
|
236
|
+
}
|
|
195
237
|
/**
|
|
196
238
|
* OpenClaw plugin entry.
|
|
197
239
|
* Boots from internal registry (installed_runtimes.json) in stateDir; does not read runtime list from config.
|
|
@@ -231,7 +273,16 @@ const senpiRuntimePlugin = {
|
|
|
231
273
|
warn: (...args) => api.logger.warn(...args),
|
|
232
274
|
error: (message, meta) => api.logger.error(message, meta),
|
|
233
275
|
};
|
|
276
|
+
// The cli-metadata pass only collects CLI command roots. 10.x hands it a runtime that throws on
|
|
277
|
+
// any read (RT566-04), so register the `senpi` root and nothing else — and read no api.runtime.
|
|
278
|
+
if (api.registrationMode === "cli-metadata") {
|
|
279
|
+
registerSenpiCliMetadata(api);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
234
282
|
pluginLogger.info("[senpi-runtime] register(api) invoked");
|
|
283
|
+
// Host facts first: every version-gated registration below reads them.
|
|
284
|
+
const openClawHost = initOpenClawHost(api);
|
|
285
|
+
pluginLogger.info(`[senpi-runtime] host OpenClaw ${openClawHost.version ?? "unknown"} (${openClawHost.modern ? "modern" : "legacy"})`);
|
|
235
286
|
const config = api.pluginConfig;
|
|
236
287
|
if (!config) {
|
|
237
288
|
pluginLogger.warn("[senpi-runtime] No plugin config found — skipping registration");
|
|
@@ -294,8 +345,8 @@ const senpiRuntimePlugin = {
|
|
|
294
345
|
// Agent telemetry — gateway hooks emit gen_ai spans (llm/tool/subagent) through
|
|
295
346
|
// the shared tracer; on-site MCP calls emit their own spans from SenpiClient.
|
|
296
347
|
try {
|
|
297
|
-
registerSpanHooks({ api });
|
|
298
|
-
pluginLogger.info(
|
|
348
|
+
const spanHookCount = registerSpanHooks({ api, modernHost: openClawHost.modern });
|
|
349
|
+
pluginLogger.info(`[senpi-runtime] gen_ai span hooks registered (${spanHookCount} hooks)`);
|
|
299
350
|
}
|
|
300
351
|
catch (err) {
|
|
301
352
|
pluginLogger.warn("[senpi-runtime] failed to register span hooks", {
|
|
@@ -334,14 +385,93 @@ const senpiRuntimePlugin = {
|
|
|
334
385
|
err: err instanceof Error ? err.message : String(err),
|
|
335
386
|
});
|
|
336
387
|
}
|
|
388
|
+
// senpi__ crib sheet (OpenClaw 10.x tool-search directory mode only): the
|
|
389
|
+
// directory folds every MCP tool into one sentence, so the runtime puts
|
|
390
|
+
// the names back as prependSystemContext. Registers nothing on 5.x.
|
|
391
|
+
// Its `before_prompt_build` hook needs the same host grant as the approval
|
|
392
|
+
// turn classification below; without it 10.x drops the hook, so the line
|
|
393
|
+
// says the crib is inactive and why instead of "registered".
|
|
394
|
+
try {
|
|
395
|
+
if (registerCribSheet({
|
|
396
|
+
api: api,
|
|
397
|
+
baseStateDir,
|
|
398
|
+
pluginConfig: config,
|
|
399
|
+
logger: pluginLogger,
|
|
400
|
+
})) {
|
|
401
|
+
// Registered, so the host is modern; only the hook grant is left to check.
|
|
402
|
+
const cribHook = turnClassificationAvailable({ modernHost: true, config: api.config, pluginId: api.id });
|
|
403
|
+
pluginLogger.info(cribHook.available
|
|
404
|
+
? "[senpi-runtime] senpi__ crib sheet registered (directory mode only)"
|
|
405
|
+
: `[senpi-runtime] senpi__ crib inactive: ${cribHook.reason}` +
|
|
406
|
+
(cribHook.configFix ? `; fix: ${cribHook.configFix}` : ""));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
catch (err) {
|
|
410
|
+
pluginLogger.warn("[senpi-runtime] failed to register the senpi__ crib sheet", {
|
|
411
|
+
err: err instanceof Error ? err.message : String(err),
|
|
412
|
+
});
|
|
413
|
+
}
|
|
337
414
|
// MCP tool approval gate — state-changing senpi MCP tools require an
|
|
338
415
|
// interactive user approval before executing. Prompts reach senpi-web via
|
|
339
416
|
// the bridge's operator.approvals-scoped gateway connection; allow-always
|
|
340
417
|
// decisions persist in <stateDir>/tool-approvals.json.
|
|
341
418
|
// See docs/mcp-tool-approvals-design.md.
|
|
419
|
+
// Open trade-approval prompts, read by the self-update idle gate (R2).
|
|
420
|
+
const pendingApprovalTracker = new PendingApprovalTracker();
|
|
421
|
+
// The turn kind (chat / cron / heartbeat) and session key of each gated
|
|
422
|
+
// call, for approval telemetry and the 10.x scheduled-turn block (R6, D13).
|
|
423
|
+
const turnContextTracker = new TurnContextTracker();
|
|
424
|
+
// One boot-time fact (D15): can this host classify runs at all? Only then
|
|
425
|
+
// does the gate stop prompts outside a direct chat turn. Without it every
|
|
426
|
+
// run reads unknown and keeps the pre-10.x prompt, so a box missing the
|
|
427
|
+
// setting never blocks chat trades; it is reported loudly instead.
|
|
428
|
+
let turnClassification = turnClassificationAvailable({
|
|
429
|
+
modernHost: openClawHost.modern,
|
|
430
|
+
config: api.config,
|
|
431
|
+
pluginId: api.id,
|
|
432
|
+
});
|
|
433
|
+
try {
|
|
434
|
+
registerTurnContextHooks({ api, tracker: turnContextTracker });
|
|
435
|
+
}
|
|
436
|
+
catch (err) {
|
|
437
|
+
turnClassification = { available: false, reason: "the turn-context hooks failed to register" };
|
|
438
|
+
pluginLogger.warn("[senpi-runtime] failed to register the approval turn-context hooks", {
|
|
439
|
+
err: err instanceof Error ? err.message : String(err),
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
// Only the logging and the status flag differ by host; the gate below reads the same boolean
|
|
443
|
+
// either way. On 10.x it is an ERROR at every registration (a box config to fix, or hooks that
|
|
444
|
+
// failed to register). On 5.x it is a host limit no config can fix, so it is one info line per
|
|
445
|
+
// process, logged from the service start below: that runs in the gateway only, so the
|
|
446
|
+
// `openclaw senpi …` CLI children (deploy.py, close.py, an agent exec) register without
|
|
447
|
+
// printing it.
|
|
448
|
+
const turnClassificationHostLimit = !turnClassification.available && !openClawHost.modern;
|
|
449
|
+
const turnClassificationNotice = turnClassification.available
|
|
450
|
+
? undefined
|
|
451
|
+
: `[senpi-tool-approvals] cannot tell chat turns from scheduled or background runs: ${turnClassification.reason}. ` +
|
|
452
|
+
"Trade approvals are requested in every run, scheduled ones included, " +
|
|
453
|
+
(turnClassification.configFix
|
|
454
|
+
? `until the box config is fixed (${turnClassification.configFix}).`
|
|
455
|
+
: turnClassificationHostLimit
|
|
456
|
+
? "on this OpenClaw version; a 10.x host lifts this."
|
|
457
|
+
: "until the runtime registers its turn-context hooks.");
|
|
458
|
+
const legacyTurnClassificationNotice = turnClassificationHostLimit ? turnClassificationNotice : undefined;
|
|
459
|
+
if (turnClassificationNotice !== undefined && !turnClassificationHostLimit) {
|
|
460
|
+
pluginLogger.error(turnClassificationNotice);
|
|
461
|
+
}
|
|
462
|
+
const approvalsHostStatus = turnClassification.available
|
|
463
|
+
? { turnClassification: "available" }
|
|
464
|
+
: {
|
|
465
|
+
turnClassification: "unavailable",
|
|
466
|
+
reason: turnClassification.reason,
|
|
467
|
+
...(turnClassificationHostLimit ? { hostLimit: true } : {}),
|
|
468
|
+
};
|
|
342
469
|
try {
|
|
343
470
|
registerToolApprovalGate({
|
|
344
471
|
api,
|
|
472
|
+
pendingApprovals: pendingApprovalTracker,
|
|
473
|
+
turnContext: turnContextTracker,
|
|
474
|
+
turnClassification: turnClassification.available,
|
|
345
475
|
mode: resolveToolApprovalsMode({
|
|
346
476
|
pluginConfig: config,
|
|
347
477
|
env: process.env,
|
|
@@ -533,24 +663,92 @@ const senpiRuntimePlugin = {
|
|
|
533
663
|
});
|
|
534
664
|
const autoUpdateLogger = withEventLogger(pluginLogger, "[senpi-core][auto-update]");
|
|
535
665
|
const autoUpdateConfig = resolveAutoUpdateConfig(config?.autoUpdate);
|
|
666
|
+
// OpenClaw 10.x (>= 2026.8.1): restart-to-apply (R2). The runtime cannot
|
|
667
|
+
// install itself there, so it waits for its spread slot and an idle box,
|
|
668
|
+
// writes the install marker, and restarts through mutateConfigFile; the
|
|
669
|
+
// senpi-agent wrapper installs before the next gateway spawn. On 5.7 and
|
|
670
|
+
// 5.12 the wiring is the in-process install + config-bump restart.
|
|
671
|
+
const modernHost = openClawHost.modern;
|
|
672
|
+
let idleGate;
|
|
673
|
+
if (modernHost) {
|
|
674
|
+
// Money calls on every route: the runtime's own in-process MCP calls, plus
|
|
675
|
+
// the agent's senpi__ calls (direct or through the dispatcher), seen at the
|
|
676
|
+
// tool hooks. A deploy job is read from the controller (this process) and
|
|
677
|
+
// its journals (any process).
|
|
678
|
+
const moneyCalls = new MoneyCallTracker();
|
|
679
|
+
try {
|
|
680
|
+
registerMoneyCallHooks({
|
|
681
|
+
api: api,
|
|
682
|
+
tracker: moneyCalls,
|
|
683
|
+
isMoneyTool: isMoneyCallTool,
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
catch (err) {
|
|
687
|
+
pluginLogger.warn("[senpi-runtime] failed to register the self-update money-call hooks", {
|
|
688
|
+
err: err instanceof Error ? err.message : String(err),
|
|
689
|
+
});
|
|
690
|
+
}
|
|
691
|
+
idleGate = new UpdateIdleGate({
|
|
692
|
+
pendingApprovals: () => pendingApprovalTracker.count(),
|
|
693
|
+
ordersInFlight: () => senpiOrderCallsInFlight() + moneyCalls.count(Date.now()),
|
|
694
|
+
// Read only from ticks, after register() has constructed the controller below.
|
|
695
|
+
deploysInFlight: () => deployController.inFlight(Date.now()),
|
|
696
|
+
logger: pluginLogger,
|
|
697
|
+
});
|
|
698
|
+
try {
|
|
699
|
+
registerIdleGateHooks({ api: api, gate: idleGate, logger: pluginLogger });
|
|
700
|
+
}
|
|
701
|
+
catch (err) {
|
|
702
|
+
pluginLogger.warn("[senpi-runtime] failed to register the self-update idle gate hooks", {
|
|
703
|
+
err: err instanceof Error ? err.message : String(err),
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
const openclawStateDir = typeof api.runtime?.state?.resolveStateDir === "function" ? api.runtime.state.resolveStateDir() : undefined;
|
|
536
708
|
const autoUpdateCoordinator = new AutoUpdateCoordinator({
|
|
537
709
|
enabled: true,
|
|
538
710
|
config: autoUpdateConfig,
|
|
539
711
|
packageName: PLUGIN_PACKAGE_NAME,
|
|
540
712
|
currentVersion: VERSION,
|
|
713
|
+
// The version this process loaded; "applied" is decided from it alone.
|
|
714
|
+
loadedVersion: VERSION,
|
|
541
715
|
stateDir: join(baseStateDir, "auto-update"),
|
|
542
716
|
logger: autoUpdateLogger,
|
|
543
717
|
// Use the resolved npm package name (not a hardcoded plugin id) so
|
|
544
718
|
// the update follows the same npm channel as the version check —
|
|
545
|
-
// see runtime/auto-update/run-update-command.ts.
|
|
546
|
-
|
|
719
|
+
// see runtime/auto-update/run-update-command.ts. Not on 10.x, which
|
|
720
|
+
// refuses plugins update while the gateway runs.
|
|
721
|
+
runUpdateCommand: modernHost ? undefined : runOpenClawPluginsUpdate,
|
|
547
722
|
configFromApi: api.config,
|
|
548
|
-
loadConfig: api.runtime?.config
|
|
723
|
+
loadConfig: !modernHost && api.runtime?.config
|
|
549
724
|
? () => api.runtime.config.loadConfig()
|
|
550
725
|
: undefined,
|
|
551
|
-
writeConfigFile: api.runtime?.config
|
|
726
|
+
writeConfigFile: !modernHost && api.runtime?.config
|
|
552
727
|
? (c) => api.runtime.config.writeConfigFile(c)
|
|
553
728
|
: undefined,
|
|
729
|
+
modernHost,
|
|
730
|
+
mutateConfigFile: modernHost && typeof api.runtime?.config?.mutateConfigFile === "function"
|
|
731
|
+
? (p) => api.runtime.config.mutateConfigFile(p)
|
|
732
|
+
: undefined,
|
|
733
|
+
readLiveConfig: modernHost ? openClawHost.currentConfig : undefined,
|
|
734
|
+
idleGate,
|
|
735
|
+
mid: modernHost
|
|
736
|
+
? resolveUpdateMid({
|
|
737
|
+
token: apiKey ?? process.env.SENPI_AUTH_TOKEN ?? process.env.SENPI_API_KEY,
|
|
738
|
+
env: process.env,
|
|
739
|
+
hostname,
|
|
740
|
+
})
|
|
741
|
+
: undefined,
|
|
742
|
+
updateMarkerPath: modernHost && openclawStateDir ? resolveUpdateMarkerPath(openclawStateDir) : undefined,
|
|
743
|
+
// The wrapper's install outcomes, reported once per coordinator start (gateway only),
|
|
744
|
+
// with auto-update on or off. The report runs off the start path: it waits for the OTel
|
|
745
|
+
// init register() started (else the events go to the no-op logger and the file is gone)
|
|
746
|
+
// and flushes the logs before deleting the file.
|
|
747
|
+
installResultsPath: modernHost && openclawStateDir ? resolveInstallResultsPath(openclawStateDir) : undefined,
|
|
748
|
+
installResultsTelemetry: {
|
|
749
|
+
ready: () => waitForOtelInit(INSTALL_RESULTS_OTEL_READY_MS),
|
|
750
|
+
flush: () => flushOtelLogs(INSTALL_RESULTS_OTEL_FLUSH_MS),
|
|
751
|
+
},
|
|
554
752
|
pluginId: api.id,
|
|
555
753
|
// Drive skills-manager off the auto-update tick. Both success and
|
|
556
754
|
// failure branches of auto-update's tick fire this hook so skills
|
|
@@ -630,6 +828,11 @@ const senpiRuntimePlugin = {
|
|
|
630
828
|
api.registerService({
|
|
631
829
|
id: "senpi-runtime",
|
|
632
830
|
async start() {
|
|
831
|
+
// The 5.x classification notice (see the approval gate above), once per process.
|
|
832
|
+
if (legacyTurnClassificationNotice !== undefined && !legacyTurnClassificationNoticeLogged) {
|
|
833
|
+
legacyTurnClassificationNoticeLogged = true;
|
|
834
|
+
pluginLogger.info(legacyTurnClassificationNotice);
|
|
835
|
+
}
|
|
633
836
|
// Deploy-journal janitor: stamp anything a restart left unterminated as `interrupted`.
|
|
634
837
|
// It never re-enters a deploy state machine — discovery is pull-based via
|
|
635
838
|
// `senpi deploy status`.
|
|
@@ -1995,7 +2198,10 @@ const senpiRuntimePlugin = {
|
|
|
1995
2198
|
// same clean line over a runtime that cannot tick.
|
|
1996
2199
|
runtimeIsLive: async (id) => runtimeHandles.has(id) && !unwiredRuntimes.has(id),
|
|
1997
2200
|
installPendingOnWallet: async (wallet) => installsInFlight.has(wallet.trim().toLowerCase()),
|
|
1998
|
-
logger: {
|
|
2201
|
+
logger: {
|
|
2202
|
+
info: (line) => api.logger.info(`[senpi-runtime] ${line}`),
|
|
2203
|
+
warn: (line) => api.logger.warn(`[senpi-runtime] ${line}`),
|
|
2204
|
+
},
|
|
1999
2205
|
});
|
|
2000
2206
|
/**
|
|
2001
2207
|
* Gateway shim for `senpi.ingestExternalScannerData`.
|
|
@@ -2198,6 +2404,8 @@ const senpiRuntimePlugin = {
|
|
|
2198
2404
|
respond(true, {
|
|
2199
2405
|
status: status ? { ...status, runtimeId } : null,
|
|
2200
2406
|
updater,
|
|
2407
|
+
approvals: approvalsHostStatus,
|
|
2408
|
+
deploy: { capabilities: DEPLOY_CAPABILITIES },
|
|
2201
2409
|
});
|
|
2202
2410
|
}
|
|
2203
2411
|
catch (err) {
|
|
@@ -2210,7 +2418,7 @@ const senpiRuntimePlugin = {
|
|
|
2210
2418
|
return;
|
|
2211
2419
|
}
|
|
2212
2420
|
const statuses = await collectRuntimeHealthStatuses(runtimeHandles, api.logger);
|
|
2213
|
-
respond(true, { statuses, updater });
|
|
2421
|
+
respond(true, { statuses, updater, approvals: approvalsHostStatus, deploy: { capabilities: DEPLOY_CAPABILITIES } });
|
|
2214
2422
|
}, { scope: "operator.read" });
|
|
2215
2423
|
api.registerGatewayMethod("senpi.getSystemState", async (ctx) => {
|
|
2216
2424
|
const respond = ctx.respond;
|