Files
openhuman/app/src/hooks/useComposeioTriggerHistory.ts
T
Steven EnamakelandGitHub a115758c6c Improve local voice readiness and add Composio trigger history (#516)
* feat: enhance local AI asset state management and error handling

- Updated the Home component to improve readiness checks for local AI assets, ensuring a more robust UI experience.
- Refactored the LocalAiService to provide clearer state management for STT and TTS models, including handling on-demand downloads and error logging.
- Enhanced the voice status function to accurately reflect the availability of transcription backends, improving overall system reliability.
- Introduced warnings for on-demand model downloads to inform users about potential delays in functionality.

* feat: implement polling for voice server status in OverlayApp

- Added a polling mechanism to periodically check the voice server status every 2 seconds, ensuring the overlay remains in sync with the server state.
- Introduced logic to activate or dismiss the speech-to-text (STT) mode based on the server's recording or transcribing state, enhancing user experience and responsiveness.
- Utilized the existing `callCoreRpc` function to fetch server status, improving reliability in state management during brief disconnects or reconnections.

* feat: refine prompt handling in LocalAiService

- Updated the prompt construction logic in `LocalAiService` to enhance clarity and functionality.
- When `no_think` is set, the system prompt now includes a directive for the model to respond with only the final answer, improving response accuracy.
- Refactored the prompt and system parameters to ensure they are correctly formatted and passed to the `OllamaGenerateRequest`, enhancing overall request handling.

* feat: enhance STT readiness checks in VoicePanel and useVoiceSkillStatus

- Updated the STT readiness logic in `VoicePanel` to account for both 'ready' and 'ondemand' states, improving the accuracy of readiness assessments.
- Refined the `useVoiceSkillStatus` hook to ensure it only blocks when the local AI's STT state is explicitly 'missing', enhancing overall system reliability and user experience.

* feat(composio): implement ComposeIO trigger history component and hook

- Added `ComposeioTriggerHistory` component to display a list of ComposeIO trigger events with formatted timestamps and payloads.
- Introduced `useComposeioTriggerHistory` hook to manage fetching and state of trigger history entries, including error handling and loading states.
- Updated `Webhooks` page to integrate the new component and hook, replacing previous webhook activity display with ComposeIO trigger history.
- Created utility functions for formatting timestamps and payloads for better readability in the UI.
- Established backend support for fetching trigger history through new Tauri commands, ensuring robust data handling and storage.

* style: apply repo formatting fixes

* feat: add fs2 dependency and enhance ComposeIO trigger history handling

- Introduced the `fs2` crate to manage file locking, improving the reliability of file operations in the ComposeIO trigger history.
- Updated `ComposioTriggerHistoryStore` to utilize exclusive file locks during archive writing, ensuring data integrity.
- Enhanced error handling for file operations, providing clearer logging for failures related to file access and locking.
- Refactored the initialization logic for global trigger history to prevent duplicate setups, improving overall stability.
2026-04-12 16:43:33 -07:00

112 lines
3.3 KiB
TypeScript

import debug from 'debug';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useCoreState } from '../providers/CoreStateProvider';
import {
type ComposioTriggerHistoryEntry,
openhumanComposioListTriggerHistory,
} from '../utils/tauriCommands';
const log = debug('composio:history');
const POLL_MS = 5000;
export interface ComposeioTriggerHistoryState {
archiveDir: string | null;
currentDayFile: string | null;
entries: ComposioTriggerHistoryEntry[];
loading: boolean;
error: string | null;
coreConnected: boolean;
refresh: () => Promise<void>;
}
export function useComposeioTriggerHistory(limit = 100): ComposeioTriggerHistoryState {
const { snapshot } = useCoreState();
const [archiveDir, setArchiveDir] = useState<string | null>(null);
const [currentDayFile, setCurrentDayFile] = useState<string | null>(null);
const [entries, setEntries] = useState<ComposioTriggerHistoryEntry[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [coreConnected, setCoreConnected] = useState(false);
const isRefreshingRef = useRef(false);
const sessionTokenRef = useRef(snapshot.sessionToken);
const clearHistory = useCallback(() => {
setArchiveDir(null);
setCurrentDayFile(null);
setEntries([]);
setLoading(false);
setError(null);
setCoreConnected(false);
}, []);
useEffect(() => {
sessionTokenRef.current = snapshot.sessionToken;
}, [snapshot.sessionToken]);
const refresh = useCallback(async () => {
if (isRefreshingRef.current) {
return;
}
if (!snapshot.sessionToken) {
clearHistory();
return;
}
const requestToken = snapshot.sessionToken;
isRefreshingRef.current = true;
setLoading(true);
try {
const response = await openhumanComposioListTriggerHistory(limit);
if (!sessionTokenRef.current || sessionTokenRef.current !== requestToken) {
return;
}
const result = response.result.result;
setArchiveDir(result.archive_dir);
setCurrentDayFile(result.current_day_file);
setEntries(result.entries);
setError(null);
setCoreConnected(true);
log('loaded %d composio trigger entries', result.entries.length);
} catch (refreshError) {
if (!sessionTokenRef.current || sessionTokenRef.current !== requestToken) {
return;
}
const message =
refreshError instanceof Error ? refreshError.message : 'Failed to load ComposeIO history';
setError(message);
setCoreConnected(false);
log('failed to load trigger history: %s', message);
} finally {
isRefreshingRef.current = false;
setLoading(false);
}
}, [clearHistory, limit, snapshot.sessionToken]);
useEffect(() => {
if (snapshot.sessionToken) {
return;
}
clearHistory();
}, [clearHistory, snapshot.sessionToken]);
useEffect(() => {
if (!snapshot.sessionToken) {
clearHistory();
return;
}
void refresh();
const timer = window.setInterval(() => {
void refresh();
}, POLL_MS);
return () => {
window.clearInterval(timer);
};
}, [clearHistory, refresh, snapshot.sessionToken]);
return { archiveDir, currentDayFile, entries, loading, error, coreConnected, refresh };
}