@openagentsinc/pylon 0.1.14 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -9
- package/package.json +1 -1
- package/src/index.js +110 -0
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npx @openagentsinc/pylon
|
|
|
13
13
|
bunx @openagentsinc/pylon
|
|
14
14
|
npm install -g @openagentsinc/pylon && pylon
|
|
15
15
|
bun install -g @openagentsinc/pylon && pylon
|
|
16
|
-
npx @openagentsinc/pylon --version 0.1.
|
|
16
|
+
npx @openagentsinc/pylon --version 0.1.15
|
|
17
17
|
npx @openagentsinc/pylon --no-launch
|
|
18
18
|
npx @openagentsinc/pylon --no-updates
|
|
19
19
|
npx @openagentsinc/pylon --download-curated-cache --model gemma-4-e2b --run-diagnostics
|
|
@@ -34,8 +34,9 @@ The launcher:
|
|
|
34
34
|
- prompts before installing the Rust toolchain via `rustup` if a source build
|
|
35
35
|
is needed and `cargo` / `rustc` are missing
|
|
36
36
|
- emits best-effort anonymous installer telemetry to `openagents.com` so the
|
|
37
|
-
public stats page can show install starts, completions, source-build
|
|
38
|
-
Rust prompts, and smoke-test
|
|
37
|
+
public stats page can show install starts, completions, source-build
|
|
38
|
+
fallbacks, update checks, restart behavior, Rust prompts, and smoke-test
|
|
39
|
+
outcomes
|
|
39
40
|
- downloads the archive and published SHA-256 checksum
|
|
40
41
|
- verifies the checksum before extracting
|
|
41
42
|
- caches the unpacked binaries under `~/.openagents/pylon/bootstrap/`
|
|
@@ -64,12 +65,12 @@ The launcher:
|
|
|
64
65
|
without replacing the global npm/bun command
|
|
65
66
|
- use `--no-updates` to keep the current installed release running without
|
|
66
67
|
background GitHub release checks; `--version` remains a pinned release run
|
|
67
|
-
- for hosted homework/training work, use launcher `0.1.
|
|
68
|
-
cached standalone binary auto-updates while the dashboard is open. The
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
- for hosted homework/training work, use launcher `0.1.15` or newer so the
|
|
69
|
+
cached standalone binary auto-updates while the dashboard is open. The
|
|
70
|
+
`pylon-v0.1.15` standalone binary keeps the long hosted homework ID hashing
|
|
71
|
+
from `0.1.14` and also refuses to seal terminal training windows until the
|
|
72
|
+
worker contribution artifact bundle has uploaded and verified for validator
|
|
73
|
+
replay.
|
|
73
74
|
- does not try to install or register a local runtime automatically; the
|
|
74
75
|
bootstrap stays honest about the separate local Gemma runtime
|
|
75
76
|
prerequisite instead of mutating the host behind the user's back
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -2023,10 +2023,41 @@ export async function launchInstalledPylonWithUpdates(
|
|
|
2023
2023
|
spawnProcessImpl = spawn,
|
|
2024
2024
|
updateCheckIntervalMs = DEFAULT_UPDATE_CHECK_INTERVAL_MS,
|
|
2025
2025
|
onStatus = null,
|
|
2026
|
+
telemetryClient = null,
|
|
2026
2027
|
...dependencies
|
|
2027
2028
|
} = {},
|
|
2028
2029
|
) {
|
|
2030
|
+
const currentReleaseTag =
|
|
2031
|
+
options.tagName ?? `pylon-v${normalizeVersion(options.version)}`;
|
|
2032
|
+
const updateTelemetryBase = {
|
|
2033
|
+
current_release_tag: currentReleaseTag,
|
|
2034
|
+
current_version: normalizeVersion(options.version),
|
|
2035
|
+
os: options.target?.os ?? null,
|
|
2036
|
+
arch: options.target?.arch ?? null,
|
|
2037
|
+
platform_key:
|
|
2038
|
+
options.target?.os && options.target?.arch
|
|
2039
|
+
? `${options.target.os}-${options.target.arch}`
|
|
2040
|
+
: null,
|
|
2041
|
+
install_source: installSourceForTelemetry(
|
|
2042
|
+
options.installMethod,
|
|
2043
|
+
Boolean(options.cached),
|
|
2044
|
+
),
|
|
2045
|
+
update_check_interval_ms: updateCheckIntervalMs,
|
|
2046
|
+
};
|
|
2047
|
+
|
|
2029
2048
|
if (options.noUpdates || options.pinnedVersion) {
|
|
2049
|
+
emitTelemetry(
|
|
2050
|
+
telemetryClient,
|
|
2051
|
+
options.noUpdates
|
|
2052
|
+
? "installer_update_disabled"
|
|
2053
|
+
: "installer_update_pinned_run",
|
|
2054
|
+
{
|
|
2055
|
+
...updateTelemetryBase,
|
|
2056
|
+
update_mode: options.noUpdates ? "no_updates" : "pinned_version",
|
|
2057
|
+
update_reason: options.noUpdates ? "--no-updates" : "--version",
|
|
2058
|
+
},
|
|
2059
|
+
);
|
|
2060
|
+
await telemetryClient?.flush?.();
|
|
2030
2061
|
return launchInstalledPylon(options, { ...dependencies, onStatus });
|
|
2031
2062
|
}
|
|
2032
2063
|
|
|
@@ -2035,6 +2066,7 @@ export async function launchInstalledPylonWithUpdates(
|
|
|
2035
2066
|
version: normalizeVersion(options.version),
|
|
2036
2067
|
};
|
|
2037
2068
|
let lastUpdateError = null;
|
|
2069
|
+
let pendingRestartTelemetry = null;
|
|
2038
2070
|
|
|
2039
2071
|
while (true) {
|
|
2040
2072
|
const pylonTuiPath = path.resolve(current.pylonTuiPath);
|
|
@@ -2043,6 +2075,14 @@ export async function launchInstalledPylonWithUpdates(
|
|
|
2043
2075
|
"Starting Pylon terminal UI",
|
|
2044
2076
|
`${path.basename(pylonTuiPath)} manages the earning worker`,
|
|
2045
2077
|
);
|
|
2078
|
+
if (pendingRestartTelemetry) {
|
|
2079
|
+
emitTelemetry(telemetryClient, "installer_update_restart_succeeded", {
|
|
2080
|
+
...pendingRestartTelemetry,
|
|
2081
|
+
restarted_release_tag: current.tagName,
|
|
2082
|
+
restarted_version: current.version,
|
|
2083
|
+
});
|
|
2084
|
+
pendingRestartTelemetry = null;
|
|
2085
|
+
}
|
|
2046
2086
|
const child = spawnPylonTui(pylonTuiPath, current, spawnProcessImpl);
|
|
2047
2087
|
const childExit = waitForChildExit(child);
|
|
2048
2088
|
let restartForUpdate = false;
|
|
@@ -2065,6 +2105,12 @@ export async function launchInstalledPylonWithUpdates(
|
|
|
2065
2105
|
);
|
|
2066
2106
|
}
|
|
2067
2107
|
|
|
2108
|
+
emitTelemetry(telemetryClient, "installer_update_check_started", {
|
|
2109
|
+
...updateTelemetryBase,
|
|
2110
|
+
observed_release_tag: current.tagName,
|
|
2111
|
+
observed_version: current.version,
|
|
2112
|
+
});
|
|
2113
|
+
|
|
2068
2114
|
try {
|
|
2069
2115
|
const install = await ensureReleaseInstallImpl(
|
|
2070
2116
|
{
|
|
@@ -2080,12 +2126,70 @@ export async function launchInstalledPylonWithUpdates(
|
|
|
2080
2126
|
if (!isNewerPylonVersion(install.version, current.version)) {
|
|
2081
2127
|
continue;
|
|
2082
2128
|
}
|
|
2129
|
+
emitTelemetry(telemetryClient, "installer_update_available", {
|
|
2130
|
+
...updateTelemetryBase,
|
|
2131
|
+
observed_release_tag: current.tagName,
|
|
2132
|
+
observed_version: current.version,
|
|
2133
|
+
available_release_tag: install.tagName,
|
|
2134
|
+
available_version: install.version,
|
|
2135
|
+
available_install_source: installSourceForTelemetry(
|
|
2136
|
+
install.installMethod,
|
|
2137
|
+
Boolean(install.cached),
|
|
2138
|
+
),
|
|
2139
|
+
});
|
|
2140
|
+
if (
|
|
2141
|
+
install.installMethod === RELEASE_ASSET_INSTALL_METHOD &&
|
|
2142
|
+
!install.cached
|
|
2143
|
+
) {
|
|
2144
|
+
emitTelemetry(telemetryClient, "installer_update_downloaded", {
|
|
2145
|
+
...updateTelemetryBase,
|
|
2146
|
+
observed_release_tag: current.tagName,
|
|
2147
|
+
observed_version: current.version,
|
|
2148
|
+
available_release_tag: install.tagName,
|
|
2149
|
+
available_version: install.version,
|
|
2150
|
+
});
|
|
2151
|
+
emitTelemetry(telemetryClient, "installer_update_verified", {
|
|
2152
|
+
...updateTelemetryBase,
|
|
2153
|
+
observed_release_tag: current.tagName,
|
|
2154
|
+
observed_version: current.version,
|
|
2155
|
+
available_release_tag: install.tagName,
|
|
2156
|
+
available_version: install.version,
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
emitTelemetry(telemetryClient, "installer_update_applied", {
|
|
2160
|
+
...updateTelemetryBase,
|
|
2161
|
+
previous_release_tag: current.tagName,
|
|
2162
|
+
previous_version: current.version,
|
|
2163
|
+
applied_release_tag: install.tagName,
|
|
2164
|
+
applied_version: install.version,
|
|
2165
|
+
applied_install_source: installSourceForTelemetry(
|
|
2166
|
+
install.installMethod,
|
|
2167
|
+
Boolean(install.cached),
|
|
2168
|
+
),
|
|
2169
|
+
});
|
|
2083
2170
|
emitStatus(
|
|
2084
2171
|
onStatus,
|
|
2085
2172
|
"Installed newer Pylon release",
|
|
2086
2173
|
`${install.tagName}; restarting dashboard`,
|
|
2087
2174
|
);
|
|
2175
|
+
emitTelemetry(telemetryClient, "installer_update_restart_attempted", {
|
|
2176
|
+
...updateTelemetryBase,
|
|
2177
|
+
previous_release_tag: current.tagName,
|
|
2178
|
+
previous_version: current.version,
|
|
2179
|
+
restart_target_release_tag: install.tagName,
|
|
2180
|
+
restart_target_version: install.version,
|
|
2181
|
+
});
|
|
2088
2182
|
await stopChild(child);
|
|
2183
|
+
pendingRestartTelemetry = {
|
|
2184
|
+
previous_release_tag: current.tagName,
|
|
2185
|
+
previous_version: current.version,
|
|
2186
|
+
applied_release_tag: install.tagName,
|
|
2187
|
+
applied_version: install.version,
|
|
2188
|
+
applied_install_source: installSourceForTelemetry(
|
|
2189
|
+
install.installMethod,
|
|
2190
|
+
Boolean(install.cached),
|
|
2191
|
+
),
|
|
2192
|
+
};
|
|
2089
2193
|
current = {
|
|
2090
2194
|
...options,
|
|
2091
2195
|
...install,
|
|
@@ -2094,6 +2198,12 @@ export async function launchInstalledPylonWithUpdates(
|
|
|
2094
2198
|
restartForUpdate = true;
|
|
2095
2199
|
} catch (error) {
|
|
2096
2200
|
const message = error instanceof Error ? error.message : String(error);
|
|
2201
|
+
emitTelemetry(telemetryClient, "installer_update_failed", {
|
|
2202
|
+
...updateTelemetryBase,
|
|
2203
|
+
observed_release_tag: current.tagName,
|
|
2204
|
+
observed_version: current.version,
|
|
2205
|
+
...telemetryFailureContext(error, "update_check"),
|
|
2206
|
+
});
|
|
2097
2207
|
if (message !== lastUpdateError) {
|
|
2098
2208
|
emitStatus(onStatus, "Pylon update check failed", message);
|
|
2099
2209
|
lastUpdateError = message;
|