GE Demo Generator Skill (v2.20.0)
Synthesizes production-grade, domain-tailored AI agent demo environments using Gemini 3.8 Flash for reasoning and Gemini 3.1 Flash Image for visual generation, adhering to a strict 6-step infrastructure dependency graph, rich A2UI interactive component streaming, Google Workspace OAuth authorization, external sample files staged in Cloud Storage and, when the credentials carry the Drive scope, in the deploying account's Google Drive, 7 structured demo prompts, automated browser video recording & Remotion highlight reel delivery to Google Drive, and global multilingual localization (i18n/l10n).
🌐 Multilingual Support & Localization Architecture (i18n/l10n)
The skill is implemented entirely in English at the system specification and codebase layer, while providing complete, dynamic multilingual support for any enterprise domain worldwide:
Automatic Language & Locale Detection:
- From Domain TLD:
.co.jp, .jp, .ne.jp, .or.jp ➔ Japanese (日本語, locale: "ja", currency: "JPY", symbol: "¥")
.de ➔ German (Deutsch, locale: "de", currency: "EUR", symbol: "€")
.fr ➔ French (Français, locale: "fr", currency: "EUR", symbol: "€")
.es ➔ Spanish (Español, locale: "es", currency: "EUR", symbol: "€")
.it ➔ Italian (Italiano, locale: "it", currency: "EUR", symbol: "€")
.cn, .tw ➔ Chinese (中文, locale: "zh", currency: "CNY"/"TWD")
.kr ➔ Korean (한국어, locale: "ko", currency: "KRW", symbol: "₩")
.br ➔ Portuguese (Português, locale: "pt", currency: "BRL", symbol: "R$")
.co.uk, .com.au, .com, .io, .org, etc. ➔ English (locale: "en", currency: "USD"/"GBP")
- From User Interaction:
- If the user provides a prompt in Japanese, all user-facing demo assets are synthesized in Japanese. If in German, all in German.
Strict Language Consistency Rule (MANDATORY):
- ALL user-facing text elements MUST strictly match the detected target language:
- Company overview & operational challenges.
- Table and column business descriptions (harvested into Knowledge Catalog).
- CSV string values (product names, category names, person names, address strings, remarks).
- External files: PDF title, body sections, audit summary tables; Excel headers, KPI cards, and notes; Scanned image prompts and handwritten ink text values.
- System instructions (
businessInstruction), Welcome Card greeting, and A2UI Button labels.
- The 7 Structured Demo Prompts (
demoGuide).
- Technical Names Isolation: Table names, column names, and primary/foreign key ID fields (e.g.
order_id, supplier_id) MUST always remain in English snake_case for database engine stability and SQL parser reliability.
- Currency symbol: write the detected symbol to
.env as CURRENCY_SYMBOL (e.g. CURRENCY_SYMBOL=¥). The A2UI few-shot examples ship with a literal [CURRENCY] placeholder instead of a hardcoded symbol; setup_and_deploy.sh substitutes it before the image is built and aborts the deploy if any occurrence survives. Defaults to $ when unset.
Complete Lifecycle & Infrastructure Dependency Graph
Phase 1: Customer Domain & Business Goal Research (Search Grounding & Language Detection)
↓
Phase 2: Requirements confirmed interactively ➔ Demo Architecture & Data Model Plan ➔ APPROVAL
↓
Phase 3: Synthetic Data & External Sample Files Generation (PDF, Excel, Images) + Google Drive Upload (Step 1/6)
↓
Phase 4: ADK Multi-Agent Project Scaffolding & A2UI System Prompts
↓
Phase 5: Ordered Cloud Provisioning & Deployment:
├── Step 1: BigQuery (with Knowledge Catalog Metadata) & Firestore Initial Data
├── Step 2: Agent Engine Sandbox (Code Execution Environment) [CRITICAL DEPENDENCY]
├── Step 3: Data Viewer Dashboard Cloud Run Deployment (Gets VIEWER_URL)
├── Step 4: Main Multi-Agent Cloud Run Deployment (Injects SANDBOX_RESOURCE_NAME & VIEWER_URL)
└── Step 5: Background Task Pub/Sub Push Subscription (/execute_task & SELF_URL)
↓
Phase 6: Gemini Enterprise App Discovery, Workspace Authorization & Registration (Step 6/6)
↓
Phase 7: Comprehensive Results Output:
├── 💬 Direct Gemini Enterprise Console Chat Link
├── 📁 External Sample Files: Cloud Storage links, plus Drive links when the upload ran
├── 📊 Firestore Data Viewer Dashboard Link
├── 🔎 BigQuery Console Link
└── 🎯 7 Structured Demo Prompts Playbook (Localized to Target Language)
↓
Phase 8: Automated Browser Demo Video Production & Drive Delivery (Optional)
├── Step 1: Playwright CDP Screen Recording of GE Web UI (Prompt 1, 3, 4)
├── Step 2: Google Cloud TTS Narration Audio & Subtitle Timecodes
├── Step 3: Remotion Programmatic Video Composition (Dynamic Camera, 4x Fast-Forward, Pure Voice Narration)
└── Step 4: Google Drive Upload to Demo Folder & Sharable Link
Phase 1: Customer Domain & Business Goal Research
Extract Domain & Company:
- If a domain is provided (e.g.,
example.com, example.co.jp, example.de), determine company name, primary industry, and regional language from the domain itself — never from a list baked into this skill.
- If a business goal or company name is provided, identify the corresponding corporate entity and language.
Grounded Deep Research (via search_web):
- Search for the company's latest corporate profile, business units, IR reports, and known operational challenges.
- Identify:
- 3-5 Key Business Challenges (e.g., "yield rate drop in semiconductor fabrication", "supply chain lead-time anomalies").
- 5-8 Operational Workflows and evaluate which ones are automatable with AI agents.
- Authentic Domain Entities & Nomenclature (e.g., real facility names like "Kumamoto Technology Center", actual product codes, industry status codes).
Interactive Use Case Selection (Customer Domain Selection Flow):
- Present the research findings to the user in their language:
- 🏢 Company Profile: Official name, summary, primary industry.
- ⚠️ Key Business Challenges: 3-5 detected operational pain points.
- 🎯 Candidate Workflows: 3-5 top automatable workflows with automation feasibility ratings.
- Prompt the user to select or customize the use case:
- Use
ask_question or present a structured choice so the user can pick the target scenario or write in specific requirements.
Phase 2: Requirements Alignment & Demo Architecture Plan (Approval Gate)
Phase 2 has two steps, in this order and never merged into one:
Step 2.1 — ask the handful of questions the design genuinely depends on, interactively.
Step 2.2 — show the finished design brief as the alignment artifact, and ask for a go.
The order is what makes the brief worth reading. A brief that still contains open questions
is a questionnaire, and the user has to hold the design in their head while answering it; a
brief written after the answers is a mirror — the user is checking whether what you
understood matches what they meant, which is a much easier thing to do and the last cheap
moment to change the entities, the narrative, the file lineage or the target project.
Until the user approves the brief, nothing is created — no CSVs, no Drive folder, no
BigQuery dataset, no Cloud Run service. Everything after this point takes 15-30 minutes and
spends real quota in someone's project.
Step 2.1 — Confirm the requirements interactively
Ask only what you cannot responsibly decide, and ask it before writing the brief. Keep it
short — two to four questions, batched into one message (ask_question where available), each
with a stated default so the user can answer "all defaults" in three words:
- Anchor persona — who is the primary user of this agent (job title, and a sentence of
context if useful)? That persona becomes the demo's protagonist: the agent is framed as
their process operator, prompt 1 opens from their daily situation, approval gates are
decisions they or their manager own, and every other persona appears only as a hand-off
counterpart. If the user declines, rotate personas freely instead.
- Scope of the narrative — which single process instance the demo follows, if Phase 1
left more than one plausible reading of the chosen scenario.
- Advanced settings — ask about the two or three the demo is a plausible candidate for
(Workspace OAuth when the scenario touches Gmail/Drive/Calendar,
rag when it turns on
documents rather than numbers, dataScale when the narrative claims enterprise volume),
and say the rest keep their defaults. Keep the question short — brief section 6 lists
every option with its resolved value, so nothing is hidden by asking about a few. Add
a warm Cloud Run instance (MIN_INSTANCES=1) to that question whenever the user has
named a date, an audience or a live session: it is the one option that is about the
presentation rather than the demo, and the only thing that removes the cold start — and
the occasional cold-start error — from the first message. Offer it with its price in the
same breath (see brief section 6).
- Target environment — only if what
gcloud reports (read it now, see below) is not
obviously the project the user means.
Anything the user has already stated — in the original request or in Phase 1 — is decided.
Re-asking it reads as not having listened.
Zero-Touch Environment, Project & IAM Pre-flight Probe:
Read and verify the target environment before writing the brief, ensuring zero-touch deployment readiness so the brief's section 5 states verified facts rather than unvalidated assumptions:
# 1. Target Project Synchronization: align project if specified by user
TARGET_PROJECT="${TARGET_PROJECT:-}"
CURRENT_PROJECT=$(gcloud config get-value project 2>/dev/null || echo "")
if [ -n "$TARGET_PROJECT" ] && [ "$CURRENT_PROJECT" != "$TARGET_PROJECT" ]; then
gcloud config set project "$TARGET_PROJECT" >/dev/null 2>&1 || true
fi
PROJECT_ID=$(gcloud config get-value project 2>/dev/null || echo "")
# 2. Account Verification & Auto-Discovery: probe project access; auto-switch if active account lacks access
GCP_ACCOUNT=$(gcloud config get-value account 2>/dev/null || echo "Unknown")
if ! gcloud projects describe "$PROJECT_ID" >/dev/null 2>&1; then
for acc in $(gcloud auth list --format="value(account)" 2>/dev/null); do
if gcloud projects describe "$PROJECT_ID" --account="$acc" >/dev/null 2>&1; then
gcloud config set account "$acc" >/dev/null 2>&1 || true
GCP_ACCOUNT="$acc"
break
fi
done
fi
PROJECT_NUMBER=$(gcloud projects describe "$PROJECT_ID" --format="value(projectNumber)" 2>/dev/null || echo "")
REGION=${CLOUD_RUN_REGION:-"asia-northeast1"}
# 3. Google Drive Scope Pre-flight
DRIVE_OK=$(curl -s -o /dev/null -w '%{http_code}' \
-H "Authorization: Bearer $(gcloud auth print-access-token 2>/dev/null)" \
'https://www.googleapis.com/drive/v3/about?fields=user')
DRIVE_OK is 200 when the Drive copy will happen, and the owner is ${GCP_ACCOUNT} — the
same account, because the upload uses this token. Anything else (usually 403, a token
carrying no Drive scope, which is what a plain gcloud auth login gives you) means this
demo will have no Google Drive copy of the sample documents at all. That is a fact the
brief has to state, not discover at deploy time — see brief sections 3 and 5. It is also one
command to fix, so say it now: gcloud auth login --enable-gdrive-access --no-launch-browser (using --no-launch-browser since an agentic IDE terminal usually has no local browser), then re-read.
Multi-OS Google Cloud Authentication & Setup Protocol
Before proceeding with deployment, verify both user CLI authentication (gcloud auth print-access-token) and Application Default Credentials (gcloud auth application-default print-access-token). If missing or expired:
Interactive TTY Mode ([ -t 0 ]): The script automatically detects the host OS environment, prints the tailored authentication commands, and pauses (read -p), allowing the user to authenticate in a separate terminal or browser window and resume seamlessly by pressing Enter.
Non-Interactive / CI Mode: Strictly fail-fast (Exit 1) with descriptive error logs and the single command to resume.
Host OS Detection & Authentication Matrix:
| Host OS / Environment |
Detection Signal |
Authentication Commands |
Notes |
| Linux / Remote VM (Headless) |
No $DISPLAY, SSH, or Cloud Shell |
gcloud auth login --enable-gdrive-access --no-launch-browsergcloud auth application-default login --no-launch-browsergcloud auth application-default set-quota-project $PROJECT_ID |
Copy verification URL to local browser, sign in, and paste auth code back. |
| macOS (Terminal / iTerm) |
uname -s == Darwin |
gcloud auth login --enable-gdrive-accessgcloud auth application-default logingcloud auth application-default set-quota-project $PROJECT_ID |
Browser opens automatically for OAuth consent. |
| Windows (WSL / WSL2) |
/proc/version contains microsoft or wsl |
gcloud auth login --enable-gdrive-accessgcloud auth application-default logingcloud auth application-default set-quota-project $PROJECT_ID |
If browser interop is disabled, append --no-launch-browser. |
| Linux Desktop (GUI) |
Linux with active $DISPLAY |
gcloud auth login --enable-gdrive-accessgcloud auth application-default logingcloud auth application-default set-quota-project $PROJECT_ID |
Browser opens automatically for OAuth consent. |
Quota Project Auto-Configuration: The deployment script and self-healing engine automatically execute gcloud auth application-default set-quota-project $PROJECT_ID to prevent HTTP 403 PERMISSION_DENIED: The discoveryengine.googleapis.com API requires a quota project.
Deployer IAM Audit & Autonomous Self-Healing Protocol
To guarantee a seamless zero-touch deployment, probe whether the deploying account ${GCP_ACCOUNT} possesses the necessary permissions on ${PROJECT_ID}:
- Owner / IAM Admin Auto-Healing:
- Check if
${GCP_ACCOUNT} is Project Owner, Editor, or has Project IAM Admin on ${PROJECT_ID}.
- If
${GCP_ACCOUNT} has IAM administrative privileges but lacks specific service roles (or if granular roles are in use), automatically grant missing deployment roles before starting deployment:
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="user:$GCP_ACCOUNT" \
--role="roles/run.admin" --condition=None
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="user:$GCP_ACCOUNT" \
--role="roles/discoveryengine.admin" --condition=None
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="user:$GCP_ACCOUNT" \
--role="roles/bigquery.admin" --condition=None
gcloud projects add-iam-policy-binding "$PROJECT_ID" \
--member="user:$GCP_ACCOUNT" \
--role="roles/iam.serviceAccountUser" --condition=None
Non-Admin Permission Denial Handling (Zero-Touch Guidance):
Capsule / Sandbox Policy Detection:
- If
${PROJECT_ID} starts with cpl-* or mpl-* (Google Cloud Capsule or restricted sandbox), inspect whether organizational policy constraints (such as constraints/run.allowedIngress or Service Directory restrictions) are active. Warn the user before data generation so expectations match sandbox capabilities.
Step 2.2 — Present the Demo Architecture & Data Model Plan
One message, six sections, in this order, then the gate. Every answer from Step 2.1 is already
folded in — the brief states decisions, it does not ask for them, and it contains no
"tell me which…" or "TBD" anywhere.
Write it in the demo's language (§ i18n above) — headings, table headers and prose alike.
Only the technical identifiers stay English snake_case: table names, column names and
.env keys.
Open with a title line naming the company and the selected scenario, so the brief is
self-contained when it is pasted into a chat with a colleague:
🏗️ <Company> — Demo Architecture & Data Model Plan
Based on the selected scenario "<scenario>", here is the data layer design, the
Mermaid ER diagram and the cross-source reconciliation lineage.
§ Brief section 1 — 🏢 Target Company & Demo Overview
- Company / group: official name, and the group entity the demo actually models.
- Industry: the specific one, in the company's own vocabulary.
- Demo narrative: 2-3 sentences following one business process instance (one
problematic order, one flagged application) end to end, naming the departments it passes
through. All 7 demo prompts later trace this same instance; see
references/demo_prompts_guide.md §1.1-§1.2.
- Anchor persona: the persona confirmed in Step 2.1, stated as a fact ("the agent is
operated by the production control manager of the main works"). If the user declined to
name one, say that personas rotate instead — do not re-ask here.
§ Brief section 2 — 📊 Data Layer Design & Mermaid ER Diagram
- Render a Mermaid
erDiagram in a ```mermaid fenced block: every table, every column
with its type, PK/FK markers, cardinality labels on each relationship, and a short
business gloss in quotes after each column (string order_id PK "order number (ORD-2026-XXXX)").
The gloss is the same sentence that later becomes the column description in the Knowledge
Catalog, so writing it here is not duplicated work.
- Include the Firestore task collection as an entity too — it is part of the model the demo
reasons over, even though it is not in BigQuery.
- Shared core-system model: design the tables as a slice of the company's system of
record, not one team's dataset — a transactional table two departments both write, a
rules/threshold table owned by one department that another's workflow must consult, and
an audit seed visible only when the departments' views are joined. Details and the
single-department escape hatch:
references/data_generation.md §1.3.
§ Brief section 3 — 📁 External Sample Files & Cross-Source Lineage
Title this section after where the files will actually be, not after where people assume they
go. Cloud Storage is the only guaranteed destination (below), so a heading that says "Google
Drive" is wrong in every run whose token lacks the Drive scope — and it was, in most of them.
A table with one row per external file — type, filename, and what binds it to BigQuery:
| External file |
Filename |
Content & data binding |
| 📄 PDF audit report |
<domain>_audit_report.pdf |
which tables it summarizes, and the deliberate 5-15% variance that makes cross-source reconciliation necessary |
| 📊 Excel ledger |
<domain>_external_ledger.xlsx |
which FK column it joins on, and the row count |
| 🖼️ Scanned form 1 |
handwritten_order_1.jpg |
what the form is, in-domain, generated by gemini-3.1-flash-image |
| 🖼️ Scanned form 2 |
handwritten_order_2.jpg |
the second form, and the discrepancy it carries |
State the join key explicitly. A lineage row that says "related to orders" is not a design —
the whole point of the external files is that a question can only be answered by reading a
document and querying a table, and that only works if the keys line up (70%+ FK match,
5-15% audit variance). See references/external_files_and_drive.md.
Close the section with where the files will actually live, in one line, because it is the
part users assume wrongly. Write the line that matches the DRIVE_OK read above:
DRIVE_OK |
The line to write |
200 |
Staged to gs://<project>-<domain>-<suffix>-docs/ and uploaded at deploy time to the Google Drive of ${GCP_ACCOUNT}, which owns the folder. |
| anything else |
Staged to gs://<project>-<domain>-<suffix>-docs/. No Google Drive copy — this machine's gcloud credentials carry no Drive scope, so a Drive or Sheets step in the demo script would find nothing. |
The Cloud Storage staging happens in both mcp and rag mode; the deploy-time upload is
the only path into any Drive. The deployed agent has no way to put them in anyone's Drive —
v2.11.0 removed the in-conversation import, deliberately. If the user wants them in Drive and
DRIVE_OK is not 200, say so here, while it can still be sorted out
(gcloud auth login --enable-gdrive-access --no-launch-browser and re-run, or upload ./external_files/ by hand
afterwards).
§ Brief section 4 — 🤖 Agent Profile & Runtime
- Agent Name (
DEMO_DISPLAY_NAME): Concise 2–4 word domain role (e.g. TWG Tea Retail Operations Director, Mercari Trust & Safety Specialist). Registered in Gemini Enterprise as ${DEMO_DISPLAY_NAME} (${SERVICE_NAME}), matching the Web UI (GAS) version.
- Description (
DEMO_DESCRIPTION): Concrete, professional 1–2 sentence mission summary specifying the business domain, core datasets, and operational goals (e.g. Orchestrates boutique inventory balancing, central commissary replenishment, and plantation harvest orders across Singapore.). Matches oneSentenceSummary in the Web UI (GAS).
- Reasoning / orchestration:
gemini-3.8-flash for all agent instances (Root Coordinator, Deep Analysis Sub-Agent, Background Worker).
- Image generation:
gemini-3.1-flash-image (with localized prompt reinforcement and GCS artifact persistence).
- Code execution: Agent Engine Sandbox (
us-central1 — fixed, not $REGION).
- UI: Gemini Enterprise A2UI v0.9 composite catalog (name the components this demo will actually lean on —
MaterialTable, VegaChart, MaterialCard).
§ Brief section 5 — ⚙️ Deployment Target Environment
Show what the commands above returned, verbatim, in a fenced block:
👤 Active User Account : ${GCP_ACCOUNT}
🏢 Target Project : ${PROJECT_ID} (${PROJECT_NUMBER})
🌐 Target Region : ${REGION}
🛡️ Deployer IAM Status : Verified (Owner/Admin) / Auto-healed
🗂️ Sample File Storage : gs://${PROJECT_ID}-<domain>-<suffix>-docs/
📁 Google Drive Copy : <the DRIVE_OK line, below>
This is the section users most often stop on, because the answer is frequently "wrong
project". Do not paraphrase the values and do not print a project the user named unless
gcloud agrees — the deploy will use what gcloud says, not what the brief claims.
Both storage lines are mandatory, and neither is optional wording: the Cloud Storage bucket is
created in every mode, and the Drive line is the one users read as a promise. Write it from
DRIVE_OK, never from intent:
DRIVE_OK |
📁 Google Drive Copy |
200 |
Google Drive of ${GCP_ACCOUNT} |
| anything else |
none - these credentials have no Drive scope (fix: gcloud auth login --enable-gdrive-access --no-launch-browser) |
Never print a Drive destination the deploy cannot reach, and never describe the copy as
something the agent will do later — nothing after the deploy writes to a Drive. See
references/external_files_and_drive.md §5.
§ Brief section 6 — 🎛️ Advanced Settings & Integrations
State the settings this demo will deploy with — the answers from Step 2.1, plus the
defaults for everything the user did not touch. These names are the .env keys,
upper-snake-cased: enableManagedAgent is ENABLE_MANAGED_AGENT. Every one of them is a
real switch in the deployed container, so an option discussed here but not written to
.env is a feature the demo will not have.
List all eleven, every time, in this order, with the value this deploy will use in the
second column — ✅ true / ❌ false / the literal value / — (unset). An option the
brief leaves out is an option the user cannot ask for: they do not know it exists, and by
the time the deploy banner mentions it the 15-30 minutes are already spent. The gate is the
last cheap moment to turn one on, so the gate has to show the whole board. Keep the third
column as written here — it is what makes a false decidable rather than merely visible —
and reword only where this demo's scenario changes what an option would buy.
| Option |
This demo |
Default |
What it buys, and what it costs |
🤖 enableManagedAgent |
<value> |
true |
Agent Engine Sandbox code execution, asynchronous background delegation (delegate_autonomous_task), scheduled tasks and Drive deliverable exports. The delegation prompts in the demo playbook exercise this, which is why it is the one default-on capability. Adds ~8-10 min of provisioning, overlapped with the rest of the deploy. |
📡 enableCloudTelemetry |
<value> |
true |
OpenTelemetry Cloud Trace instrumentation. Fully tracks per-turn LLM token consumption (input_tokens, output_tokens), latency breakdown waterfall, and tool execution. PII-safe via NO_CONTENT (zero chat prompt text transmitted), 0ms warm-turn overhead (async background batching), and free under monthly Cloud Trace quota. Set to false to opt out. |
🛡️ enableModelArmor |
<value> |
false |
Vertex AI Agent Platform Model Armor integration. Enforces prompt injection & jailbreak defense, automatic sensitive data protection (SDP credentials/PII masking), and RAI safety filters. Auto-provisions and binds ge-demo-default-armor in us-central1 if no custom template is specified. |
🔎 dataExplorationMode |
<value> |
mcp |
How the agent reads the demo's data. mcp (default) provisions no search index: the data-asset catalog is already in the agent's system instruction, so a figure question is one execute_sql call — the four-to-five round trips people blame on "no index" came from the metadata expedition in front of the query, and the mcp routing block overrides exactly that. rag additionally builds a Discovery Engine index over the BigQuery dataset and the staged files and makes it the read path: lookups and document questions return in one sub-second search_datastore call, while computed figures, joins and every write stay on MCP because the index lags the tables. Pick rag when the demo turns on documents rather than on numbers, and note it also attaches data stores to the (often shared) Gemini Enterprise app — see references/datastore_connectors.md. |
📁 enableDatastoreFs |
<value> |
false |
When dataExplorationMode=rag, provisions a semi-structured Discovery Engine DataStore (ds-${SERVICE_NAME}-fs) from FIRESTORE_COLLECTION via FirestoreSource (GCS export staging). Enables semantic search over historical incident tickets, resolved remediation logs, and SOP archives. Note: live task mutations, approvals, and Operations Viewer synchronization continue to use Firestore MCP for sub-100ms real-time state tracking. |
🔑 enableWorkspaceAuth |
<value> |
false |
User-OAuth passthrough — the agent acts as the signed-in user for the Drive handoff and Workspace token plumbing. Commonly wanted, since Workspace is usually available in the target environment, but not default-on: some organizations refuse to authorize an OAuth client they have not vetted, and there sign-in fails for every demo user. Confirm the target org permits it before enabling. |
🔑 enableWorkspaceMcp |
<value> |
false |
Advanced, rarely used. Adds the Gmail / Drive / Calendar / Docs / Chat MCP toolsets on top of the auth passthrough. The Workspace MCP servers are Developer Preview and the project must be allowlisted first — enable it without that and every Workspace call 403s. Kept separate from enableWorkspaceAuth for exactly this reason. |
🖥️ enableComputerUse |
<value> |
false |
Headless browser automation (Playwright). Also requires uncommenting the Playwright block in both requirements.txt and the Dockerfile; the deploy pre-flights this and refuses a half-configured build. |
📦 customMcpRepos |
<value> |
empty |
Third-party MCP servers. Both GitHub sidecars and remote managed servers (Slack included — it is one entry in this list, not a flag of its own) go here. |
🌐 publicDatasetId |
<value> |
unset |
Ground the demo in a real BigQuery public dataset (e.g. NOAA Weather, Google Trends) alongside the synthetic data. |
📈 dataScale |
<value> |
unset (hero rows only) |
Row count to grow the fact tables to before loading — thousands to tens of thousands. You still write only the 50-200 hero rows the demo script names; scripts/amplify_data.py expands the tables around them deterministically, keeping the hero rows verbatim and foreign keys intact. Ask for it when the narrative claims enterprise volume or the demo opens with an aggregate — a COUNT(*) of 63 undercuts both. Costs ~10-30s of setup and a longer Discovery Engine ingest. |
Only list the options that are on, plus the two or three the demo is a plausible candidate
for. A user reading eight defaults they did not ask about is a user who skims the whole brief.
One more switch, and it is deliberately not in that table — it is not an .env key and it
changes nothing inside the container. Cloud Run scales this demo to zero when nobody is talking
to it, which is why an idle demo costs nothing, and why the first message after an idle gap
waits ~20-25s for a cold start and can come back as an error instead: Cloud Run sometimes
refuses a request outright while the container is still starting. Deploying with
MIN_INSTANCES=1 — the environment variable setup_and_deploy.sh reads in Step 4/6, exported
before the deploy runs — keeps one instance always up and removes both.
State it as a line under the table when you offer it, with the price attached rather than in a
footnote:
🔥 Warm instance — MIN_INSTANCES=1 · default 0 (scale-to-zero). No cold start and no
cold-start error on the first message. Cost: one 8 GiB / 2 vCPU instance is then billed
continuously for as long as the demo exists — not just during the presentation.
The honest default is 0: for a demo deployed now and shown next week, sending the first
message twice is far cheaper than a week of idle billing. It is also not a decision that has to
be made now — it is read at deploy time, so re-running the deploy with the variable set (or
unset) flips an existing demo either way.
§ The gate — ask once, then stop
Close the message by triggering an interactive approval and option selection modal using the ask_question tool (with plain text fallback only if ask_question is not supported in the active environment). This allows the user to review all capabilities and toggle any extra features directly:
Call ask_question with is_multi_select: true:
question: "Do you approve this architecture and deployment plan? Select '(Recommended) Proceed with default configuration' to start deployment immediately, or check any additional options you want enabled:" (in the demo's language)
options:
"(Recommended) Proceed with default configuration (Managed Agent: Enabled, Cloud Trace Telemetry: Enabled, other options: default)"
"🛡️ Enable Model Armor Guardrails (Auto-provisions and binds ge-demo-default-armor in us-central1 for jailbreak defense and PII masking)"
"🔑 Enable Google Workspace OAuth (Drive/Slides/Docs export as signed-in user)"
"🔎 Enable RAG Data Exploration Mode (Build Discovery Engine search index for document & table reads)"
"📁 Enable Firestore DataStore (Semantic search over historical tickets & SOPs in RAG mode)"
"🔥 Enable Warm Instance (Cloud Run min-instances=1 to eliminate cold-start delay)"
"🖥️ Enable Computer Use (Gemini 3.8 Flash Chromium browser automation)"
"📈 Enable Enterprise Data Scale (Grow fact tables to thousands of rows via amplify_data.py)"
"📡 Disable Cloud Trace Telemetry (Opt-out from OpenTelemetry token & latency tracking)"
In non-interactive or headless environments where ask_question is unavailable, output the equivalent choices in chat text and pause for user reply.
When the user selects options, update .env (ENABLE_MODEL_ARMOR=1, ENABLE_WORKSPACE_AUTH=1, ENABLE_CLOUD_TELEMETRY=0, DATA_EXPLORATION_MODE=rag, etc.) and deployment flags accordingly before proceeding to Phase 3.
Then stop and wait. Do not start Phase 3 in the same turn, and do not treat "looks good" on
a previous message — the scenario choice in Phase 1 or an answer in Step 2.1 — as approval of
this brief.
When the user changes something, re-render the affected sections and ask again; an approved
brief is the specification the rest of the run is built from, so it has to be the version the
user actually said yes to.
Phase 3: Synthetic Data & External Sample Files Generation + Google Drive Upload
Entry condition: the Phase 2 brief was presented in full and the user approved it. If you
arrive here without that, go back and present it.
Derive the demo's identifiers, concrete name, and description:
SUFFIX=$(date +%s | tail -c 5)
DEMO_ID="${DOMAIN_SLUG}-${SUFFIX}"
SERVICE_NAME="ge-demo-${DOMAIN_SLUG}-${SUFFIX}"
DATASET_ID="demo_${DOMAIN_SLUG}_${SUFFIX}"
FIRESTORE_COLLECTION="demo-${DOMAIN_SLUG}-${SUFFIX}-tasks"
# Set concrete, domain-specific display name & description (matching Web UI / GAS version)
DEMO_DISPLAY_NAME="${COMPANY_NAME} ${AGENT_ROLE:-Operations Specialist}"
DEMO_DESCRIPTION="Orchestrates ${SCENARIO_SUMMARY:-operations and intelligent data analytics} across ${COMPANY_NAME}."
Always write DEMO_DISPLAY_NAME and DEMO_DESCRIPTION into .env so setup_and_deploy.sh and register_agent.py register the agent with concrete domain details.
Generate Real-World Synthetic Data & Display Previews:
- Generate CSV files with realistic addresses, valid foreign keys across tables, and varied statuses in
data/<table_name>.csv.
- Ensure all string data is generated in the detected target language.
- Run validation script:
python3 scripts/validate_csv.py data/*.csv.
- Render Dataset Preview & Record Counts: Output a Dataset Summary Table with total generated record counts for each BigQuery table, Firestore collection, and external Drive file, followed by 3–5 representative sample rows per table in clean Markdown preview tables (or
<carousel> sliders) clearly indicating the total row count in each table title.
- Write one line of grain per table into
data/<table_name>_description.txt ("one row per
POS transaction line", "one row per store"). The deploy folds it, the column
descriptions from data/<table_name>_schema.json, the row counts and the real date
range of every date column into adk_agent/app/data_assets.md — the DATA ASSET CATALOG
the agent's prompt is written around. Skipping the grain line costs only that line;
skipping the column descriptions costs the agent its schema.
2b. Amplify to Demo Volume (only when dataScale was agreed in Phase 2):
- Generate External Sample Files & Upload Directly to Google Drive:
- Synthesize external demo files in
./external_files/:
- PDF Audit Report (
<domain>_audit_report.pdf): Multi-section structured document in target language with summary, details, and intentional 5-15% variance from BigQuery to trigger cross-source reasoning.
- Excel Spreadsheet Ledger (
<domain>_external_ledger.xlsx): Semi-structured workbook with localized KPI headers, units, and 40-80 transaction rows with FK references matching BigQuery tables.
- Simulated Operational Document Images (
handwritten_order_1.jpg, handwritten_order_2.jpg): Realistic scanned forms generated via gemini-3.1-flash-image with localized text.
- Upload to Google Drive:
uv run --no-project \
--with "openpyxl>=3.1.0,<4.0.0" \
--with "reportlab>=4.0.0,<6.0.0" \
--with "pillow>=10.0.0,<13.0.0" \
python3 scripts/generate_and_upload_external_files.py \
--domain "$DOMAIN_SLUG" \
--company "$COMPANY_NAME" \
--suffix "$SUFFIX" \
--outdir "./external_files" \
--spec-file "./data/external_files_spec.json"
--spec-file carries THIS demo's content (titles, sections, table rows, and the
style wording for the scanned forms), written in the demo's own language and
domain. Without it the script emits generic placeholder documents - it holds no
built-in industry content by design.
- Creates dedicated Drive folder:
GE Demo - <Company Name> (<Suffix>), reusing one
of that name if a previous run already made it.
- Uploads
.pdf, .xlsx, and .jpg files.
- Saves links to
external_files/drive_upload_summary.json and creates .url.json artifacts.
- The folder is owned by
${GCP_ACCOUNT} — the upload is a Drive v3 REST call
carrying this machine's own gcloud access token, so the account deploying the
demo owns what it creates and nothing has to be shared with it. Report that owner
and the folder URL. The script also asks for "anyone with the link (Reader)" as a
convenience; plenty of organizations refuse it, in which case the summary carries
share_error and the banner notes ℹ️ LINK SHARING OFF — the owner can still open
everything, so this is a footnote, not a failure.
- When the token has n
…(truncated)
1---2name: ge-demo-generator3description: Synthesizes and deploys complete, domain-specific Gemini Enterprise demo environments directly to Google Cloud. Use when the user asks to create an AI agent demo for any customer domain (e.g. 'example.com', 'example.co.jp', 'example.de', 'example.fr' - any company, any industry, any region) or business goal, generate realistic BigQuery/Firestore sample datasets, create external demo files (PDF, Excel, scanned images), stage them in Cloud Storage and upload them to the deploying account's Google Drive, scaffold ADK multi-agent architectures with MCP tools and A2UI cards, deploy to Cloud Run, publish to Gemini Enterprise, and generate 7 structured demo prompts in any language. Confirms the requirements interactively and presents a demo architecture & data model plan (Mermaid ER diagram, external file lineage, target project) for approval before anything is deployed. Also triggered by /ge-demo-generator.4---56# GE Demo Generator Skill (v2.20.0)78Synthesizes production-grade, domain-tailored AI agent demo environments using **Gemini 3.8 Flash** for reasoning and **Gemini 3.1 Flash Image** for visual generation, adhering to a strict **6-step infrastructure dependency graph**, rich **A2UI interactive component streaming**, **Google Workspace OAuth authorization**, **external sample files staged in Cloud Storage and, when the credentials carry the Drive scope, in the deploying account's Google Drive**, **7 structured demo prompts**, **automated browser video recording & Remotion highlight reel delivery to Google Drive**, and **global multilingual localization (i18n/l10n)**.910---1112## 🌐 Multilingual Support & Localization Architecture (i18n/l10n)1314The skill is implemented entirely in **English** at the system specification and codebase layer, while providing **complete, dynamic multilingual support** for any enterprise domain worldwide:15161. **Automatic Language & Locale Detection**:17 - **From Domain TLD**:18 - `.co.jp`, `.jp`, `.ne.jp`, `.or.jp` ➔ Japanese (`日本語`, `locale: "ja"`, `currency: "JPY"`, `symbol: "¥"`)19 - `.de` ➔ German (`Deutsch`, `locale: "de"`, `currency: "EUR"`, `symbol: "€"`)20 - `.fr` ➔ French (`Français`, `locale: "fr"`, `currency: "EUR"`, `symbol: "€"`)21 - `.es` ➔ Spanish (`Español`, `locale: "es"`, `currency: "EUR"`, `symbol: "€"`)22 - `.it` ➔ Italian (`Italiano`, `locale: "it"`, `currency: "EUR"`, `symbol: "€"`)23 - `.cn`, `.tw` ➔ Chinese (`中文`, `locale: "zh"`, `currency: "CNY"/"TWD"`)24 - `.kr` ➔ Korean (`한국어`, `locale: "ko"`, `currency: "KRW"`, `symbol: "₩"`)25 - `.br` ➔ Portuguese (`Português`, `locale: "pt"`, `currency: "BRL"`, `symbol: "R$"`)26 - `.co.uk`, `.com.au`, `.com`, `.io`, `.org`, etc. ➔ English (`locale: "en"`, `currency: "USD"/"GBP"`)27 - **From User Interaction**:28 - If the user provides a prompt in Japanese, all user-facing demo assets are synthesized in Japanese. If in German, all in German.29302. **Strict Language Consistency Rule (MANDATORY)**:31 - ALL user-facing text elements MUST strictly match the detected target language:32 - Company overview & operational challenges.33 - Table and column business descriptions (harvested into Knowledge Catalog).34 - CSV string values (product names, category names, person names, address strings, remarks).35 - External files: PDF title, body sections, audit summary tables; Excel headers, KPI cards, and notes; Scanned image prompts and handwritten ink text values.36 - System instructions (`businessInstruction`), Welcome Card greeting, and A2UI Button labels.37 - The 7 Structured Demo Prompts (`demoGuide`).38 - **Technical Names Isolation**: Table names, column names, and primary/foreign key ID fields (e.g. `order_id`, `supplier_id`) MUST always remain in English `snake_case` for database engine stability and SQL parser reliability.39 - **Currency symbol**: write the detected symbol to `.env` as `CURRENCY_SYMBOL` (e.g. `CURRENCY_SYMBOL=¥`). The A2UI few-shot examples ship with a literal `[CURRENCY]` placeholder instead of a hardcoded symbol; `setup_and_deploy.sh` substitutes it before the image is built and aborts the deploy if any occurrence survives. Defaults to `$` when unset.4041---4243## Complete Lifecycle & Infrastructure Dependency Graph4445```46Phase 1: Customer Domain & Business Goal Research (Search Grounding & Language Detection)47 ↓48Phase 2: Requirements confirmed interactively ➔ Demo Architecture & Data Model Plan ➔ APPROVAL49 ↓50Phase 3: Synthetic Data & External Sample Files Generation (PDF, Excel, Images) + Google Drive Upload (Step 1/6)51 ↓52Phase 4: ADK Multi-Agent Project Scaffolding & A2UI System Prompts53 ↓54Phase 5: Ordered Cloud Provisioning & Deployment:55 ├── Step 1: BigQuery (with Knowledge Catalog Metadata) & Firestore Initial Data56 ├── Step 2: Agent Engine Sandbox (Code Execution Environment) [CRITICAL DEPENDENCY]57 ├── Step 3: Data Viewer Dashboard Cloud Run Deployment (Gets VIEWER_URL)58 ├── Step 4: Main Multi-Agent Cloud Run Deployment (Injects SANDBOX_RESOURCE_NAME & VIEWER_URL)59 └── Step 5: Background Task Pub/Sub Push Subscription (/execute_task & SELF_URL)60 ↓61Phase 6: Gemini Enterprise App Discovery, Workspace Authorization & Registration (Step 6/6)62 ↓63Phase 7: Comprehensive Results Output:64 ├── 💬 Direct Gemini Enterprise Console Chat Link65 ├── 📁 External Sample Files: Cloud Storage links, plus Drive links when the upload ran66 ├── 📊 Firestore Data Viewer Dashboard Link67 ├── 🔎 BigQuery Console Link68 └── 🎯 7 Structured Demo Prompts Playbook (Localized to Target Language)69 ↓70Phase 8: Automated Browser Demo Video Production & Drive Delivery (Optional)71 ├── Step 1: Playwright CDP Screen Recording of GE Web UI (Prompt 1, 3, 4)72 ├── Step 2: Google Cloud TTS Narration Audio & Subtitle Timecodes73 ├── Step 3: Remotion Programmatic Video Composition (Dynamic Camera, 4x Fast-Forward, Pure Voice Narration)74 └── Step 4: Google Drive Upload to Demo Folder & Sharable Link75```7677---7879## Phase 1: Customer Domain & Business Goal Research80811. **Extract Domain & Company**:82 - If a domain is provided (e.g., `example.com`, `example.co.jp`, `example.de`), determine company name, primary industry, and regional language from the domain itself — never from a list baked into this skill.83 - If a business goal or company name is provided, identify the corresponding corporate entity and language.84852. **Grounded Deep Research (via `search_web`)**:86 - Search for the company's latest corporate profile, business units, IR reports, and known operational challenges.87 - Identify:88 - **3-5 Key Business Challenges** (e.g., "yield rate drop in semiconductor fabrication", "supply chain lead-time anomalies").89 - **5-8 Operational Workflows** and evaluate which ones are **automatable** with AI agents.90 - **Authentic Domain Entities & Nomenclature** (e.g., real facility names like "Kumamoto Technology Center", actual product codes, industry status codes).91923. **Interactive Use Case Selection (Customer Domain Selection Flow)**:93 - Present the research findings to the user in their language:94 - 🏢 **Company Profile**: Official name, summary, primary industry.95 - ⚠️ **Key Business Challenges**: 3-5 detected operational pain points.96 - 🎯 **Candidate Workflows**: 3-5 top automatable workflows with automation feasibility ratings.97 - **Prompt the user to select or customize the use case**:98 - Use `ask_question` or present a structured choice so the user can pick the target scenario or write in specific requirements.99100---101102## Phase 2: Requirements Alignment & Demo Architecture Plan (Approval Gate)103104Phase 2 has two steps, in this order and never merged into one:105106**Step 2.1 — ask** the handful of questions the design genuinely depends on, interactively.107**Step 2.2 — show** the finished design brief as the alignment artifact, and ask for a go.108109The order is what makes the brief worth reading. A brief that still contains open questions110is a questionnaire, and the user has to hold the design in their head while answering it; a111brief written *after* the answers is a mirror — the user is checking whether what you112understood matches what they meant, which is a much easier thing to do and the last cheap113moment to change the entities, the narrative, the file lineage or the target project.114115Until the user approves the brief, **nothing is created** — no CSVs, no Drive folder, no116BigQuery dataset, no Cloud Run service. Everything after this point takes 15-30 minutes and117spends real quota in someone's project.118119### Step 2.1 — Confirm the requirements interactively120121Ask only what you cannot responsibly decide, and ask it *before* writing the brief. Keep it122short — two to four questions, batched into one message (`ask_question` where available), each123with a stated default so the user can answer "all defaults" in three words:1241251. **Anchor persona** — who is the primary user of this agent (job title, and a sentence of126 context if useful)? That persona becomes the demo's protagonist: the agent is framed as127 *their* process operator, prompt 1 opens from their daily situation, approval gates are128 decisions they or their manager own, and every other persona appears only as a hand-off129 counterpart. If the user declines, rotate personas freely instead.1302. **Scope of the narrative** — which single process instance the demo follows, if Phase 1131 left more than one plausible reading of the chosen scenario.1323. **Advanced settings** — ask about the two or three the demo is a plausible candidate for133 (Workspace OAuth when the scenario touches Gmail/Drive/Calendar, `rag` when it turns on134 documents rather than numbers, `dataScale` when the narrative claims enterprise volume),135 and say the rest keep their defaults. Keep the *question* short — brief section 6 lists136 every option with its resolved value, so nothing is hidden by asking about a few. Add137 **a warm Cloud Run instance** (`MIN_INSTANCES=1`) to that question whenever the user has138 named a date, an audience or a live session: it is the one option that is about the139 *presentation* rather than the demo, and the only thing that removes the cold start — and140 the occasional cold-start error — from the first message. Offer it with its price in the141 same breath (see brief section 6).1424. **Target environment** — only if what `gcloud` reports (read it now, see below) is not143 obviously the project the user means.144145Anything the user has already stated — in the original request or in Phase 1 — is *decided*.146Re-asking it reads as not having listened.147148**Zero-Touch Environment, Project & IAM Pre-flight Probe**:149150Read and verify the target environment before writing the brief, ensuring zero-touch deployment readiness so the brief's section 5 states verified facts rather than unvalidated assumptions:151152```bash153# 1. Target Project Synchronization: align project if specified by user154TARGET_PROJECT="${TARGET_PROJECT:-}"155CURRENT_PROJECT=$(gcloud config get-value project 2>/dev/null || echo "")156if [ -n "$TARGET_PROJECT" ] && [ "$CURRENT_PROJECT" != "$TARGET_PROJECT" ]; then157 gcloud config set project "$TARGET_PROJECT" >/dev/null 2>&1 || true158fi159PROJECT_ID=$(gcloud config get-value project 2>/dev/null || echo "")160161# 2. Account Verification & Auto-Discovery: probe project access; auto-switch if active account lacks access162GCP_ACCOUNT=$(gcloud config get-value account 2>/dev/null || echo "Unknown")163if ! gcloud projects describe "$PROJECT_ID" >/dev/null 2>&1; then164 for acc in $(gcloud auth list --format="value(account)" 2>/dev/null); do165 if gcloud projects describe "$PROJECT_ID" --account="$acc" >/dev/null 2>&1; then166 gcloud config set account "$acc" >/dev/null 2>&1 || true167 GCP_ACCOUNT="$acc"168 break169 fi170 done171fi172173PROJECT_NUMBER=$(gcloud projects describe "$PROJECT_ID" --format="value(projectNumber)" 2>/dev/null || echo "")174REGION=${CLOUD_RUN_REGION:-"asia-northeast1"}175176# 3. Google Drive Scope Pre-flight177DRIVE_OK=$(curl -s -o /dev/null -w '%{http_code}' \178 -H "Authorization: Bearer $(gcloud auth print-access-token 2>/dev/null)" \179 'https://www.googleapis.com/drive/v3/about?fields=user')180```181182`DRIVE_OK` is `200` when the Drive copy will happen, and the owner is `${GCP_ACCOUNT}` — the183same account, because the upload uses this token. Anything else (usually `403`, a token184carrying no Drive scope, which is what a plain `gcloud auth login` gives you) means **this185demo will have no Google Drive copy of the sample documents at all**. That is a fact the186brief has to state, not discover at deploy time — see brief sections 3 and 5. It is also one187command to fix, so say it now: `gcloud auth login --enable-gdrive-access --no-launch-browser` (using `--no-launch-browser` since an agentic IDE terminal usually has no local browser), then re-read.188189#### Multi-OS Google Cloud Authentication & Setup Protocol190Before proceeding with deployment, verify both user CLI authentication (`gcloud auth print-access-token`) and Application Default Credentials (`gcloud auth application-default print-access-token`). If missing or expired:191- **Interactive TTY Mode (`[ -t 0 ]`)**: The script automatically detects the host OS environment, prints the tailored authentication commands, and pauses (`read -p`), allowing the user to authenticate in a separate terminal or browser window and resume seamlessly by pressing Enter.192- **Non-Interactive / CI Mode**: Strictly fail-fast (Exit 1) with descriptive error logs and the single command to resume.193- **Host OS Detection & Authentication Matrix**:194195 | Host OS / Environment | Detection Signal | Authentication Commands | Notes |196 |---|---|---|---|197 | **Linux / Remote VM (Headless)** | No `$DISPLAY`, SSH, or Cloud Shell | `gcloud auth login --enable-gdrive-access --no-launch-browser`<br>`gcloud auth application-default login --no-launch-browser`<br>`gcloud auth application-default set-quota-project $PROJECT_ID` | Copy verification URL to local browser, sign in, and paste auth code back. |198 | **macOS (Terminal / iTerm)** | `uname -s == Darwin` | `gcloud auth login --enable-gdrive-access`<br>`gcloud auth application-default login`<br>`gcloud auth application-default set-quota-project $PROJECT_ID` | Browser opens automatically for OAuth consent. |199 | **Windows (WSL / WSL2)** | `/proc/version` contains `microsoft` or `wsl` | `gcloud auth login --enable-gdrive-access`<br>`gcloud auth application-default login`<br>`gcloud auth application-default set-quota-project $PROJECT_ID` | If browser interop is disabled, append `--no-launch-browser`. |200 | **Linux Desktop (GUI)** | Linux with active `$DISPLAY` | `gcloud auth login --enable-gdrive-access`<br>`gcloud auth application-default login`<br>`gcloud auth application-default set-quota-project $PROJECT_ID` | Browser opens automatically for OAuth consent. |201202- **Quota Project Auto-Configuration**: The deployment script and self-healing engine automatically execute `gcloud auth application-default set-quota-project $PROJECT_ID` to prevent HTTP 403 `PERMISSION_DENIED: The discoveryengine.googleapis.com API requires a quota project`.203204#### Deployer IAM Audit & Autonomous Self-Healing Protocol205To guarantee a seamless zero-touch deployment, probe whether the deploying account `${GCP_ACCOUNT}` possesses the necessary permissions on `${PROJECT_ID}`:2062071. **Owner / IAM Admin Auto-Healing**:208 - Check if `${GCP_ACCOUNT}` is Project Owner, Editor, or has Project IAM Admin on `${PROJECT_ID}`.209 - If `${GCP_ACCOUNT}` has IAM administrative privileges but lacks specific service roles (or if granular roles are in use), **automatically grant missing deployment roles** before starting deployment:210```text211gcloud projects add-iam-policy-binding "$PROJECT_ID" \212 --member="user:$GCP_ACCOUNT" \213 --role="roles/run.admin" --condition=None214215gcloud projects add-iam-policy-binding "$PROJECT_ID" \216 --member="user:$GCP_ACCOUNT" \217 --role="roles/discoveryengine.admin" --condition=None218219gcloud projects add-iam-policy-binding "$PROJECT_ID" \220 --member="user:$GCP_ACCOUNT" \221 --role="roles/bigquery.admin" --condition=None222223gcloud projects add-iam-policy-binding "$PROJECT_ID" \224 --member="user:$GCP_ACCOUNT" \225 --role="roles/iam.serviceAccountUser" --condition=None226```2272282. **Non-Admin Permission Denial Handling (Zero-Touch Guidance)**:229 - If `${GCP_ACCOUNT}` lacks `roles/resourcemanager.projectIamAdmin` or `roles/owner` and `gcloud projects describe` or service checks return `PERMISSION_DENIED`:230 - **DO NOT** stop with a vague error or ask the user to manually run setup scripts in their terminal.231 - Present the exact, copy-pasteable command for their Google Cloud Project Administrator:232 ```text233 gcloud projects add-iam-policy-binding "$PROJECT_ID" \234 --member="user:$GCP_ACCOUNT" \235 --role="roles/owner"236 ```237 - Prompt the user interactively (using `ask_question` if available) to notify their administrator or switch accounts (`gcloud config set account <admin-account>`), then cleanly re-test and proceed with automated deployment.2382393. **Capsule / Sandbox Policy Detection**:240 - If `${PROJECT_ID}` starts with `cpl-*` or `mpl-*` (Google Cloud Capsule or restricted sandbox), inspect whether organizational policy constraints (such as `constraints/run.allowedIngress` or Service Directory restrictions) are active. Warn the user before data generation so expectations match sandbox capabilities.241242### Step 2.2 — Present the Demo Architecture & Data Model Plan243244One message, six sections, in this order, then the gate. Every answer from Step 2.1 is already245folded in — the brief **states** decisions, it does not ask for them, and it contains no246"tell me which…" or "TBD" anywhere.247248Write it in **the demo's language** (§ i18n above) — headings, table headers and prose alike.249Only the technical identifiers stay English `snake_case`: table names, column names and250`.env` keys.251252Open with a title line naming the company and the selected scenario, so the brief is253self-contained when it is pasted into a chat with a colleague:254255> ### 🏗️ `<Company>` — Demo Architecture & Data Model Plan256> Based on the selected scenario **"`<scenario>`"**, here is the data layer design, the257> Mermaid ER diagram and the cross-source reconciliation lineage.258259### § Brief section 1 — 🏢 Target Company & Demo Overview260261- **Company / group**: official name, and the group entity the demo actually models.262- **Industry**: the specific one, in the company's own vocabulary.263- **Demo narrative**: 2-3 sentences following **one** business process instance (one264 problematic order, one flagged application) end to end, naming the departments it passes265 through. All 7 demo prompts later trace this same instance; see266 `references/demo_prompts_guide.md` §1.1-§1.2.267- **Anchor persona**: the persona confirmed in Step 2.1, stated as a fact ("the agent is268 operated by the production control manager of the main works"). If the user declined to269 name one, say that personas rotate instead — do not re-ask here.270271### § Brief section 2 — 📊 Data Layer Design & Mermaid ER Diagram272273- **Render a Mermaid `erDiagram`** in a ```mermaid fenced block: every table, every column274 with its type, `PK`/`FK` markers, cardinality labels on each relationship, and a short275 business gloss in quotes after each column (`string order_id PK "order number (ORD-2026-XXXX)"`).276 The gloss is the same sentence that later becomes the column description in the Knowledge277 Catalog, so writing it here is not duplicated work.278- Include the Firestore task collection as an entity too — it is part of the model the demo279 reasons over, even though it is not in BigQuery.280- **Shared core-system model**: design the tables as a slice of the company's system of281 record, not one team's dataset — a transactional table two departments both write, a282 rules/threshold table owned by one department that another's workflow must consult, and283 an audit seed visible only when the departments' views are joined. Details and the284 single-department escape hatch: `references/data_generation.md` §1.3.285286### § Brief section 3 — 📁 External Sample Files & Cross-Source Lineage287288Title this section after where the files will actually be, not after where people assume they289go. Cloud Storage is the only guaranteed destination (below), so a heading that says "Google290Drive" is wrong in every run whose token lacks the Drive scope — and it was, in most of them.291292A table with one row per external file — type, filename, and what binds it to BigQuery:293294| External file | Filename | Content & data binding |295|---|---|---|296| 📄 PDF audit report | `<domain>_audit_report.pdf` | which tables it summarizes, and the deliberate 5-15% variance that makes cross-source reconciliation necessary |297| 📊 Excel ledger | `<domain>_external_ledger.xlsx` | which FK column it joins on, and the row count |298| 🖼️ Scanned form 1 | `handwritten_order_1.jpg` | what the form is, in-domain, generated by `gemini-3.1-flash-image` |299| 🖼️ Scanned form 2 | `handwritten_order_2.jpg` | the second form, and the discrepancy it carries |300301State the join key explicitly. A lineage row that says "related to orders" is not a design —302the whole point of the external files is that a question can only be answered by reading a303document *and* querying a table, and that only works if the keys line up (70%+ FK match,3045-15% audit variance). See `references/external_files_and_drive.md`.305306Close the section with where the files will actually live, in one line, because it is the307part users assume wrongly. Write the line that matches the `DRIVE_OK` read above:308309| `DRIVE_OK` | The line to write |310| --- | --- |311| `200` | Staged to `gs://<project>-<domain>-<suffix>-docs/` **and** uploaded at deploy time to the Google Drive of `${GCP_ACCOUNT}`, which owns the folder. |312| anything else | Staged to `gs://<project>-<domain>-<suffix>-docs/`. **No Google Drive copy** — this machine's `gcloud` credentials carry no Drive scope, so a Drive or Sheets step in the demo script would find nothing. |313314The Cloud Storage staging happens in **both** `mcp` and `rag` mode; the deploy-time upload is315the *only* path into any Drive. The deployed agent has no way to put them in anyone's Drive —316v2.11.0 removed the in-conversation import, deliberately. If the user wants them in Drive and317`DRIVE_OK` is not `200`, say so here, while it can still be sorted out318(`gcloud auth login --enable-gdrive-access --no-launch-browser` and re-run, or upload `./external_files/` by hand319afterwards).320321### § Brief section 4 — 🤖 Agent Profile & Runtime322323- **Agent Name (`DEMO_DISPLAY_NAME`)**: Concise 2–4 word domain role (e.g. `TWG Tea Retail Operations Director`, `Mercari Trust & Safety Specialist`). Registered in Gemini Enterprise as `${DEMO_DISPLAY_NAME} (${SERVICE_NAME})`, matching the Web UI (GAS) version.324- **Description (`DEMO_DESCRIPTION`)**: Concrete, professional 1–2 sentence mission summary specifying the business domain, core datasets, and operational goals (e.g. `Orchestrates boutique inventory balancing, central commissary replenishment, and plantation harvest orders across Singapore.`). Matches `oneSentenceSummary` in the Web UI (GAS).325- **Reasoning / orchestration**: **`gemini-3.8-flash`** for all agent instances (Root Coordinator, Deep Analysis Sub-Agent, Background Worker).326- **Image generation**: **`gemini-3.1-flash-image`** (with localized prompt reinforcement and GCS artifact persistence).327- **Code execution**: Agent Engine Sandbox (`us-central1` — fixed, not `$REGION`).328- **UI**: Gemini Enterprise A2UI v0.9 composite catalog (name the components this demo will actually lean on — `MaterialTable`, `VegaChart`, `MaterialCard`).329330### § Brief section 5 — ⚙️ Deployment Target Environment331332Show what the commands above returned, verbatim, in a fenced block:333334```335👤 Active User Account : ${GCP_ACCOUNT}336🏢 Target Project : ${PROJECT_ID} (${PROJECT_NUMBER})337🌐 Target Region : ${REGION}338🛡️ Deployer IAM Status : Verified (Owner/Admin) / Auto-healed339🗂️ Sample File Storage : gs://${PROJECT_ID}-<domain>-<suffix>-docs/340📁 Google Drive Copy : <the DRIVE_OK line, below>341```342343This is the section users most often stop on, because the answer is frequently "wrong344project". Do not paraphrase the values and do not print a project the user named unless345`gcloud` agrees — the deploy will use what `gcloud` says, not what the brief claims.346347Both storage lines are mandatory, and neither is optional wording: the Cloud Storage bucket is348created in every mode, and the Drive line is the one users read as a promise. Write it from349`DRIVE_OK`, never from intent:350351| `DRIVE_OK` | `📁 Google Drive Copy` |352| --- | --- |353| `200` | `Google Drive of ${GCP_ACCOUNT}` |354| anything else | `none - these credentials have no Drive scope (fix: gcloud auth login --enable-gdrive-access --no-launch-browser)` |355356Never print a Drive destination the deploy cannot reach, and never describe the copy as357something the agent will do later — nothing after the deploy writes to a Drive. See358`references/external_files_and_drive.md` §5.359360### § Brief section 6 — 🎛️ Advanced Settings & Integrations361362 State the settings **this** demo will deploy with — the answers from Step 2.1, plus the363 defaults for everything the user did not touch. These names are the `.env` keys,364 upper-snake-cased: `enableManagedAgent` is `ENABLE_MANAGED_AGENT`. Every one of them is a365 real switch in the deployed container, so an option discussed here but not written to366 `.env` is a feature the demo will not have.367368 **List all eleven, every time**, in this order, with the value this deploy will use in the369 second column — `✅ true` / `❌ false` / the literal value / `— (unset)`. An option the370 brief leaves out is an option the user cannot ask for: they do not know it exists, and by371 the time the deploy banner mentions it the 15-30 minutes are already spent. The gate is the372 last cheap moment to turn one on, so the gate has to show the whole board. Keep the third373 column as written here — it is what makes a `false` decidable rather than merely visible —374 and reword only where this demo's scenario changes what an option would buy.375376 | Option | This demo | Default | What it buys, and what it costs |377 |---|---|---|---|378 | 🤖 `enableManagedAgent` | `<value>` | **`true`** | Agent Engine Sandbox code execution, asynchronous background delegation (`delegate_autonomous_task`), scheduled tasks and Drive deliverable exports. The delegation prompts in the demo playbook exercise this, which is why it is the one default-on capability. Adds ~8-10 min of provisioning, overlapped with the rest of the deploy. |379 | 📡 `enableCloudTelemetry` | `<value>` | **`true`** | OpenTelemetry Cloud Trace instrumentation. Fully tracks per-turn LLM token consumption (`input_tokens`, `output_tokens`), latency breakdown waterfall, and tool execution. PII-safe via `NO_CONTENT` (zero chat prompt text transmitted), 0ms warm-turn overhead (async background batching), and free under monthly Cloud Trace quota. Set to `false` to opt out. |380 | 🛡️ `enableModelArmor` | `<value>` | `false` | Vertex AI Agent Platform Model Armor integration. Enforces prompt injection & jailbreak defense, automatic sensitive data protection (SDP credentials/PII masking), and RAI safety filters. Auto-provisions and binds `ge-demo-default-armor` in `us-central1` if no custom template is specified. |381 | 🔎 `dataExplorationMode` | `<value>` | **`mcp`** | How the agent reads the demo's data. **`mcp`** (default) provisions no search index: the data-asset catalog is already in the agent's system instruction, so a figure question is *one* `execute_sql` call — the four-to-five round trips people blame on "no index" came from the metadata expedition in front of the query, and the mcp routing block overrides exactly that. **`rag`** additionally builds a Discovery Engine index over the BigQuery dataset and the staged files and makes it the read path: lookups and document questions return in one sub-second `search_datastore` call, while computed figures, joins and every write stay on MCP because the index lags the tables. Pick `rag` when the demo turns on documents rather than on numbers, and note it also attaches data stores to the (often shared) Gemini Enterprise app — see `references/datastore_connectors.md`. |382 | 📁 `enableDatastoreFs` | `<value>` | `false` | When `dataExplorationMode=rag`, provisions a semi-structured Discovery Engine DataStore (`ds-${SERVICE_NAME}-fs`) from `FIRESTORE_COLLECTION` via `FirestoreSource` (GCS export staging). Enables semantic search over historical incident tickets, resolved remediation logs, and SOP archives. Note: live task mutations, approvals, and Operations Viewer synchronization continue to use Firestore MCP for sub-100ms real-time state tracking. |383 | 🔑 `enableWorkspaceAuth` | `<value>` | `false` | User-OAuth passthrough — the agent acts as the signed-in user for the Drive handoff and Workspace token plumbing. Commonly wanted, since Workspace is usually available in the target environment, but **not** default-on: some organizations refuse to authorize an OAuth client they have not vetted, and there sign-in fails for every demo user. Confirm the target org permits it before enabling. |384 | 🔑 `enableWorkspaceMcp` | `<value>` | `false` | **Advanced, rarely used.** Adds the Gmail / Drive / Calendar / Docs / Chat MCP toolsets on top of the auth passthrough. The Workspace MCP servers are Developer Preview and the project must be allowlisted first — enable it without that and every Workspace call 403s. Kept separate from `enableWorkspaceAuth` for exactly this reason. |385 | 🖥️ `enableComputerUse` | `<value>` | `false` | Headless browser automation (Playwright). Also requires uncommenting the Playwright block in **both** `requirements.txt` and the `Dockerfile`; the deploy pre-flights this and refuses a half-configured build. |386 | 📦 `customMcpRepos` | `<value>` | empty | Third-party MCP servers. Both GitHub sidecars and remote managed servers (Slack included — it is one entry in this list, not a flag of its own) go here. |387 | 🌐 `publicDatasetId` | `<value>` | unset | Ground the demo in a real BigQuery public dataset (e.g. NOAA Weather, Google Trends) alongside the synthetic data. |388 | 📈 `dataScale` | `<value>` | unset (hero rows only) | Row count to grow the fact tables to before loading — thousands to tens of thousands. You still write only the 50-200 hero rows the demo script names; `scripts/amplify_data.py` expands the tables around them deterministically, keeping the hero rows verbatim and foreign keys intact. Ask for it when the narrative claims enterprise volume or the demo opens with an aggregate — a `COUNT(*)` of 63 undercuts both. Costs ~10-30s of setup and a longer Discovery Engine ingest. |389390Only list the options that are on, plus the two or three the demo is a plausible candidate391for. A user reading eight defaults they did not ask about is a user who skims the whole brief.392393**One more switch, and it is deliberately not in that table** — it is not an `.env` key and it394changes nothing inside the container. Cloud Run scales this demo to zero when nobody is talking395to it, which is why an idle demo costs nothing, and why the first message after an idle gap396waits ~20-25s for a cold start and can come back as an error instead: Cloud Run sometimes397refuses a request outright while the container is still starting. Deploying with398`MIN_INSTANCES=1` — the environment variable `setup_and_deploy.sh` reads in Step 4/6, exported399before the deploy runs — keeps one instance always up and removes both.400401State it as a line under the table when you offer it, with the price attached rather than in a402footnote:403404> 🔥 **Warm instance** — `MIN_INSTANCES=1` · default `0` (scale-to-zero). No cold start and no405> cold-start error on the first message. **Cost:** one 8 GiB / 2 vCPU instance is then billed406> continuously for as long as the demo exists — not just during the presentation.407408The honest default is `0`: for a demo deployed now and shown next week, sending the first409message twice is far cheaper than a week of idle billing. It is also not a decision that has to410be made now — it is read at deploy time, so re-running the deploy with the variable set (or411unset) flips an existing demo either way.412413### § The gate — ask once, then stop414415Close the message by triggering an interactive approval and option selection modal using the `ask_question` tool (with plain text fallback only if `ask_question` is not supported in the active environment). This allows the user to review all capabilities and toggle any extra features directly:416417- Call `ask_question` with `is_multi_select: true`:418 - `question`: "Do you approve this architecture and deployment plan? Select '(Recommended) Proceed with default configuration' to start deployment immediately, or check any additional options you want enabled:" (in the demo's language)419 - `options`:420 1. `"(Recommended) Proceed with default configuration (Managed Agent: Enabled, Cloud Trace Telemetry: Enabled, other options: default)"`421 2. `"🛡️ Enable Model Armor Guardrails (Auto-provisions and binds ge-demo-default-armor in us-central1 for jailbreak defense and PII masking)"`422 3. `"🔑 Enable Google Workspace OAuth (Drive/Slides/Docs export as signed-in user)"`423 4. `"🔎 Enable RAG Data Exploration Mode (Build Discovery Engine search index for document & table reads)"`424 5. `"📁 Enable Firestore DataStore (Semantic search over historical tickets & SOPs in RAG mode)"`425 6. `"🔥 Enable Warm Instance (Cloud Run min-instances=1 to eliminate cold-start delay)"`426 7. `"🖥️ Enable Computer Use (Gemini 3.8 Flash Chromium browser automation)"`427 8. `"📈 Enable Enterprise Data Scale (Grow fact tables to thousands of rows via amplify_data.py)"`428 9. `"📡 Disable Cloud Trace Telemetry (Opt-out from OpenTelemetry token & latency tracking)"`429430- In non-interactive or headless environments where `ask_question` is unavailable, output the equivalent choices in chat text and pause for user reply.431- When the user selects options, update `.env` (`ENABLE_MODEL_ARMOR=1`, `ENABLE_WORKSPACE_AUTH=1`, `ENABLE_CLOUD_TELEMETRY=0`, `DATA_EXPLORATION_MODE=rag`, etc.) and deployment flags accordingly before proceeding to Phase 3.432433Then **stop and wait**. Do not start Phase 3 in the same turn, and do not treat "looks good" on434a *previous* message — the scenario choice in Phase 1 or an answer in Step 2.1 — as approval of435this brief.436437When the user changes something, re-render the affected sections and ask again; an approved438brief is the specification the rest of the run is built from, so it has to be the version the439user actually said yes to.440441---442443## Phase 3: Synthetic Data & External Sample Files Generation + Google Drive Upload444445**Entry condition: the Phase 2 brief was presented in full and the user approved it.** If you446arrive here without that, go back and present it.4474481. **Derive the demo's identifiers, concrete name, and description**:449 ```bash450 SUFFIX=$(date +%s | tail -c 5)451 DEMO_ID="${DOMAIN_SLUG}-${SUFFIX}"452 SERVICE_NAME="ge-demo-${DOMAIN_SLUG}-${SUFFIX}"453 DATASET_ID="demo_${DOMAIN_SLUG}_${SUFFIX}"454 FIRESTORE_COLLECTION="demo-${DOMAIN_SLUG}-${SUFFIX}-tasks"455456 # Set concrete, domain-specific display name & description (matching Web UI / GAS version)457 DEMO_DISPLAY_NAME="${COMPANY_NAME} ${AGENT_ROLE:-Operations Specialist}"458 DEMO_DESCRIPTION="Orchestrates ${SCENARIO_SUMMARY:-operations and intelligent data analytics} across ${COMPANY_NAME}."459 ```460 *Always write `DEMO_DISPLAY_NAME` and `DEMO_DESCRIPTION` into `.env` so `setup_and_deploy.sh` and `register_agent.py` register the agent with concrete domain details.*4614622. **Generate Real-World Synthetic Data & Display Previews**:463 - Generate CSV files with realistic addresses, valid foreign keys across tables, and varied statuses in `data/<table_name>.csv`.464 - Ensure all string data is generated in the detected target language.465 - Run validation script: `python3 scripts/validate_csv.py data/*.csv`.466 - **Render Dataset Preview & Record Counts**: Output a Dataset Summary Table with total generated record counts for each BigQuery table, Firestore collection, and external Drive file, followed by 3–5 representative sample rows per table in clean Markdown preview tables (or `<carousel>` sliders) clearly indicating the total row count in each table title.467 - Write one line of grain per table into `data/<table_name>_description.txt` ("one row per468 POS transaction line", "one row per store"). The deploy folds it, the column469 descriptions from `data/<table_name>_schema.json`, the row counts and the real date470 range of every date column into `adk_agent/app/data_assets.md` — the DATA ASSET CATALOG471 the agent's prompt is written around. Skipping the grain line costs only that line;472 skipping the column descriptions costs the agent its schema.4734742b. **Amplify to Demo Volume (only when `dataScale` was agreed in Phase 2)**:475- Do **not** try to write thousands of rows yourself. Write the 50-200 hero rows as476 above — the ones the demo prompts name by id — and let the amplifier expand the477 tables around them. It resamples each column from what the hero rows already show,478 draws foreign keys from the parent table's amplified key set, and keeps the hero479 rows verbatim at the top of every file, so every id a prompt refers to still resolves.480- Write `data/data_scale_spec.json` with a per-table `target_rows` map. Describe a481 column only where the hero rows misrepresent it — in practice that means date482 columns, because hand-written rows cluster into one week while the narrative spans483 a fiscal year. Everything you leave out is inferred. See the module docstring of484 `scripts/amplify_data.py` for the format and for the two things the spec will not do.485 ```bash486 python3 scripts/amplify_data.py --data-dir ./data --spec ./data/data_scale_spec.json487 for f in data/*.csv; do case "$f" in *.hero.csv) ;; *) python3 scripts/validate_csv.py "$f" ;; esac; done488 ```489- Alternatively set `DATA_SCALE=<rows>` in `.env` and let the deploy run it: the step490 is idempotent and deterministic, so doing it in both places is harmless.491- Report the amplified counts in the Dataset Summary Table, and say which tables were492 left at hero size — master data that the narrative describes as small must stay small.493- `python3 scripts/amplify_data.py --data-dir ./data --restore` puts the hero CSVs back.4944953. **Generate External Sample Files & Upload Directly to Google Drive**:496 - Synthesize external demo files in `./external_files/`:497 1. **PDF Audit Report** (`<domain>_audit_report.pdf`): Multi-section structured document in target language with summary, details, and intentional 5-15% variance from BigQuery to trigger cross-source reasoning.498 2. **Excel Spreadsheet Ledger** (`<domain>_external_ledger.xlsx`): Semi-structured workbook with localized KPI headers, units, and 40-80 transaction rows with FK references matching BigQuery tables.499 3. **Simulated Operational Document Images** (`handwritten_order_1.jpg`, `handwritten_order_2.jpg`): Realistic scanned forms generated via `gemini-3.1-flash-image` with localized text.500 - **Upload to Google Drive**:501 ```bash502 uv run --no-project \503 --with "openpyxl>=3.1.0,<4.0.0" \504 --with "reportlab>=4.0.0,<6.0.0" \505 --with "pillow>=10.0.0,<13.0.0" \506 python3 scripts/generate_and_upload_external_files.py \507 --domain "$DOMAIN_SLUG" \508 --company "$COMPANY_NAME" \509 --suffix "$SUFFIX" \510 --outdir "./external_files" \511 --spec-file "./data/external_files_spec.json"512 ```513 - `--spec-file` carries THIS demo's content (titles, sections, table rows, and the514 `style` wording for the scanned forms), written in the demo's own language and515 domain. Without it the script emits generic placeholder documents - it holds no516 built-in industry content by design.517 - Creates dedicated Drive folder: `GE Demo - <Company Name> (<Suffix>)`, reusing one518 of that name if a previous run already made it.519 - Uploads `.pdf`, `.xlsx`, and `.jpg` files.520 - Saves links to `external_files/drive_upload_summary.json` and creates `.url.json` artifacts.521 - **The folder is owned by `${GCP_ACCOUNT}`** — the upload is a Drive v3 REST call522 carrying this machine's own `gcloud` access token, so the account deploying the523 demo owns what it creates and nothing has to be shared with it. Report that owner524 and the folder URL. The script also asks for "anyone with the link (Reader)" as a525 convenience; plenty of organizations refuse it, in which case the summary carries526 `share_error` and the banner notes `ℹ️ LINK SHARING OFF` — the owner can still open527 everything, so this is a footnote, not a failure.528 - When the token has n529530…(truncated)