Commit Graph
96 Commits
Author SHA1 Message Date
41e548b3d8 fix(observability): drop transient backend_api + integrations failures from Sentry (#1632)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 14:20:33 -07:00
6d2e722fa8 fix(threads): typed ThreadNotFound error + skip Sentry for stale-thread RPCs (OPENHUMAN-TAURI-4H, -60) (#1570)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-12 21:30:34 -07:00
afdc268040 fix(observability): drop transient upstream HTTP from Sentry (429/408/502/503/504) (#1529)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-12 20:45:06 -07:00
sanil-23andGitHub 12ef69b89f feat(learning): ambient personalization cache for #566 (#1460) 2026-05-10 09:45:40 -07:00
Steven EnamakelandGitHub 065e198cf4 Support reliable self-update for server-side and headless core instances (#1458) 2026-05-09 23:55:25 -07:00
Steven EnamakelandGitHub 97089a68a6 feat(wallet): add execution surface for balances, transfers, swaps, contract calls (#1396) (#1424) 2026-05-09 15:54:09 -07:00
Steven EnamakelandGitHub 6e2d69792d Add seed phrase onboarding and multi-chain wallet setup (#1407) 2026-05-09 13:54:10 -07:00
Steven EnamakelandGitHub 6b044a9456 docs: rewrite README + gitbooks around current product, add Developing section (#1384) 2026-05-08 21:18:20 -07:00
8d9a1ca788 perf(agent): orchestrator harness efficiency improvements (#1314)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-08 20:09:47 -07:00
0f6cc583f3 feat(tools/whatsapp_data): expose local WhatsApp store to agent (#1341) (#1373)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 19:04:15 -07:00
Steven EnamakelandGitHub 0636b0c1a5 feat(meet_agent): live note-taking agent for Google Meet (listen + speak) (#1355) 2026-05-07 20:10:42 -07:00
Steven EnamakelandGitHub 836a6d852c feat(meet): join Google Meet calls with mascot virtual camera (#1350) 2026-05-07 17:56:05 -07:00
obchainandGitHub 3bbf4b5d9f fix(stt): rewrite stale-sidecar voice error + e2e registration guard (#1298) 2026-05-07 12:05:07 -07:00
ba88d8cfc3 fix(webview/meet): gate orchestrator handoff on user opt-in (#1299) (#1310)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 17:43:21 -07:00
a35ba10bb2 feat(channels): expose WhatsApp Web data to agent via structured RPC API (#1308)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-06 13:11:52 -07:00
Steven EnamakelandGitHub b03412111d Agent harness: USD cost tracking, stop hooks, per-tool result caps (#1268) 2026-05-05 22:36:01 -07:00
Steven EnamakelandGitHub 1570f3220b feat(local-ai): off by default, scoped usage flags, faster auto-updates (#1263) 2026-05-05 22:22:54 -07:00
obchainandGitHub 1ac3feed3a fix(channels): managed-DM credentials surface as connected to chat (#1209) 2026-05-05 11:24:28 -07:00
Steven EnamakelandGitHub 49a9b835b6 Persist turn state + restore conversation history on cold-boot (#1202) 2026-05-04 22:02:51 -07:00
62516ba418 feat(memory_tree): cloud-default LLM, queue priority, entity filter, Memory tab UI (#1198)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 20:52:56 -07:00
YellowSnnowmannandGitHub 995e5ccccb feat(security): enforce prompt-injection guard before model and tool execution (#1175) 2026-05-04 02:30:22 -07:00
Steven EnamakelandGitHub d812bf9da7 fix(agent): drop redundant [Memory context] recall injection (#1173) 2026-05-04 00:09:50 -07:00
Steven EnamakelandGitHub e6b491bcf1 feat(threads): surface live subagent work in parent thread (#1122) (#1159) 2026-05-03 19:51:46 -07:00
Steven EnamakelandGitHub 2484ea40f2 feat(memory): ingestion pipeline + tree-architecture docs + ops/schemas split (#1142) 2026-05-03 15:22:22 -07:00
Steven EnamakelandGitHub 52eb3a175f feat(memory): singleton ingestion + status RPC + UI pill (#1126) 2026-05-03 12:52:55 -07:00
393852b1d6 Feat: core rpc auth (#881)
Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-29 18:43:58 -07:00
Steven EnamakelandGitHub 2304d9d58f feat(memory): add Sync and Learn sections to Memory workspace (#1031) 2026-04-29 18:43:11 -07:00
Steven EnamakelandGitHub ac97a96d3a fix(local-ai): cap local models to 1b preset (#1029) 2026-04-29 18:39:03 -07:00
0768d18873 feat(orchestrator): wire memory-tree retrieval tools with periodic prefetch (#1027)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 11:08:21 -07:00
40fddf5bfa chore(dev): add Windows dev runner and align lockfile versions (#1015)
Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com>
2026-04-29 11:07:00 -07:00
Steven EnamakelandGitHub b11b8f333f [Feature] Thread labels / categories for list organization (#947) 2026-04-28 22:08:45 -07:00
Steven EnamakelandGitHub da94043c31 test(memory): phase 1 email ingest harness (#1009) 2026-04-28 19:25:25 -07:00
YellowSnnowmannGitHubgoogle-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
cf89552273 Fix: calendar events (#1004)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-04-28 18:55:49 -07:00
fd0398d5fa feat(memory): MD-on-disk content + participant bucketing + async pipeline foundation (#1008)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-28 17:44:20 -07:00
4f9da9eb8d test(foundation): coverage matrix + strategy + gap-fill batch (#773) (#980)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 16:13:48 +05:30
oxoxDevandGitHub 215a776eea feat(ux): lock UI to welcome agent until chat onboarding completes (#883) (#892) 2026-04-24 15:46:31 -07:00
Mega MindandGitHub d2f045769f test(notifications): add Phase 4 RPC and dismiss reducer coverage (#878) 2026-04-24 12:45:26 -07:00
95504d4b09 test: add 196 tests across MCP, services, utils, autocomplete (#855)
Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-24 11:47:26 -07:00
Steven EnamakelandGitHub 7bd8f9d4c1 ci: parallelize rust tests, dedupe typecheck/clippy/sentry across workflows (#895) 2026-04-24 11:10:27 -07:00
VectorJetandGitHub a96d9da3a4 chore: migrate from yarn to pnpm (#886) 2026-04-24 10:52:16 -07:00
Steven EnamakelandGitHub 3862b1bb1c fix(tests): run webview_apis mock bridge on a dedicated runtime (#893) 2026-04-24 10:33:42 -07:00
Mega MindandGitHub 11c67a70b9 feat(notifications): add dismiss/stats RPC, DomainEvents, and triage bus integration (#875) 2026-04-24 22:33:51 +05:30
Mega MindandGitHub 208c276a3e feat(notifications): bridge CEF providers into core ingest pipeline with dedup (#874) 2026-04-24 19:18:10 +05:30
b329e45cdb feat(skills): uninstall for user-scope SKILL.md skills (#781) (#833)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-24 17:23:40 +05:30
Steven EnamakelandGitHub 500ddc2a8a feat(webview_apis): WebSocket bridge for live-webview APIs, Gmail first (#869) 2026-04-23 22:21:53 -07:00
629b4ccb07 test(memory_tree): unit tests for retrieval RPC handlers (#710) (#839)
- Add JSON-RPC handlers for source, global, and topic-based memory retrieval.
- Integrate Ollama embeddings for semantic reranking of chunks and summaries.
- Implement 15 unit tests for RPC handlers covering parameter parsing and PII redaction.
- Redact PII from logs by removing raw source, entity, and node identifiers.
- Fix BFS traversal for drill-down and deduplicate results in topic queries.
- Add configuration for embedding endpoints, models, and strictness modes.

Co-authored-by: sanil-23 <sanil@vezures.xyz>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-23 12:31:56 -07:00
5e660f2fe8 feat(core): memory namespaces, recall citations, provider_surfaces RPC (#803)
Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-23 09:57:26 -07:00
3bb714bf96 feat(webview): native OS notifications from embedded webview apps (#714) (#727)
* feat(webview_accounts): native OS notifications from embedded webviews (#714)

Forward CEF notification intercept payloads to tauri-plugin-notification,
prefixing the title with the provider label so the source of each toast is
obvious at a glance. Honour `silent` (skip toast, still record route),
`icon` (passed through to the native builder), and `tag` (used as the
dedup key, with a monotonic timestamp fallback for untagged payloads).

Record a NotificationRoute keyed by `{provider}:{account_id}:{tag_or_uuid}`
so a future click hook (UNUserNotificationCenter / notify-rust on_response)
can route the OS click back to the source account. Entries are cleared on
webview_account_close / _purge to bound map growth.

Expose webview_notification_permission_state / _request commands mapping
tauri::plugin::PermissionState onto the web API triple. Non-cef stubs
return "default" so the frontend can call the same invoke names on both
runtimes. Wire notification:allow-* capabilities so the plugin can be
invoked from the webview.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(accounts): wire notification permission + click bridge (#714)

Round-trip the OS notification permission once per session on first
account open via the new invoke pair. Attach a dormant notification:click
listener that dispatches setActiveAccount and brings the main window to
front when a platform click hook starts emitting the event — contract
matches the Rust NotificationRoute shape so the emit side is a one-liner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: sync Cargo.lock to 0.52.26 after version bump

Lockfile picked up the pending 0.52.26 version bump from Cargo.toml
while building the notification feature. No dependency graph change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(notifications): add notification bypass for embedded webview apps (#679)

- Add NotificationBypassPrefs (global DND, per-account mute, bypass-when-focused)
  to WebviewAccountsState with thread-safe AtomicBool window focus tracking
- Evaluate all three bypass conditions inside forward_native_notification before
  showing OS toast; each suppression path logs at debug with [notify-bypass] prefix
- Add four new Tauri commands: webview_notification_set_dnd,
  webview_notification_mute_account, webview_notification_get_bypass_prefs,
  webview_set_focused_account
- Wire window focus tracking in setup hook via on_window_event Focused handler
- Frontend: add setAccountMuted, setGlobalDnd, getBypassPrefs, setFocusedAccount
  helpers in webviewAccountService; sync focused account on open + click
- Add NotificationsPanel settings page with Global DND toggle
- Register NotificationsPanel at /settings/notifications

Closes #679

* feat(notifications): integrate notifications feature into app

- Added Notifications page and routing to AppRoutes.
- Introduced NotificationRoutingPanel in Settings for managing notification settings.
- Updated SettingsHome to include navigation for notification routing.
- Integrated notifications reducer into the store for state management.
- Enhanced Rust backend to support notification handling from embedded webviews.

This commit lays the groundwork for a comprehensive notification system within the application.

* refactor(notifications): clean up code formatting and structure

- Simplified JSX structure in NotificationCard for better readability.
- Consolidated fetchNotifications call in NotificationCenter for cleaner syntax.
- Improved formatting in NotificationRoutingPanel and notificationsSlice for consistency.
- Enhanced Rust code readability by streamlining function signatures and logic.

These changes enhance code maintainability and readability across the notifications feature.

* refactor(webview_accounts): simplify webview_notification_set_dnd function signature

- Removed unnecessary line breaks in the webview_notification_set_dnd function for improved readability.

* feat(notifications): implement provider-level notification settings management

- Added `getNotificationSettings` and `setNotificationSettings` functions to manage notification settings for providers.
- Enhanced `NotificationRoutingPanel` to display and update settings for Gmail, Slack, Discord, and WhatsApp.
- Introduced new RPC endpoints for retrieving and updating notification settings.
- Updated database schema to store notification settings persistently.

This commit establishes a robust system for managing notification preferences, improving user control over notifications.

* refactor(notifications): improve code formatting and readability

- Enhanced formatting in NotificationRoutingPanel for better clarity.
- Streamlined function signatures in notificationService and Rust backend.
- Improved readability of assertions in tests by adjusting line breaks.

These changes contribute to a more maintainable and comprehensible codebase for the notifications feature.

* chore(vendor): bump tauri-cef to fix Slack notification permission banner

Updates the tauri-cef submodule to 55db2d6 which adds a
navigator.permissions.query shim in the CEF render process. Slack checks
this API (not just Notification.permission) to decide whether to show its
"needs your permission" banner — the shim returns "granted" for
notifications queries so the banner no longer appears.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(vendor): bump tauri-cef for cargo fmt fixes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(vendor): bump tauri-cef — native V8 permissions.query shim

Switches from context.eval() to a proper PermissionsQueryV8Handler so
the navigator.permissions.query fix actually runs in on_context_created.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(notifications): patch navigator.permissions.query in ua_spoof.js

The V8 set_value_bykey approach in cef-helper's on_context_created does
not stick on CEF platform objects (Chromium's V8 binding layer silently
ignores property writes on native wrappers like Permissions). The init
script path via frame.execute_java_script runs in the fully-initialised
JS context where navigator.permissions IS writable, matching how
ua_spoof.js already overrides navigator.userAgent successfully.

Slack checks navigator.permissions.query({ name: 'notifications' })
before showing its "needs permission" banner — patching it here to
return "granted" removes the banner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(notifications): use Object.defineProperty to shim navigator.permissions

Two-layer fix for the Slack "needs permission to enable notifications" banner:

1. cef-helper (submodule update to 99a2686): context.eval() in
   on_context_created installs Object.defineProperty(navigator, 'permissions',
   ...) before any page JS runs.

2. ua_spoof.js: same Object.defineProperty pattern as belt-and-suspenders
   for frames that reload or trigger permission checks after on_load_end.

Simple property assignment on Blink platform objects is silently ignored;
Object.defineProperty on the navigator wrapper itself (the same mechanism
already used for navigator.userAgent) works correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(notifications): address CodeRabbit review issues on PR #727

- Move raw_title out of log::info! (PII risk) — log title_chars at info,
  raw_title at debug only
- Fix permissionChecked set before async invoke in ensureNotificationPermission
  so transient failures allow retry on next account open

* fix(cef): enable webview-data-url feature for CEF placeholder URL

The CEF backend uses a data: URL as the initial webview location so CDP
can attach before the real provider URL loads. Tauri's add_child rejects
data: URLs unless the webview-data-url feature is enabled.

* fix(notifications): address remaining CodeRabbit issues on PR #727

- cdp/emulation: bump Chrome UA 124→136 to pass Slack browser check
- cdp/session: inject Page.addScriptToEvaluateOnNewDocument to stub
  Notification.permission as "granted" and silence provider banners
- notifications/mod.rs + core/all.rs: wire notifications domain into
  the controller registry (fixes unknown-method in json_rpc_e2e tests)
- notifications/schemas: add skipped bool output to ingest schema
- notifications/store: add tracing::warn on datetime parse failure
- notificationService: union return type for ingestNotification
- webviewAccountService: narrow union before accessing result.id
- NotificationCenter: drive loading/error from fetch effect; track
  allProviders separately so filter pills don't collapse on selection
- NotificationRoutingPanel: rollback optimistic update on save failure
- useSettingsNavigation: add notifications/notification-routing routes
- scripts/install.sh: remove silent dry-run exit 0 on asset failure
- scripts/setup-dev-codesign.sh: remove unconditional -legacy flag
- docs/SUMMARY.md: remove worktree path, fix macOS capitalisation,
  remove self-referential deletion note

* chore: apply prettier + cargo fmt + fix useEffect dep warning

Auto-apply formatting changes flagged by the pre-push hook:
- prettier reformatted NotificationCenter.tsx and notificationService.ts
- cargo fmt reformatted all.rs, openhuman/mod.rs, notifications/schemas.rs
- NotificationRoutingPanel: move providers array to module scope so
  useEffect dependency array is satisfied without exhaustive-deps warning

* feat(notifications): enhance notification management and permissions

- Added new commands for managing notification preferences, including setting global Do Not Disturb (DND), muting specific accounts, and retrieving current bypass preferences.
- Implemented a notification permission state handler to ensure consistent behavior across different environments.
- Updated the JavaScript shim for notification permissions to handle both Notification and PushManager states, ensuring compatibility with various providers.
- Refactored the WebviewAccountsState to include a new structure for managing notification bypass preferences, improving the overall notification handling logic.

* update agents

* fix(notifications): complete schema + navigation metadata for ingest/settings routes

- app/src/components/settings/hooks/useSettingsNavigation.ts: resolve the
  new `/settings/notifications` and `/settings/notification-routing` URLs
  to their SettingsRoute values and feed them into breadcrumbs so the new
  panels don't silently fall through to `'home'`. Addresses CodeRabbit on
  useSettingsNavigation.ts:34.
- src/openhuman/notifications/schemas.rs: add the optional `reason` output
  on `notification.ingest` (populated alongside `skipped=true` by the
  runtime) and the normalized `settings` output on `notification.settings_set`
  so schema-driven clients see the full response shape. Addresses
  CodeRabbit on schemas.rs:103 and schemas.rs:217.
- src/core/all.rs: add a `notification` namespace_description so CLI help
  covers the new controllers, plus a test assertion. Addresses CodeRabbit
  on src/core/all.rs:149.

* fix(notifications): trace DB entry, surface empty update matches, warn on bad scored_at

- Add `tracing::trace!` checkpoints around the `with_connection` DB open
  and schema migration so notification-delivery issues are reconstructible
  from logs.
- `update_triage` and `mark_read` now inspect `Connection::execute`'s
  affected-row count: log a `warn!` when the update matched zero rows
  (row deleted between ingest and scoring / client passed a stale id),
  `debug!` on the normal path.
- `scored_at` parsing no longer silently drops malformed values — log a
  `warn!` with the raw value and parse error before treating the row as
  unscored, matching the existing behavior for `received_at`.

Addresses CodeRabbit on store.rs (lines 72, 172, 294).

* fix(webview): respect silent notifications, multi-host CDP fallback, shim idempotency

- webview_accounts/mod.rs: honor the Web Notification `silent` flag.
  Previously we only logged it and still called `builder.show()`, so
  pages that marked a notification silent still produced an OS toast.
  Mirror event still fires so the in-app center updates; only the OS
  toast is suppressed. Also picks up a prior cargo-fmt rewrap.
- cdp/target.rs: `browser_ws_url()` now continues the host loop when
  `resp.json()` fails instead of early-returning via `?`. A malformed
  response from the first host (CDP_HOST) no longer prevents the
  `localhost` fallback from being tried.
- webview_accounts/ua_spoof.js: guard the Notification wrapper behind
  `window.__OH_NOTIF_SHIM` so repeated evaluations of the script
  (Page.addScriptToEvaluateOnNewDocument + frame-level re-injections)
  don't stack wrappers onto the same page globals or re-proxy
  `Function.prototype.toString`.

Addresses CodeRabbit on webview_accounts/mod.rs:377, cdp/target.rs:33,
and ua_spoof.js:176.

* update agents

* update

---------

Co-authored-by: oxoxDev <nikhil@tinyhumans.ai>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-22 14:13:35 -07:00
5fff5568d3 feat(memory): Phase 2 memory tree - preprocessing, scoring, admission gate (#708) (#733)
* feat(memory): phase 1 memory tree - multi-source ingestion & canonical chunks (#707)

Adds an isolated memory tree layer under src/openhuman/memory/tree/
implementing Phase 1 of the new memory architecture (umbrella #711).
Zero edits to existing memory/*.rs files - the new layer coexists
with the legacy TinyHumans-backed client.

- Source adapters: chat / email / document -> canonical Markdown
- Token-bounded chunker with deterministic SHA-256 chunk IDs
- SQLite persistence at <workspace>/memory_tree/chunks.db with full
  provenance metadata (source_kind, source_id, owner, timestamps,
  tags, time_range) and back-pointer to raw source
- Unified JSON-RPC ingest (dispatches on source_kind + JSON payload):
  openhuman.memory_tree_ingest, _list_chunks, _get_chunk
- DataSource enum covering the 8 providers from m.excalidraw step 1
  (Discord/Telegram/Whatsapp/Gmail/OtherEmail/Notion/MeetingNotes/DriveDocs)
- ~40 unit tests (chunk ID stability, UTF-8-safe splitting,
  canonicalisation idempotence, store round-trip, filter behavior)

Additive only: new tables in a new DB file, new JSON-RPC namespace,
no existing behavior changes. Feeds #708 (scoring), #709 (summary
trees), #710 (query tools).

Closes #707. Parent: #711.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(memory): phase 2 memory tree - preprocessing, scoring, admission gate (#708)

Adds the scoring / admission layer between Phase 1's chunker and store.
Stacked on feat/707-memory-ingestion (PR #732) - depends on Phase 1's
chunk substrate.

- Pluggable EntityExtractor trait + CompositeExtractor chain
- RegexEntityExtractor: mechanical entities (emails, URLs, @handles, #hashtags)
  - Always on, deterministic, zero deps, UTF-8-safe char spans
- Five weighted signals: token count, unique-word ratio, metadata weight,
  source weight (per-DataSource), interaction (reply/sent/mention/dm tags),
  entity density
- Exact-match entity canonicalisation (email lowercased, @ and # stripped)
- Admission gate drops chunks below configurable threshold (default 0.3)
  - Score rationale persists for EVERY chunk (kept or dropped) for debugging
  - Entities indexed for KEPT chunks only
- Two new SQLite tables added to the memory_tree DB:
  - mem_tree_score: per-chunk score rationale with all signal values
  - mem_tree_entity_index: inverted index entity_id -> node_id
- Idempotent ALTER TABLE migration adds embedding BLOB column to
  mem_tree_chunks (used in Phase 3 retrieval, wired but not populated here)
- Ingest pipeline converted to async to accommodate the extractor trait;
  blocking SQLite work isolated on spawn_blocking; JSON-RPC surface
  unchanged (same memory_tree_ingest / list / get methods)
- Phase 2 deliberately ships without GLiNER/semantic NER - per-chunk
  semantic entities land later behind a cargo feature flag; the composite
  extractor interface keeps that drop-in trivial

Additive only: new tables, new columns, new module. Existing Phase 1
behavior unchanged except that low-signal chunks are now dropped before
reaching mem_tree_chunks. Raise score_drop_threshold to 0 to disable
the gate and restore Phase-1-identical behavior.

Closes #708. Parent: #711. Depends on: #707 (#732).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Fix memory tree scoring persistence issues

* Fix memory tree scoring robustness issues from PR review

- ingest: fail fast if scorer returns fewer/more results than chunks
  (silent zip truncation would drop chunks or their score rationale)
- score::persist_score{,_tx}: clear stale entity-index rows before
  re-indexing a re-scored chunk, since INSERT OR REPLACE never deletes
  rows whose entity_id is no longer in the new extraction
- score::store::lookup_entity: clamp limit to i64::MAX before casting
  to prevent a large usize wrapping into a negative LIMIT

Adds clear_entity_index_drops_stale_rows regression test.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-21 16:17:27 -07:00
0ce1253fe1 feat(memory): Phase 1 memory tree - multi-source ingestion & canonical chunks (#707) (#732)
* feat(memory): phase 1 memory tree - multi-source ingestion & canonical chunks (#707)

Adds an isolated memory tree layer under src/openhuman/memory/tree/
implementing Phase 1 of the new memory architecture (umbrella #711).
Zero edits to existing memory/*.rs files - the new layer coexists
with the legacy TinyHumans-backed client.

- Source adapters: chat / email / document -> canonical Markdown
- Token-bounded chunker with deterministic SHA-256 chunk IDs
- SQLite persistence at <workspace>/memory_tree/chunks.db with full
  provenance metadata (source_kind, source_id, owner, timestamps,
  tags, time_range) and back-pointer to raw source
- Unified JSON-RPC ingest (dispatches on source_kind + JSON payload):
  openhuman.memory_tree_ingest, _list_chunks, _get_chunk
- DataSource enum covering the 8 providers from m.excalidraw step 1
  (Discord/Telegram/Whatsapp/Gmail/OtherEmail/Notion/MeetingNotes/DriveDocs)
- ~40 unit tests (chunk ID stability, UTF-8-safe splitting,
  canonicalisation idempotence, store round-trip, filter behavior)

Additive only: new tables in a new DB file, new JSON-RPC namespace,
no existing behavior changes. Feeds #708 (scoring), #709 (summary
trees), #710 (query tools).

Closes #707. Parent: #711.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(memory): enhance memory tree functionality and tests

- Added support for "memory_tree" namespace description in `namespace_description`.
- Implemented clamping for zero token budget in `chunk_markdown` to prevent empty leading chunks.
- Introduced detailed logging for document ingestion, including title length.
- Updated output schemas in `schemas.rs` for improved clarity.
- Enhanced chunk listing with clamping limits and ordering by sequence in `list_chunks`.
- Normalized source references in canonicalization functions to drop blank values.
- Added comprehensive tests for new features and edge cases in chunking and canonicalization.

These changes improve the robustness and usability of the memory tree layer, aligning with ongoing development efforts for Phase 1 of the memory architecture.

* fix(memory): address follow-up CodeRabbit comments

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-04-21 14:40:27 -07:00