mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-29 14:02:19 +00:00
* feat(autocomplete): add overlay TTL configuration to AutocompletePanel - Introduced `overlay_ttl_ms` parameter to the Autocomplete configuration, allowing users to set the overlay display duration. - Updated AutocompletePanel to include a new input field for adjusting the overlay TTL in milliseconds. - Enhanced parsing and saving logic to handle the new configuration parameter. - Added corresponding tests to ensure functionality and validate the new overlay TTL feature. This update improves user control over the autocomplete overlay behavior, enhancing the overall user experience. * Refactor accessibility code for improved readability and consistency - Simplified log statements in `precompile_helper_background` for better clarity. - Reformatted `detect_input_monitoring_permission` check in `keys.rs` for enhanced readability. - Rearranged imports in `mod.rs` to maintain consistent structure. - Improved formatting of `ElementBounds` initialization across multiple test cases in `overlay.rs` and `types.rs` for better visual alignment. - Enhanced test context creation in `types.rs` for improved clarity. These changes enhance code maintainability and readability across the accessibility module. * fix(overlay): parent core RPC, voice toggle, and debug for #342 - Pass OPENHUMAN_OVERLAY_PARENT_RPC_URL from sidecar spawn and strip inherited OPENHUMAN_CORE_PORT so the overlay no longer fights for the parent listen port. - Overlay UI uses HTTP JSON-RPC to the parent sidecar for globe, debug, and voice STT so state matches the main app; add parentCoreRpc helper mirroring legacy method aliases. - Skip embedded JSON-RPC server when parent URL is set; use OPENHUMAN_OVERLAY_EMBEDDED_CORE_PORT (default 7799) for standalone dev. - Fix screen intelligence status method name; add voice_status polling, STT section, collapsible debug summary, and connection banner when core is unreachable. - Voice capture switch gates the mic with real STT availability from voice_status. Closes #342 Made-with: Cursor * fix: address CodeRabbit review on overlay/autocomplete (PR #378) - helper: correlate JSON-RPC replies with monotonic request ids; discard mismatched lines until deadline (fixes stale response after timeout). - helper: serialize Swift compile via HELPER_COMPILE_LOCK (precompile vs first use). - Overlay Tab hint: pass tab_hint from Rust from accept_with_tab; Swift hides hint when empty. - keys: re-check Input Monitoring on an interval when denied so grant without restart works. - engine: use non-zero confidence placeholder (0.75) until inline_complete returns scores. - overlay dedupe: suppress identical badge only within 400ms, not for process lifetime. Co-authored-by: Code review feedback <noreply@github.com> Made-with: Cursor * fix(ci): resolve clippy and warning issues for Rust gates - Use match on anchor_bounds in autocomplete overlay (avoid unnecessary unwrap) - Drop unused test imports in registry_ops and rpc dispatch - Prefix unused notion_doc_id in subconscious integration test Made-with: Cursor * fix(overlay): improve parent RPC URL handling in App component - Updated the useEffect hook to manage the parent RPC URL more robustly by introducing a mounted flag to prevent state updates on unmounted components. - Added error handling to set the parent RPC URL to null in case of invocation failure, enhancing the reliability of the component's behavior. * feat(overlay): implement timeout handling for parent core RPC requests - Introduced a default timeout for parent core RPC requests, enhancing reliability by preventing indefinite waiting for responses. - Added an AbortController to manage request timeouts, throwing a specific error message when a timeout occurs. - Updated the `callParentCoreRpc` function to accept a customizable timeout parameter, improving flexibility for RPC calls. * fix(overlay): allow stopping active recording regardless of config state - Updated the main button handler in the App component to always permit stopping an active recording when the status is "listening", improving user experience and control over the recording process. - Removed redundant code that previously checked the status before stopping the recording, streamlining the logic. * feat(overlay): update Cargo.lock with new dependencies and versions - Added new packages including `alsa`, `alsa-sys`, `arboard`, `block`, `cocoa`, `core-foundation`, `core-graphics`, `coreaudio-rs`, `coreaudio-sys`, `cpal`, `crunchy`, and `dasp_sample` to enhance functionality and support for audio processing and system interactions. - Updated existing dependencies to their latest versions for improved performance and compatibility. - Modified the `show_overlay` function in `ops.rs` to include an additional parameter, enhancing the overlay display functionality. * feat(autocomplete): add overlay_ttl_ms parameter to Autocomplete interfaces - Introduced a new optional parameter `overlay_ttl_ms` to both `AutocompleteSetStyleParams` and `AutocompleteConfig` interfaces, allowing for customizable overlay timeout settings. - This enhancement improves the flexibility of the autocomplete feature by enabling developers to specify how long the overlay should remain visible. --------- Co-authored-by: Code review feedback <noreply@github.com> Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
96 lines
2.5 KiB
TypeScript
96 lines
2.5 KiB
TypeScript
/**
|
|
* HTTP JSON-RPC to the desktop core sidecar (same process as the main app).
|
|
* Mirrors the naming normalization in app/src/services/coreRpcClient.ts (subset).
|
|
*/
|
|
|
|
let nextJsonRpcId = 1;
|
|
|
|
export function normalizeLegacyMethod(method: string): string {
|
|
if (method.startsWith("openhuman.accessibility_")) {
|
|
return method.replace("openhuman.accessibility_", "openhuman.screen_intelligence_");
|
|
}
|
|
return method;
|
|
}
|
|
|
|
/** RpcOutcome with non-empty logs serializes as `{ result, logs }` in the core. */
|
|
function unwrapCliCompatibleJson<T>(raw: unknown): T {
|
|
if (
|
|
raw !== null &&
|
|
typeof raw === "object" &&
|
|
"result" in raw &&
|
|
"logs" in raw &&
|
|
Array.isArray((raw as { logs: unknown }).logs)
|
|
) {
|
|
return (raw as { result: T }).result;
|
|
}
|
|
return raw as T;
|
|
}
|
|
|
|
interface JsonRpcError {
|
|
code: number;
|
|
message: string;
|
|
data?: unknown;
|
|
}
|
|
|
|
interface JsonRpcResponse<T> {
|
|
jsonrpc?: string;
|
|
id?: number | string | null;
|
|
result?: T;
|
|
error?: JsonRpcError;
|
|
}
|
|
|
|
/** Default timeout for parent core RPC requests (ms). */
|
|
const DEFAULT_RPC_TIMEOUT_MS = 10_000;
|
|
|
|
export async function callParentCoreRpc<T>(
|
|
rpcUrl: string,
|
|
method: string,
|
|
params: Record<string, unknown> = {},
|
|
timeoutMs: number = DEFAULT_RPC_TIMEOUT_MS,
|
|
): Promise<T> {
|
|
const normalizedMethod = normalizeLegacyMethod(method);
|
|
const payload = {
|
|
jsonrpc: "2.0" as const,
|
|
id: nextJsonRpcId++,
|
|
method: normalizedMethod,
|
|
params,
|
|
};
|
|
|
|
const controller = new AbortController();
|
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
|
|
let response: Response;
|
|
try {
|
|
response = await fetch(rpcUrl, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(payload),
|
|
signal: controller.signal,
|
|
});
|
|
} catch (err) {
|
|
clearTimeout(timer);
|
|
if (err instanceof DOMException && err.name === "AbortError") {
|
|
throw new Error(`Core RPC request timed out after ${timeoutMs}ms (method: ${normalizedMethod})`);
|
|
}
|
|
throw err;
|
|
} finally {
|
|
clearTimeout(timer);
|
|
}
|
|
|
|
if (!response.ok) {
|
|
const text = await response.text();
|
|
throw new Error(`Core RPC HTTP ${response.status}: ${text || response.statusText}`);
|
|
}
|
|
|
|
const json = (await response.json()) as JsonRpcResponse<unknown>;
|
|
|
|
if (json.error) {
|
|
throw new Error(json.error.message || "Core RPC returned an error");
|
|
}
|
|
if (!Object.prototype.hasOwnProperty.call(json, "result")) {
|
|
throw new Error("Core RPC response missing result");
|
|
}
|
|
|
|
return unwrapCliCompatibleJson<T>(json.result);
|
|
}
|