feat: implement telemetry system for application usage tracking

- Added telemetry utility to capture application events and metrics.
- Integrated PostHog for event tracking with distinct user identification.
- Implemented telemetry initialization, event capturing, and shutdown procedures.

feat: add UV environment setup for Python management

- Created utilities to manage Python installation and configuration.
- Implemented network optimization checks for Python installation mirrors.
- Added functions to set up managed Python environments with error handling.

feat: enhance host API communication with token management

- Introduced host API token retrieval and management for secure requests.
- Updated host API fetch functions to include token in headers.
- Added support for creating event sources with authentication.

test: add comprehensive tests for gateway protocol and startup helpers

- Implemented unit tests for gateway protocol helpers, event dispatching, and state management.
- Added tests for startup recovery strategies and process policies.
- Ensured coverage for connection monitoring and restart governance logic.
This commit is contained in:
DEV_DSW
2026-04-23 17:21:57 +08:00
parent 655e7c51d2
commit 71bcc3b3c5
39 changed files with 5504 additions and 313 deletions

View File

@@ -0,0 +1,62 @@
export type GatewayReloadMode = 'hybrid' | 'reload' | 'restart' | 'off';
export type GatewayReloadPolicy = {
mode: GatewayReloadMode;
debounceMs: number;
};
export const DEFAULT_GATEWAY_RELOAD_POLICY: GatewayReloadPolicy = {
mode: 'hybrid',
debounceMs: 1200,
};
const MAX_DEBOUNCE_MS = 60_000;
function normalizeMode(value: unknown): GatewayReloadMode {
if (value === 'off' || value === 'reload' || value === 'restart' || value === 'hybrid') {
return value;
}
return DEFAULT_GATEWAY_RELOAD_POLICY.mode;
}
function normalizeDebounceMs(value: unknown): number {
if (typeof value !== 'number' || !Number.isFinite(value)) {
return DEFAULT_GATEWAY_RELOAD_POLICY.debounceMs;
}
const rounded = Math.round(value);
if (rounded < 0) return 0;
if (rounded > MAX_DEBOUNCE_MS) return MAX_DEBOUNCE_MS;
return rounded;
}
export function parseGatewayReloadPolicy(config: unknown): GatewayReloadPolicy {
if (!config || typeof config !== 'object') {
return { ...DEFAULT_GATEWAY_RELOAD_POLICY };
}
const root = config as Record<string, unknown>;
const gateway = (root.gateway && typeof root.gateway === 'object'
? root.gateway
: {}) as Record<string, unknown>;
const reload = (gateway.reload && typeof gateway.reload === 'object'
? gateway.reload
: {}) as Record<string, unknown>;
return {
mode: normalizeMode(reload.mode),
debounceMs: normalizeDebounceMs(reload.debounceMs),
};
}
export async function loadGatewayReloadPolicy(): Promise<GatewayReloadPolicy> {
try {
const [{ readFile }, { homedir }, { join }] = await Promise.all([
import('node:fs/promises'),
import('node:os'),
import('node:path'),
]);
const raw = await readFile(join(homedir(), '.openclaw', 'openclaw.json'), 'utf-8');
return parseGatewayReloadPolicy(JSON.parse(raw));
} catch {
return { ...DEFAULT_GATEWAY_RELOAD_POLICY };
}
}