Skip to content

refactor(agent): unify AppFunction discovery, input conversion, and execution - #65

Merged
mingweiliao merged 2 commits into
android:mainfrom
juliantoledo:refactor/tool-discovery-execution
Oct 29, 2026
Merged

mingweiliao merged 2 commits into
android:mainfrom
juliantoledo:refactor/tool-discovery-execution

Conversation

@juliantoledo

@juliantoledo juliantoledo commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Refactors AppFunction tool discovery, remote file resolution, URI permission granting, and execution out of AgentOrchestrator into shared use cases so chat orchestration, debugging, and upcoming live voice orchestration share a unified pipeline.

Part 1 of 5 splitting #61 into smaller, independently reviewable PRs:

  1. Refactor tool discovery and execution (this PR)
  2. Live LLM provider abstraction & Gemini Live WebSocket implementation
  3. Full-duplex Live audio capture & playback (LiveAudioSession)
  4. Live session orchestration (LiveAgentOrchestrator)
  5. VoiceInteractionService, floating Live overlay, and app UI entry points

Key Changes

  • Unified AppFunction observation with filter parameters (GetAppFunctionsUseCase & GetAppFunctionsParams):

    • Evolved GetAppFunctionsUseCase.invoke(params: GetAppFunctionsParams) to accept nullable/optional filters (targetPackageNames, isEnabled, isConnected, includeInternalTools) composed via Flow operators (observeExternalFunctions, filterByConnection, filterByEnabledState) and merged with getInternalFunctions.
    • Updated external-app-only callers (GetConnectedAppsUseCase, TroubleshootAppUseCase, AgentDemoViewModel, DebuggingViewModel) to pass includeInternalTools = false.
  • Remote file reference download use case (ResolveRemoteFileToLocalUriUseCase & FileDownloadHelper):

    • Added FileDownloadHelper (FileDownloadHelperImpl bound in DataModule) and ResolveRemoteFileToLocalUriUseCase so callers (AgentOrchestrator) can chain remote http:// / https:// file reference resolution before calling ConvertInputToAppFunctionDataUseCase.
  • Recursive URI permission granting & internal tool execution (GrantAppFunctionUriPermissionsUseCase, AgentInternalTools, & ExecuteAppFunctionUseCase):

    • Extracted GrantAppFunctionUriPermissionsUseCase to recursively traverse AppFunctionData parameters and grant FLAG_GRANT_READ_URI_PERMISSION on content:// URIs to the target package.
    • Added AgentInternalTools.executeInternalTool(function, parameters) to encapsulate internal tool dispatch and result mapping.
    • Evolved ExecuteAppFunctionUseCase(function, parameters, threadId) to delegate internal tools to AgentInternalTools.executeInternalTool and invoke GrantAppFunctionUriPermissionsUseCase before executing external AppFunctions.
  • Simplified AgentOrchestrator & Expanded Tests:

    • Removed ~340 lines of inline tool-discovery, remote-file resolution, URI-granting, and internal-tool dispatch logic from AgentOrchestrator.
    • Added and updated unit and instrumented test coverage in GetAppFunctionsUseCaseTest (unit & androidTest), ResolveRemoteFileToLocalUriUseCaseTest, ConvertInputToAppFunctionDataUseCaseTest, GrantAppFunctionUriPermissionsUseCaseTest, ExecuteAppFunctionUseCaseTest, AgentInternalToolsTest, AgentOrchestratorTest, GetConnectedAppsUseCaseTest, AgentDemoViewModelTest, and DebuggingViewModelTest.

Verification

  • ./gradlew spotlessCheck
  • ./gradlew testStandardDebugUnitTest testRetailDebugUnitTest
  • ./gradlew compileStandardDebugAndroidTestKotlin compileStandardDebugScreenshotTestKotlin assembleStandardDebug

…xecution

Extract shared tool discovery, input conversion, and execution logic out of AgentOrchestrator into the core AppFunction use cases so chat, debugging, and future live voice orchestration share a single pipeline:

- Evolve GetAppFunctionsUseCase with GetAppFunctionsParams (targetPackageNames, isEnabled, isConnected, includeInternalTools) and expose shared internal package metadata in AgentInternalTools.
- Evolve ConvertInputToAppFunctionDataUseCase to resolve remote HTTP/HTTPS file reference URLs into local FileProvider content:// URIs during conversion to AppFunctionData.
- Evolve ExecuteAppFunctionUseCase to dispatch internal agent tools directly from AppFunctionData and recursively grant content:// read URI permissions to target packages before executing external AppFunctions.
- Update AgentOrchestrator and existing external-app-only callers (GetConnectedAppsUseCase, TroubleshootAppUseCase, AgentDemoViewModel, DebuggingViewModel) and expand unit/instrumented test coverage.
@juliantoledo
juliantoledo requested a review from a team as a code owner October 27, 2026 20:04
@juliantoledo juliantoledo mentioned this pull request Oct 27, 2026
… PR review

- Extract ResolveRemoteFileToLocalUriUseCase and FileDownloadHelper / FileDownloadHelperImpl out of ConvertInputToAppFunctionDataUseCase, chaining them in AgentOrchestrator.
- Move executeInternalTool into AgentInternalTools so internal tool mapping stays encapsulated.
- Extract GrantAppFunctionUriPermissionsUseCase out of ExecuteAppFunctionUseCase, removing runCatching around AppFunctionData getters, replacing .let with explicit locals, and using try/catch for grantUriPermission.
- Refactor GetAppFunctionsUseCase into Flow operators (observeExternalFunctions, filterByConnection, filterByEnabledState) merging getInternalFunctions at the end.
- Move nonNullArguments and extractMessageAttachment into AgentOrchestrator and update AgentOrchestratorTest to mock GetAppFunctionsUseCase directly.
@mingweiliao
mingweiliao merged commit ba0d895 into android:main Oct 29, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants