Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b5aec57
refactor(tauri): update development scripts and configuration for CEF…
senamakel Apr 18, 2026
e37ddf3
refactor(release): enhance macOS signing script for nested frameworks…
senamakel Apr 18, 2026
6a2a69f
feat(orchestrator): add current_time tool and enhance agent capabilities
senamakel Apr 18, 2026
86fe30e
feat(gmail): implement post-processing for Gmail responses to convert…
senamakel Apr 18, 2026
95ea9d6
refactor(gmail): improve HTML to markdown conversion and tool result …
senamakel Apr 18, 2026
3e66a76
feat(thread): implement thread title generation from user and assista…
senamakel Apr 18, 2026
22ffdf7
feat(conversations): add thread title update functionality
senamakel Apr 18, 2026
96b0227
feat(docs): add comprehensive agent and subagent tool flow documentation
senamakel Apr 18, 2026
5fb289b
feat(subagent): implement extraction tool and handoff cache for overs…
senamakel Apr 18, 2026
ad1c399
feat(conversations): enhance message bubble rendering and timeline en…
senamakel Apr 18, 2026
34fd6c5
feat(subagent): enforce restrictions on sub-agent spawning tools
senamakel Apr 18, 2026
198da7d
feat(conversations): add ToolTimelineBlock component and enhance time…
senamakel Apr 18, 2026
b8f7495
refactor(conversations): streamline component imports and enhance for…
senamakel Apr 18, 2026
9e70107
fix: satisfy pre-push lint on fix/tauri
senamakel Apr 18, 2026
45a04e7
fix(chat): refresh usage counters after responses
senamakel Apr 18, 2026
d7661dd
refactor(ChatRuntimeProvider): remove redundant import of requestUsag…
senamakel Apr 18, 2026
37140cf
fix(chat): satisfy pre-push checks
senamakel Apr 18, 2026
d0a7c5d
refactor(conversations): improve error handling and remove unused tit…
senamakel Apr 18, 2026
d0a024e
refactor(conversations): improve formatting of title redaction and st…
senamakel Apr 18, 2026
99c8b08
refactor(tokenjuice): sort fact parts for improved formatting in inli…
senamakel Apr 18, 2026
4a7eaaf
fix: address remaining CodeRabbit review comments
senamakel Apr 18, 2026
d3b98cc
refactor: streamline error handling and improve code readability
senamakel Apr 18, 2026
94f74e0
refactor: improve code formatting and structure
senamakel Apr 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
"scripts": {
"dev": "vite",
"dev:web": "vite",
"dev:app": "yarn tauri:ensure && yarn core:stage && bash ../scripts/setup-chromium-safe-storage.sh && source ../scripts/load-dotenv.sh && APPLE_SIGNING_IDENTITY='OpenHuman Dev Signer' cargo tauri dev",
"dev:app": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && yarn core:stage && bash ../scripts/setup-chromium-safe-storage.sh && source ../scripts/load-dotenv.sh && APPLE_SIGNING_IDENTITY='OpenHuman Dev Signer' cargo tauri dev",
"dev:cef": "yarn dev:app",
"dev:wry": "yarn tauri:ensure && yarn core:stage && source ../scripts/load-dotenv.sh && cargo tauri dev --no-default-features --features wry",
"dev:wry": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && yarn core:stage && source ../scripts/load-dotenv.sh && cargo tauri dev --no-default-features --features wry",
"core:stage": "node ../scripts/stage-core-sidecar.mjs",
"tauri:ensure": "bash ../scripts/ensure-tauri-cli.sh",
"build": "tsc && vite build",
"build:app": "tsc && vite build",
"compile": "tsc --noEmit",
"preview": "vite preview",
"tauri": "tauri",
"tauri:build:ui": "yarn tauri:ensure && cargo tauri build -- --bin OpenHuman",
"macos:build:intel": "yarn tauri:ensure && source ../scripts/load-dotenv.sh && cargo tauri build --bundles app dmg --target x86_64-apple-darwin -- --bin OpenHuman",
"macos:build:intel:debug": "yarn tauri:ensure && source ../scripts/load-dotenv.sh && cargo tauri build --debug --bundles app dmg --target x86_64-apple-darwin -- --bin OpenHuman",
"macos:build:debug": "yarn tauri:ensure && source ../scripts/load-dotenv.sh && cargo tauri build --debug --bundles app dmg -- --bin OpenHuman",
"macos:build:release": "yarn tauri:ensure && source ../scripts/load-dotenv.sh && cargo tauri build --bundles app dmg -- --bin OpenHuman",
"macos:build:release:signed": "yarn tauri:ensure && source ../scripts/load-env.sh && cargo tauri build --bundles app dmg -- --bin OpenHuman",
"tauri:build:ui": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && cargo tauri build -- --bin OpenHuman",
"macos:build:intel": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && source ../scripts/load-dotenv.sh && cargo tauri build --bundles app dmg --target x86_64-apple-darwin -- --bin OpenHuman",
"macos:build:intel:debug": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && source ../scripts/load-dotenv.sh && cargo tauri build --debug --bundles app dmg --target x86_64-apple-darwin -- --bin OpenHuman",
"macos:build:debug": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && source ../scripts/load-dotenv.sh && cargo tauri build --debug --bundles app dmg -- --bin OpenHuman",
"macos:build:release": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && source ../scripts/load-dotenv.sh && cargo tauri build --bundles app dmg -- --bin OpenHuman",
"macos:build:release:signed": "yarn tauri:ensure && export CEF_PATH=\"$HOME/Library/Caches/tauri-cef\" && source ../scripts/load-env.sh && cargo tauri build --bundles app dmg -- --bin OpenHuman",
"macos:build:sign:release": "yarn macos:build:release:signed",
"macos:run": "open '../target/debug/bundle/macos/OpenHuman.app'",
"macos:dev": "yarn macos:build:debug && open '../target/debug/bundle/macos/OpenHuman.app'",
Expand Down
36 changes: 19 additions & 17 deletions app/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ fn overlay_parent_rpc_url() -> Option<String> {
Some(trimmed.to_string())
}

#[allow(dead_code)] // Overlay disabled in tauri.conf.json; helper kept for future re-enable.
fn pin_overlay_bottom_right(window: &WebviewWindow<AppRuntime>) {
let Ok(Some(monitor)) = window.current_monitor() else {
log::warn!("[overlay] could not resolve current monitor for positioning");
Expand All @@ -111,6 +112,7 @@ fn pin_overlay_bottom_right(window: &WebviewWindow<AppRuntime>) {
}

#[cfg(target_os = "macos")]
#[allow(dead_code)] // Overlay disabled in tauri.conf.json; helper kept for future re-enable.
fn configure_overlay_window_macos(window: &WebviewWindow<AppRuntime>) {
// Standard NSWindow cannot float above fullscreen apps on macOS because
// fullscreen apps run in a separate Space. Only NSPanel can do this.
Expand Down Expand Up @@ -612,23 +614,23 @@ pub fn run() {
}
}

#[cfg(target_os = "macos")]
{
if let Some(window) = app.get_webview_window("overlay") {
configure_overlay_window_macos(&window);
} else {
log::warn!("[overlay] overlay window not found during setup");
}
}

if let Some(window) = app.get_webview_window("overlay") {
pin_overlay_bottom_right(&window);
if let Err(err) = window.show() {
log::warn!("[overlay] failed to show overlay on startup: {err}");
} else {
log::info!("[overlay] overlay shown on startup");
}
}
// Overlay window is currently disabled in `tauri.conf.json` (the
// `overlay` entry under `app.windows` was removed), so we skip
// the macOS NSPanel reclass + bottom-right pin + initial show
// here. The helpers (`configure_overlay_window_macos`,
// `pin_overlay_bottom_right`) and the React entry point
// (`src/overlay/OverlayApp.tsx`) are kept intact so the overlay
// can be re-enabled by restoring the config entry and the two
// setup blocks below.
//
// #[cfg(target_os = "macos")]
// if let Some(window) = app.get_webview_window("overlay") {
// configure_overlay_window_macos(&window);
// }
// if let Some(window) = app.get_webview_window("overlay") {
// pin_overlay_bottom_right(&window);
// let _ = window.show();
// }

if let Err(err) = setup_tray(app.handle()) {
log::error!("[tray] failed to setup tray icon: {err}");
Expand Down
14 changes: 0 additions & 14 deletions app/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@
"decorations": true,
"resizable": true,
"center": true
},
{
"label": "overlay",
"title": "OpenHuman Overlay",
"width": 50,
"height": 50,
"transparent": true,
"decorations": false,
"alwaysOnTop": true,
"skipTaskbar": true,
"resizable": false,
"visible": false,
"create": false,
"center": false
}
],
"security": {
Expand Down
2 changes: 1 addition & 1 deletion app/src-tauri/vendor/tauri-cef
28 changes: 28 additions & 0 deletions app/src/hooks/usageRefresh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import debug from 'debug';

type UsageRefreshListener = () => void;

const listeners = new Set<UsageRefreshListener>();
const usageRefreshLog = debug('usage-refresh');
let dispatchCount = 0;

export function subscribeUsageRefresh(listener: UsageRefreshListener): () => void {
listeners.add(listener);
usageRefreshLog('[usage-refresh] subscribe listeners=%d', listeners.size);
return () => {
listeners.delete(listener);
usageRefreshLog('[usage-refresh] unsubscribe listeners=%d', listeners.size);
};
}

export function requestUsageRefresh(): void {
dispatchCount += 1;
usageRefreshLog('[usage-refresh] dispatch count=%d listeners=%d', dispatchCount, listeners.size);
for (const listener of listeners) {
try {
listener();
} catch (error) {
usageRefreshLog('[usage-refresh] listener_error count=%d error=%O', dispatchCount, error);
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
}
60 changes: 59 additions & 1 deletion app/src/hooks/useUsageState.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { renderHook, waitFor } from '@testing-library/react';
import { act, renderHook, waitFor } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';

const mockGetCurrentPlan = vi.fn();
Expand Down Expand Up @@ -131,4 +131,62 @@ describe('useUsageState', () => {
expect(result.current.isBudgetExhausted).toBe(false);
expect(result.current.shouldShowBudgetCompletedMessage).toBe(false);
});

it('refetches when a global usage refresh is requested', async () => {
const { useUsageState } = await import('./useUsageState');
const { requestUsageRefresh } = await import('./usageRefresh');

mockGetCurrentPlan.mockResolvedValue({
plan: 'BASIC',
hasActiveSubscription: true,
planExpiry: '2026-05-01T00:00:00.000Z',
subscription: {
id: 'sub_123',
status: 'active',
currentPeriodEnd: '2026-05-01T00:00:00.000Z',
quantity: 1,
},
monthlyBudgetUsd: 20,
weeklyBudgetUsd: 10,
fiveHourCapUsd: 3,
});
mockGetTeamUsage
.mockResolvedValueOnce({
remainingUsd: 9,
cycleBudgetUsd: 10,
cycleLimit5hr: 1,
cycleLimit7day: 1,
fiveHourCapUsd: 3,
fiveHourResetsAt: null,
cycleStartDate: '2026-04-09T00:00:00.000Z',
cycleEndsAt: '2026-04-16T00:00:00.000Z',
bypassCycleLimit: false,
})
.mockResolvedValueOnce({
remainingUsd: 7,
cycleBudgetUsd: 10,
cycleLimit5hr: 2,
cycleLimit7day: 3,
fiveHourCapUsd: 3,
fiveHourResetsAt: null,
cycleStartDate: '2026-04-09T00:00:00.000Z',
cycleEndsAt: '2026-04-16T00:00:00.000Z',
bypassCycleLimit: false,
});

const { result } = renderHook(() => useUsageState());

await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
expect(result.current.teamUsage?.remainingUsd).toBe(9);

act(() => {
requestUsageRefresh();
});

await waitFor(() => {
expect(result.current.teamUsage?.remainingUsd).toBe(7);
});
});
});
3 changes: 3 additions & 0 deletions app/src/hooks/useUsageState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
import { billingApi } from '../services/api/billingApi';
import { creditsApi, type TeamUsage } from '../services/api/creditsApi';
import type { CurrentPlanData, PlanTier } from '../types/api';
import { subscribeUsageRefresh } from './usageRefresh';

export interface UsageState {
teamUsage: TeamUsage | null;
Expand Down Expand Up @@ -50,6 +51,8 @@ export function useUsageState(): UsageState {
setFetchCount(c => c + 1);
}, []);

useEffect(() => subscribeUsageRefresh(refresh), [refresh]);

useEffect(() => {
let cancelled = false;
setIsLoading(true);
Expand Down
Loading
Loading