Skip to content

feat: Add hybrid inference and structured output support to sample app#998

Draft
ryanwilson wants to merge 1 commit intomasterfrom
feature/hybrid-structured-output
Draft

feat: Add hybrid inference and structured output support to sample app#998
ryanwilson wants to merge 1 commit intomasterfrom
feature/hybrid-structured-output

Conversation

@ryanwilson
Copy link
Copy Markdown
Member

This PR updates the AI React sample app to support new features of the Firebase AI SDK, specifically Hybrid Inference and Structured Output.

Changes:

  • Hybrid Inference: Added UI controls (in RightSidebar) to toggle Hybrid Mode and select Inference Mode (Prefer On-Device, Only On-Device, etc.). Updated MainLayout and ChatView to pass these parameters to the SDK.
  • Model Download UI: Added a section in the sidebar to check the availability of the Chrome Prompt API model and a button to trigger the download if it is downloadable.
  • Structured Output: Added a JSON Schema textarea in the sidebar to allow users to provide a schema for structured JSON responses.
  • Model Updates: Updated the list of available generative models to the Gemini 2.5 series.

- Added InferenceMode controls in MainLayout and ChatView.
- Added JSON Schema textarea in RightSidebar and wired it to responseJsonSchema.
- Updated available model names to Gemini 2.5 series.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces Hybrid Mode, enabling on-device inference via Chrome's Prompt API alongside cloud-based inference. Key updates include a new UI in the sidebar for managing model status and inference preferences, a JSON schema editor for structured outputs, and updated model configurations in the service layer. The review feedback identifies critical issues with the Chrome Prompt API access path, redundant code assignments, and opportunities to improve maintainability through refactoring duplicated logic and enhancing type safety.

const checkModelAvailability = async () => {
setModelStatus("checking");
try {
const ai = (window as any).LanguageModel;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Chrome Prompt API is typically accessed via window.ai.languageModel. Accessing window.LanguageModel directly is likely to fail in standard Chrome environments, causing the availability check to incorrectly report the model as unavailable.

Suggested change
const ai = (window as any).LanguageModel;
const ai = (window as any).ai?.languageModel;

const handleDownloadModel = async () => {
setModelStatus("downloading");
try {
const ai = (window as any).LanguageModel;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the availability check, the model creation should use the window.ai.languageModel entry point to ensure compatibility with the Chrome Prompt API.

Suggested change
const ai = (window as any).LanguageModel;
const ai = (window as any).ai?.languageModel;

Comment on lines +213 to +214
nextState.generationConfig.responseJsonSchema = { type: "object", properties: {} }; // Default schema
nextState.generationConfig.responseSchema = undefined;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assignment to responseSchema on line 214 is redundant because it is performed again on line 217 within the same logical block. Removing the duplicate assignment improves code clarity.

Suggested change
nextState.generationConfig.responseJsonSchema = { type: "object", properties: {} }; // Default schema
nextState.generationConfig.responseSchema = undefined;
nextState.generationConfig.responseJsonSchema = { type: "object", properties: {} }; // Default schema

Comment on lines +486 to +497
try {
const schema = JSON.parse(e.target.value);
handleModelParamsUpdate((prev: ModelParams) => ({
...prev,
generationConfig: {
...prev.generationConfig,
responseJsonSchema: schema,
},
}));
} catch (err) {
// Ignore invalid JSON while typing
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The try-catch block silently ignores JSON parsing errors. While this prevents the application from crashing during typing, the user receives no feedback when their schema contains a syntax error. Consider adding a local state to track and display validation errors to the user for a better experience.

Comment on lines +100 to +104
const paramsToUse = isHybridMode ? {
mode: inferenceMode,
inCloudParams: params,
onDeviceParams: {}
} : params;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for constructing the hybrid parameters object is duplicated in three places within this file (initializeChatSession, handleChatSubmit, and the recovery block). Consider extracting this into a helper function to ensure consistency and improve maintainability.

inCloudParams: params,
onDeviceParams: {}
} : params;
const model = getGenerativeModel(aiInstance, paramsToUse as any);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using as any bypasses TypeScript's type safety. If the Firebase AI SDK supports hybrid inference, it should provide a specific type (e.g., HybridModelParams) for these parameters. Using the correct type will help prevent runtime errors if the parameter structure changes in future SDK versions.

@ryanwilson ryanwilson marked this pull request as draft April 28, 2026 13:58
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.

1 participant