Repository navigation
Add EmbeddingsService gRPC: proto, daemon handler, Tauri proxy (closes #1135) - #1155
Conversation
Code Review SummaryThis PR successfully delivers the EmbeddingsService gRPC migration described in #1135. The architecture is sound: the proto definition is clean, the tonic handler follows the established Several issues need attention before merge, ranging from a hard startup failure to numeric type problems. FindingsCritical Issues[Critical/Blocker]
Either:
Option 1 is more consistent with the Tauri-side behavior. [Critical/Blocker]
The fix is to either restart Suggested Improvements[Improvement] Both RPCs call [Improvement]
[Improvement]
[Improvement] The old implementation returned [Improvement] The filename NitpicksNit: Nit: Nit: Requirements Validation
The two Critical issues mean the change is a net improvement in the happy path but introduces regressions in model-absent and database-switch scenarios. Recommend fixing both before merge. |
Critical fixes: - daemon/main.rs: ServiceBundle.embeddings_service_grpc is now Option<EmbeddingsServiceImpl>; daemon starts gracefully without the NLP model instead of returning Err. Both serve_headless and serve_grpc conditionally register EmbeddingsServiceServer only when the impl is present. - grpc_client.rs: GrpcClient now uses Arc<RwLock<GrpcClientInner>> for interior mutability. Added restart() method so switch_database_services can atomically replace channels with new database-backed services. settings.rs calls grpc_client.restart() after the AppServices swap. All command callers updated: client().await / embeddings_client().await. Suggested improvements: - embeddings_service.rs: Extract stale_count_inner() to eliminate duplicate store query logic in get_embedding_status and get_stale_count. Also fixes len() overflow via i32::try_from().unwrap_or(i32::MAX). - embeddings.rs: node_from_proto now emits tracing::warn! with node_id and raw timestamp when a node is dropped due to unparseable timestamps. - embeddings.rs: Add comment explaining why on_root_idle returns Ok(true) unconditionally. - grpc_client.rs: Compute has_embeddings bool before moving embeddings_impl into spawn closure; embeddings client is now gated on whether the server actually registered the service. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Review Findings Addressed (commit f53e25b)Critical FixesCritical #1 — Daemon crash when NLP model absent (
Critical #2 —
Suggested ImprovementsDRY: stale count logic (
Silent node drop warning (
Skipped (as instructed)
Build + Test Results |
…#1135) Defines EmbeddingsService in the nodespace proto with 7 RPCs (GetEmbeddingStatus, SearchSemantic, RegenerateEmbedding, QueueEmbedding, TriggerBatchEmbed, GetStaleCount, BatchQueueEmbeddings), implements the tonic handler in nodespaced wrapping NodeEmbeddingService and EmbeddingProcessor, and replaces all AppServices calls in commands/embeddings.rs with thin gRPC proxy calls via GrpcClient. GPU drain protocol (release_gpu_context) is now handled on daemon shutdown. EmbeddingState struct removed from AppServices; NodeEmbeddingService Arc retained there only for the local agent's GraphToolExecutor in-process use (avoids an extra gRPC round-trip for semantic skill injection). Co-Authored-By: Claude <noreply@anthropic.com>
Critical fixes: - daemon/main.rs: ServiceBundle.embeddings_service_grpc is now Option<EmbeddingsServiceImpl>; daemon starts gracefully without the NLP model instead of returning Err. Both serve_headless and serve_grpc conditionally register EmbeddingsServiceServer only when the impl is present. - grpc_client.rs: GrpcClient now uses Arc<RwLock<GrpcClientInner>> for interior mutability. Added restart() method so switch_database_services can atomically replace channels with new database-backed services. settings.rs calls grpc_client.restart() after the AppServices swap. All command callers updated: client().await / embeddings_client().await. Suggested improvements: - embeddings_service.rs: Extract stale_count_inner() to eliminate duplicate store query logic in get_embedding_status and get_stale_count. Also fixes len() overflow via i32::try_from().unwrap_or(i32::MAX). - embeddings.rs: node_from_proto now emits tracing::warn! with node_id and raw timestamp when a node is dropped due to unparseable timestamps. - embeddings.rs: Add comment explaining why on_root_idle returns Ok(true) unconditionally. - grpc_client.rs: Compute has_embeddings bool before moving embeddings_impl into spawn closure; embeddings client is now gated on whether the server actually registered the service. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
f53e25b to
87fe4e6
Compare
…#1135) (#1155) * Add EmbeddingsService gRPC: proto, daemon handler, Tauri proxy (closes #1135) Defines EmbeddingsService in the nodespace proto with 7 RPCs (GetEmbeddingStatus, SearchSemantic, RegenerateEmbedding, QueueEmbedding, TriggerBatchEmbed, GetStaleCount, BatchQueueEmbeddings), implements the tonic handler in nodespaced wrapping NodeEmbeddingService and EmbeddingProcessor, and replaces all AppServices calls in commands/embeddings.rs with thin gRPC proxy calls via GrpcClient. GPU drain protocol (release_gpu_context) is now handled on daemon shutdown. EmbeddingState struct removed from AppServices; NodeEmbeddingService Arc retained there only for the local agent's GraphToolExecutor in-process use (avoids an extra gRPC round-trip for semantic skill injection). Co-Authored-By: Claude <noreply@anthropic.com> * Address code review findings from PR #1155 Critical fixes: - daemon/main.rs: ServiceBundle.embeddings_service_grpc is now Option<EmbeddingsServiceImpl>; daemon starts gracefully without the NLP model instead of returning Err. Both serve_headless and serve_grpc conditionally register EmbeddingsServiceServer only when the impl is present. - grpc_client.rs: GrpcClient now uses Arc<RwLock<GrpcClientInner>> for interior mutability. Added restart() method so switch_database_services can atomically replace channels with new database-backed services. settings.rs calls grpc_client.restart() after the AppServices swap. All command callers updated: client().await / embeddings_client().await. Suggested improvements: - embeddings_service.rs: Extract stale_count_inner() to eliminate duplicate store query logic in get_embedding_status and get_stale_count. Also fixes len() overflow via i32::try_from().unwrap_or(i32::MAX). - embeddings.rs: node_from_proto now emits tracing::warn! with node_id and raw timestamp when a node is dropped due to unparseable timestamps. - embeddings.rs: Add comment explaining why on_root_idle returns Ok(true) unconditionally. - grpc_client.rs: Compute has_embeddings bool before moving embeddings_impl into spawn closure; embeddings client is now gated on whether the server actually registered the service. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Michael Libio <malibio@Michaels-Mac-mini.local> Co-authored-by: Claude <noreply@anthropic.com>
Summary
EmbeddingsServicein the nodespace proto with 7 RPCs (GetEmbeddingStatus, SearchSemantic, RegenerateEmbedding, QueueEmbedding, TriggerBatchEmbed, GetStaleCount, BatchQueueEmbeddings)NodeEmbeddingServiceandEmbeddingProcessorAppServicesdirect calls incommands/embeddings.rswith thin gRPC proxy calls viaGrpcClientrelease_gpu_context) handled on daemon shutdown;EmbeddingStatestruct removed fromAppServicesTest plan
cargo build --bin nodespacedpassesbun run test:allpassesbun run quality:fixpasses🤖 Generated with Claude Code