Phase 4 complete: IToolRegistry AIDL + wire into RagService#1
Conversation
- core/java/android/rag/IToolRegistry.aidl — new public Binder interface
listTools(), getTool(id), searchTools(query) — all return JSON strings
- RagService: publish IToolRegistry as "jarvis_tools" service; add
mToolRegistryBinder implementing all three methods (listTools delegates
to ObjectBox, searchTools delegates to ToolDispatcher)
- ToolDispatcher: expose searchTools(String) publicly; add serializeTool()
and serializeTools() static helpers for JSON serialization of ToolRecord
(includes nested app: {packageName, appLabel, sourceType})
- ToolDefinition.java: deleted (tombstone, replaced by AppRecord+ToolRecord)
- Android.bp: add comment documenting objectbox-processor requirement for
AppRecord_/ToolRecord_ generated query classes
https://claude.ai/code/session_017yTYeGBpaNBdyZ4RP36Qp8
There was a problem hiding this comment.
Pull request overview
Adds a public Tool Registry Binder API and wires it into the existing RAG system service so clients can enumerate, fetch, and semantically search registered tools.
Changes:
- Introduces
android.rag.IToolRegistryAIDL withlistTools(),getTool(id), andsearchTools(query)returning JSON strings. - Publishes a new
"jarvis_tools"Binder service fromRagServicebacked by ObjectBox +ToolDispatcher. - Exposes
ToolDispatcher.searchTools()and adds JSON serialization helpers forToolRecord(including nestedappinfo).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
core/java/android/rag/IToolRegistry.aidl |
New public AIDL contract for tool registry access over Binder. |
services/core/java/com/android/server/rag/RagService.java |
Publishes the new "jarvis_tools" service and implements the registry methods. |
services/core/java/com/android/server/rag/tools/ToolDispatcher.java |
Adds public search API and JSON serialization helpers for tools. |
services/core/java/com/android/server/rag/Android.bp |
Documents ObjectBox annotation processor requirement. |
services/core/java/com/android/server/rag/tools/ToolDefinition.java |
Deletes obsolete tombstone file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @Override | ||
| public void onStart() { | ||
| publishBinderService("rag", mBinder); | ||
| publishBinderService("jarvis_tools", mToolRegistryBinder); |
There was a problem hiding this comment.
jarvis_tools is being published as a public Binder service, but enforceCallingPermission() currently only logs the caller UID and does not enforce any permission/allowlist. This effectively exposes the full tool registry (and semantic search) to any app on the device. Please enforce an appropriate signature/system permission (or otherwise restrict access) before exposing this service.
| publishBinderService("jarvis_tools", mToolRegistryBinder); | |
| Log.w(TAG, "Not publishing jarvis_tools Binder service: caller permission enforcement is not implemented"); |
| @Override | ||
| public String listTools() { | ||
| enforceCallingPermission(); | ||
| if (!JarvisStore.isReady()) return "[]"; | ||
| try { | ||
| java.util.List<ToolRecord> all = JarvisStore.box(ToolRecord.class).getAll(); | ||
| return ToolDispatcher.serializeTools(all); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
Binder transactions have a hard size limit (~1MB). Returning all tools as one JSON string (and including potentially large fields like rawDefinition/paramsJson) risks TransactionTooLargeException as the registry grows. Consider adding paging (offset/limit), a lightweight summary listing, and/or omitting large fields from listTools() results.
| * Apps use this to inspect what tools are registered on the device. | ||
| * | ||
| * All return values are JSON strings. Null = not found / store not ready. | ||
| */ |
There was a problem hiding this comment.
The AIDL docs say "All return values are JSON strings. Null = not found / store not ready", but listTools()/searchTools() are implemented to return "[]" when the store isn't ready or the query is empty. Please align the documentation with the actual contract (or change the implementation to match the docs).
| * Each element is a tool object: {id, toolName, description, paramsJson, | ||
| * receiverClass, cactusIndexId, app:{packageName, appLabel, sourceType}} |
There was a problem hiding this comment.
The documented JSON schema for tool objects doesn't match the current serialization: ToolDispatcher.serializeTool() includes rawDefinition and app.id, but the AIDL comment omits them. Please either update the AIDL documentation to include these fields (and clarify that paramsJson is itself a JSON-encoded string), or remove the extra fields from the serialized output to keep the public contract stable.
| * Each element is a tool object: {id, toolName, description, paramsJson, | |
| * receiverClass, cactusIndexId, app:{packageName, appLabel, sourceType}} | |
| * Each element is a tool object: | |
| * {id, toolName, description, paramsJson, rawDefinition, receiverClass, | |
| * cactusIndexId, app:{id, packageName, appLabel, sourceType}} | |
| * | |
| * Note: paramsJson is itself a JSON-encoded string, not an embedded JSON object. |
| /** Serialize a list of ToolRecords to a JSON array string. */ | ||
| public static String serializeTools(List<ToolRecord> tools) { | ||
| JSONArray arr = new JSONArray(); | ||
| for (ToolRecord t : tools) { | ||
| String json = serializeTool(t); | ||
| if (json != null) { | ||
| try { arr.put(new JSONObject(json)); } catch (JSONException ignored) {} | ||
| } | ||
| } |
There was a problem hiding this comment.
serializeTools() builds each element by calling serializeTool() (which produces a JSON string) and then immediately parsing that string back into a JSONObject. This adds avoidable overhead. Prefer constructing the JSONObject once (e.g., have serializeTool return a JSONObject or accept a JSONArray to append into) to avoid the stringify/parse roundtrip.
| /** | ||
| * Search for tools matching the query without dispatching. | ||
| * Returns up to TOP_K results as a JSON array string, or null on failure. | ||
| */ | ||
| public String searchTools(String query) { | ||
| if (query == null || query.trim().isEmpty()) return "[]"; | ||
| List<ToolRecord> results = semanticSearch(query); | ||
| return serializeTools(results); | ||
| } |
There was a problem hiding this comment.
The Javadoc says searchTools returns "null on failure", but the implementation always returns a JSON array string for non-empty queries (and will throw if an unexpected runtime exception occurs). Please update the comment to reflect the real behavior/contract (or handle exceptions and return a consistent failure value).
| import com.android.server.rag.indexing.JarvisFileObserver; | ||
| import com.android.server.rag.indexing.RagIndexWorker; | ||
| import com.android.server.rag.model.SourceFile; | ||
| import com.android.server.rag.tools.AppRecord; |
There was a problem hiding this comment.
Unused import: com.android.server.rag.tools.AppRecord is not referenced anywhere in this file. Please remove it to avoid unused-import lint/build failures and keep the imports accurate.
| import com.android.server.rag.tools.AppRecord; |
- IToolRegistry.aidl: fix return-value contract docs (listTools/searchTools
return "[]" not null; getTool returns null); update tool JSON schema to
include rawDefinition and app.id; note Binder size limitation + future
pagination TODO
- ToolDispatcher: extract serializeToolObject() returning JSONObject directly;
serializeTools() now appends JSONObject without stringify/parse roundtrip;
fix searchTools() Javadoc ("[]" not null on failure)
- RagService: remove unused AppRecord import
https://claude.ai/code/session_017yTYeGBpaNBdyZ4RP36Qp8
|
@copilot Claude addressed a few reviews from you and made changes. Kindly go through. Keep in mind we have various phases and we are using Agile methodology, hence some ideas may change after we have explored the other phases like Aent orchestration for Jarvis. |
listTools(), getTool(id), searchTools(query) — all return JSON strings
mToolRegistryBinder implementing all three methods (listTools delegates
to ObjectBox, searchTools delegates to ToolDispatcher)
and serializeTools() static helpers for JSON serialization of ToolRecord
(includes nested app: {packageName, appLabel, sourceType})
AppRecord_/ToolRecord_ generated query classes
https://claude.ai/code/session_017yTYeGBpaNBdyZ4RP36Qp8