Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/types/src/deployment-configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export type ClientDeploymentConfiguration = {
MEASUREMENT_ID?: string;
BACKEND_API_ENDPOINT?: string;
ENVIRONMENT_NAME?: string;
ENABLE_NEW_URL_SCHEME?: boolean;
ENABLE_SHARING_2?: boolean;
GOOGLE_OAUTH_TOKEN_ENDPOINT?: string;
GOOGLE_OAUTH_AUTH_ENDPOINT?: string;
Expand All @@ -35,7 +34,7 @@ export type ClientDeploymentConfiguration = {
* value is "false"
*/
ALLOW_3P_MODULES?: boolean;
ENABLE_EMAIL_OPT_IN?: boolean;

FAKE_MODE?: boolean;
SHARE_SURFACE_URL_TEMPLATES: Record<string, string>;
domains?: Record<string, DomainConfiguration>;
Expand Down
43 changes: 2 additions & 41 deletions packages/types/src/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,7 @@ export type RuntimeFlags = {
* Enables output templates for consistent output.
*/
outputTemplates: boolean;
/**
* Requres users consent to use of get_webpage tool
*/
requireConsentForGetWebpage: boolean;
/**
* Requres users consent to use of open_webpage tool
*/
requireConsentForOpenWebpage: boolean;
/**
* Enables SSE streaming for planner calls.
*/
streamPlanner: boolean;
/**
* Enables SSE streaming for GenerateWebpage (output node HTML generation).
*/
streamGenWebpage: boolean;
/**
* Enables the "Add from Drive" option in lite mode (it is always enabled in
* non-lite mode).
*/
enableDrivePickerInLiteMode: boolean;

/**
* Enables "export to Drive" capability for the agent
*/
Expand Down Expand Up @@ -159,26 +139,7 @@ export const RUNTIME_FLAG_META: Record<keyof RuntimeFlags, RuntimeFlagMeta> = {
title: "Output Templates",
description: "Enable output templates for consistent output",
},
requireConsentForGetWebpage: {
title: "Consent for Get Webpage",
description: "Require user consent to use the get_webpage tool",
},
requireConsentForOpenWebpage: {
title: "Consent for Open Webpage",
description: "Require user consent to use the open_webpage tool",
},
streamPlanner: {
title: "Stream Planner",
description: "Enable SSE streaming for planner calls",
},
streamGenWebpage: {
title: "Stream Generate Webpage",
description: "Enable SSE streaming for HTML generation",
},
enableDrivePickerInLiteMode: {
title: "Drive Picker (Lite Mode)",
description: "Enable 'Add from Drive' in lite mode",
},

enableGoogleDriveTools: {
title: "Google Drive Tools",
description: "Enable 'export to Drive' capability",
Expand Down
11 changes: 3 additions & 8 deletions packages/unified-server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ export async function createClientConfig(opts: {
SHELL_GUEST_ORIGIN: flags.SHELL_GUEST_ORIGIN,
SHELL_HOST_ORIGINS: flags.SHELL_HOST_ORIGINS,
SHELL_PREFIX: flags.SHELL_PREFIX,
ENABLE_EMAIL_OPT_IN: flags.ENABLE_EMAIL_OPT_IN,

SHARE_SURFACE_URL_TEMPLATES: flags.SHARE_SURFACE_URL_TEMPLATES,
ENABLE_NEW_URL_SCHEME: flags.ENABLE_NEW_URL_SCHEME,

ENABLE_SHARING_2: flags.ENABLE_SHARING_2,
FAKE_MODE: flags.FAKE_MODE,
domains: flags.DOMAIN_CONFIG,
Expand All @@ -72,12 +72,7 @@ export async function createClientConfig(opts: {
opalAdk: flags.ENABLE_OPAL_ADK,
outputTemplates: flags.ENABLE_OUTPUT_TEMPLATES,
googleOne: flags.ENABLE_GOOGLE_ONE,
requireConsentForGetWebpage: flags.ENABLE_REQUIRE_CONSENT_FOR_GET_WEBPAGE,
requireConsentForOpenWebpage:
flags.ENABLE_REQUIRE_CONSENT_FOR_OPEN_WEBPAGE,
streamPlanner: flags.STREAM_PLANNER,
streamGenWebpage: flags.ENABLE_STREAM_GEN_WEBPAGE,
enableDrivePickerInLiteMode: flags.ENABLE_DRIVE_PICKER_IN_LITE_MODE,

enableGoogleDriveTools: flags.ENABLE_GOOGLE_DRIVE_TOOLS,
enableNotebookLm: flags.ENABLE_NOTEBOOK_LM,
enableResumeAgentRun: flags.ENABLE_RESUME_AGENT_RUN,
Expand Down
21 changes: 0 additions & 21 deletions packages/unified-server/src/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,8 @@ export const ENABLE_FORCE_2D_GRAPH: boolean = getBoolean(

export const ENABLE_SHARING_2: boolean = getBoolean("ENABLE_SHARING_2");

export const ENABLE_STREAM_GEN_WEBPAGE: boolean = getBoolean(
"ENABLE_STREAM_GEN_WEBPAGE"
);

export const ENABLE_AGENT_MODE: boolean = getBoolean("ENABLE_AGENT_MODE");

export const STREAM_PLANNER: boolean = getBoolean("ENABLE_STREAM_PLANNER");

export const OBSERVE_SYSTEM_THEME = getBoolean("OBSERVE_SYSTEM_THEME");

export const ENABLE_CONSISTENT_UI: boolean = getBoolean("ENABLE_CONSISTENT_UI");
Expand Down Expand Up @@ -124,30 +118,15 @@ export const SHELL_HOST_ORIGINS = getStringList("SHELL_HOST_ORIGINS");

export const SHELL_PREFIX = getString("SHELL_PREFIX");

export const ENABLE_EMAIL_OPT_IN = getBoolean("ENABLE_EMAIL_OPT_IN");

export const ENABLE_OPAL_ADK = getBoolean("ENABLE_OPAL_ADK");

export const ENABLE_OUTPUT_TEMPLATES = getBoolean("ENABLE_OUTPUT_TEMPLATES");

export const ENABLE_GOOGLE_ONE = getBoolean("ENABLE_GOOGLE_ONE");
export const ENABLE_REQUIRE_CONSENT_FOR_GET_WEBPAGE = getBoolean(
"ENABLE_REQUIRE_CONSENT_FOR_GET_WEBPAGE"
);

export const ENABLE_REQUIRE_CONSENT_FOR_OPEN_WEBPAGE = getBoolean(
"ENABLE_REQUIRE_CONSENT_FOR_OPEN_WEBPAGE"
);

export const ENABLE_NEW_URL_SCHEME = getBoolean("ENABLE_NEW_URL_SCHEME");

export const SHARE_SURFACE_URL_TEMPLATES =
(getJson("SHARE_SURFACE_URL_TEMPLATES") as Record<string, string>) ?? {};

export const ENABLE_DRIVE_PICKER_IN_LITE_MODE = getBoolean(
"ENABLE_DRIVE_PICKER_IN_LITE_MODE"
);

export const ENABLE_GOOGLE_DRIVE_TOOLS = getBoolean(
"ENABLE_GOOGLE_DRIVE_TOOLS"
);
Expand Down
136 changes: 3 additions & 133 deletions packages/visual-editor/src/a2/a2/html-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,134 +3,21 @@
*/

import { LLMContent, Outcome } from "@breadboard-ai/types";
import type {
ContentMap,
ExecuteStepRequest,
ExecuteStepArgs,
} from "./step-executor.js";
import { executeStep } from "./step-executor.js";
import { executeWebpageStream } from "./generate-webpage-stream.js";
import { encodeBase64, err, mergeContent, ok } from "./utils.js";
import { A2ModuleArgs } from "../runnable-module-factory.js";
import { createReporter } from "../agent/progress-work-item.js";
import { isInlineData } from "../../data/common.js";

export { callGenWebpage };

const OUTPUT_KEY = "rendered_outputs";

/**
* Legacy (non-streaming) implementation of GenerateWebpage.
*/
async function callGenWebpageLegacy(
moduleArgs: A2ModuleArgs,
instruction: string,
content: LLMContent[],
renderMode: string,
modelName: string
): Promise<Outcome<LLMContent>> {
const executionInputs: ContentMap = {};
const inputParameters: string[] = [];
let i = 0;
for (const val of content) {
if (!val.parts) continue;
for (const part of val.parts) {
i++;
if ("text" in part) {
const key = `text_${i}`;
inputParameters.push(key);
executionInputs[key] = {
chunks: [
{
mimetype: "text/plain",
data: encodeBase64(part.text),
},
],
};
} else if ("inlineData" in part) {
const key = `media_${i}`;
inputParameters.push(key);
executionInputs[key] = {
chunks: [
{
mimetype: part.inlineData.mimeType,
data: part.inlineData.data,
},
],
};
} else if ("storedData" in part) {
const key = `media_${i}`;
inputParameters.push(key);
let handle = part.storedData.handle;
if (handle.startsWith("drive:/")) {
const driveId = handle.replace(/^drive:\/+/, "");
handle = `https://drive.google.com/file/d/${driveId}/preview`;
}
executionInputs[key] = {
chunks: [
{
mimetype: "url/" + part.storedData.mimeType,
data: encodeBase64(handle),
},
],
};
} else {
console.error("Skipping unexpected content part");
}
}
}
const body = {
planStep: {
stepName: "GenerateWebpage",
modelApi: "generate_webpage",
inputParameters: inputParameters,
systemPrompt: "",
stepIntent: "",
output: OUTPUT_KEY,
options: {
disablePromptRewrite: true,
renderMode: renderMode,
modelName: modelName,
systemInstruction: instruction,
},
},
execution_inputs: executionInputs,
} satisfies ExecuteStepRequest;
// Add the contents
// TODO(askerryryan): Remove once functional.
console.log("request body");
console.log(body);
const reporter = createReporter(moduleArgs, {
title: `Calling generate_webpage`,
icon: "spark",
});
const args: ExecuteStepArgs = { ...moduleArgs, reporter };
const response = await executeStep(args, body, {
expectedDurationInSec: 70,
});
if (!ok(response)) {
let errorMessage;
if (response.$error.includes("The service is currently unavailable")) {
errorMessage =
"Request timed out. The model may be experiencing heavy load";
} else {
errorMessage = response.$error;
}
return err("Webpage generation failed: " + errorMessage);
}

return mergeContent(response.chunks, "model");
}

/**
* Main entry point for generating webpage HTML.
* Uses streaming API when streamGenWebpage flag is enabled.
* Always uses the streaming API.
*/
async function callGenWebpage(
moduleArgs: A2ModuleArgs,
instruction: string,
content: LLMContent[],
renderMode: string,
_renderMode: string,
modelName: string
): Promise<Outcome<LLMContent>> {
// If the content already contains HTML inlineData, pass it through
Expand All @@ -143,22 +30,5 @@ async function callGenWebpage(
}
}

const flags = await moduleArgs.context.flags?.flags();
const useStreaming = flags?.streamGenWebpage ?? false;

if (useStreaming) {
console.log("[html-generator] Using streaming API for GenerateWebpage");
return executeWebpageStream(moduleArgs, instruction, content, modelName);
} else {
console.log(
"[html-generator] Using legacy executeStep for GenerateWebpage"
);
return callGenWebpageLegacy(
moduleArgs,
instruction,
content,
renderMode,
modelName
);
}
return executeWebpageStream(moduleArgs, instruction, content, modelName);
}
18 changes: 8 additions & 10 deletions packages/visual-editor/src/main-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,14 @@ abstract class MainBase extends SignalWatcher(LitElement) {
}
});

if (this.sca.services.globalConfig.ENABLE_EMAIL_OPT_IN) {
this.sca.services.emailPrefsManager.refreshPrefs().then(() => {
if (
this.sca.services.emailPrefsManager.prefsValid &&
!this.sca.services.emailPrefsManager.hasStoredPreferences
) {
this.sca.controller.global.main.show.add("WarmWelcome");
}
});
}
this.sca.services.emailPrefsManager.refreshPrefs().then(() => {
if (
this.sca.services.emailPrefsManager.prefsValid &&
!this.sca.services.emailPrefsManager.hasStoredPreferences
) {
this.sca.controller.global.main.show.add("WarmWelcome");
}
});

// Admin — side-effect: exposes `window.o` when URL has #owner-tools.
new Admin(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ async function runBoard(): Promise<void> {

// b/452677430 - Check for consent before running shared Opals that
// use the get_webpage tool, as this could be a data exfiltration vector.
if ((await controller.global.flags.flags()).requireConsentForGetWebpage) {
{
const url = gc.url;
const boardServer = services.googleDriveBoardServer;
const isGalleryApp = url && boardServer.galleryGraphs.has(url);
Expand Down
Loading
Loading