diff --git a/skills/.curated/google-adk-js/SKILL.md b/skills/.curated/google-adk-js/SKILL.md new file mode 100644 index 0000000..b37a3bf --- /dev/null +++ b/skills/.curated/google-adk-js/SKILL.md @@ -0,0 +1,99 @@ +--- +name: adk-js +description: Build, configure, and update Agent Development Kit (ADK) agents in TypeScript using `@google/adk` and `@google/adk-devtools`. Use when a user asks to scaffold a brand-new ADK TS project, define agents (LlmAgent, workflow agents, custom BaseAgent), add tools (FunctionTool, AgentTool, built-ins like GOOGLE_SEARCH), design multi-agent orchestration, configure models/auth (Gemini API key or Vertex AI), run via devtools, or adapt patterns from ADK JS docs/samples. +--- + +# ADK JS + +## Overview +Build and iterate on ADK TypeScript agents with the official SDK, devtools, and docs-driven patterns. Prefer official docs and samples for API details and compatibility. + +## Quick Decision Guide +- **New project or first agent:** Open `references/quickstart.md`. +- **Running or debugging:** Open `references/devtools.md`. +- **Adding tools:** Open `references/tools.md`. +- **Model/auth setup:** Open `references/models.md`. +- **LLM agent configuration (schemas, output keys, context):** Open `references/llm-agents.md`. +- **Callbacks/guardrails:** Open `references/callbacks.md`. +- **Example patterns:** Open `references/samples.md`. + +## Core Workflow +1. **Clarify scope:** Identify whether the user needs a new agent, an update, or a specific feature (tools, multi-agent, model/auth). +2. **Bootstrap or edit:** For brand-new projects, follow `references/quickstart.md` exactly; otherwise edit existing `agent.ts` and configs. +3. **Design architecture:** Use a root LLM orchestrator plus deterministic agents (Sequential/Parallel/Loop) instead of hardcoded intent rules. See `references/architecture.md`. +4. **Add capabilities:** Implement tools or multi-agent orchestration as needed. +5. **Run and verify:** Use devtools for local run or web UI. + +## Agent Construction Guidelines +- Export a `rootAgent` when the user intends to run with ADK devtools. +- Use `outputKey` to persist agent output into session state for downstream steps. +- Prefer `LlmAgent` for reasoning, `SequentialAgent`/`ParallelAgent`/`LoopAgent` for deterministic workflows. +- Keep tools on `LlmAgent.tools`, not `generateContentConfig.tools` (ADK throws if tools are set in config). +- If `inputSchema` is set, the incoming user message must be a JSON string matching the schema. +- If `outputSchema` is set, the agent must return JSON matching the schema and tool use is not effective. +- For new projects, default to a Gemini 3 preview model string and document access + region requirements. + +## Multi-Agent Patterns +- Use `subAgents` to form a hierarchy for delegation and workflow orchestration. +- Use `AgentTool` when you want the parent agent to stay in control and summarize a tool-agent's output. +- Distinguish **sub-agent transfer** vs **agent-as-tool** based on whether control should move to the child agent. + +## Architecture Best Practices +- Use a root LLM agent as the conversational front door and delegate work to deterministic agents. +- Avoid hardcoded intent checks; let the orchestrator decide whether to ask clarifying questions or transfer to a workflow. +- Prefer `AgentTool` for isolation in loops (fresh context each iteration) when state bleed is a risk. +- Store tool outputs in session state for downstream agents to read and compile. +- Use `subAgents` for LLM-driven delegation (`transfer_to_agent`) and keep agent names/roles explicit. +- Sequential agents share the same invocation context; parallel agents share state but run on branch contexts; loops stop on `maxIterations` or `escalate=true`. + +See `references/architecture.md` for a minimal “orchestrator + pipeline” blueprint. + +## Human-in-the-Loop (TypeScript) +- TypeScript recommends using `SecurityPlugin` + a custom `BasePolicyEngine` to require user confirmation before tool calls. +- Treat this as the default pattern for approvals rather than hardcoding user prompts. + +See `references/architecture.md` and `references/callbacks.md` for a lightweight HITL sketch. + +## Model + Auth Notes +- Use `GOOGLE_GENAI_API_KEY` or `GEMINI_API_KEY` for Gemini API mode; ADK does not read `GOOGLE_API_KEY`. +- Use Vertex by setting `GOOGLE_GENAI_USE_VERTEXAI=true` plus `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION`. +- Do not expect API keys to work with Vertex. Use ADC or service account JSON/credentials. +- For Gemini 3 preview on Vertex, set `GOOGLE_CLOUD_LOCATION=global` and confirm model access. +- Use `ADK_MODEL` to override the model string; default to `gemini-3-flash-preview` and fall back to `gemini-2.5-flash` if preview access is not enabled. +- If `GOOGLE_SERVICE_ACCOUNT_JSON` is provided (single-line JSON), write it to a temp file and set `GOOGLE_APPLICATION_CREDENTIALS` at runtime. Escape newlines in `private_key` with `\\n`. + +## Common Failure Modes +- **"Invalid JSON payload... ~standard/def" for tools**: Pin `zod` to v3. ADK tool schema conversion is not compatible with zod v4 output. +- **"Must include at least one parts field"**: Ensure request contents contain at least one `parts` entry (use a `beforeModelCallback` guard). +- **Vertex auth errors with API key**: Remove API key env vars or disable Vertex (`GOOGLE_GENAI_USE_VERTEXAI=false`). +- **"Session not found"**: Create a session in your API route before calling `runner.runAsync` (InMemoryRunner does not auto-create). +- **"Publisher Model ... was not found"**: For `gemini-3-flash-preview`, set `GOOGLE_CLOUD_LOCATION=global`. Otherwise use `gemini-2.5-flash` in regional locations. +- **Empty reply after tool call**: If the final event contains only `functionResponse` parts, surface the tool response directly in the UI/API (this is expected when `skipSummarization` is set or the model emits tool-only output). +- **Tool results missing in UI**: If you only read `event.content.parts[].text` (e.g., via `stringifyContent`), tool outputs will be dropped. Read `functionResponse.response` when no text is present. + +## Field Notes (Next.js Chat Integration) +- Use a singleton `InMemoryRunner` (e.g., on `globalThis`) to avoid reinitializing sessions during hot reloads. +- Default to `LoggingPlugin` in dev to log tool calls + events (`new InMemoryRunner({ plugins: [new LoggingPlugin()] })`); keep prod quiet unless debugging. +- Create sessions explicitly on each request if missing: `sessionService.getSession` then `createSession`. +- Surface `event.errorMessage` / `event.errorCode` when no reply is returned to avoid silent failures. +- For preview models on Vertex: `GOOGLE_CLOUD_LOCATION=global` + `ADK_MODEL=gemini-3-flash-preview`. +- Streaming (SSE): pass `runConfig: { streamingMode: StreamingMode.SSE }` to `runner.runAsync`, then stream `event.partial` deltas from `event.content.parts[].text`. Avoid emitting the full final text if you already streamed deltas (otherwise you'll double‑append). For UI drip‑feed, buffer the delta string and emit small chunks on a timer. +- If Vertex returns `must include at least one parts field` during streaming, add a `beforeModelCallback` that prunes empty `request.contents` and reuses `context.userContent` if needed. +- Avoid heuristic pre-routing (regex checks for math/search); let the LLM agent decide which tools to call. +- If tool calls succeed but no text is returned, read `event.content.parts[].functionResponse.response` and display it when no text is present (avoid regex pre-routing; let the LLM decide tool use). +- For SSE, don’t stop on empty “final” events; keep reading the generator to allow tool responses and the post‑tool LLM pass to arrive. + +## Notes and Constraints +- Treat the ADK web UI as development-only. +- Check the tools limitations doc before mixing tools. +- Confirm TypeScript support for evaluation features before implementing them. + +## References +- `references/quickstart.md`: Project scaffolding and minimal agent setup. +- `references/devtools.md`: CLI/web devtools usage. +- `references/tools.md`: Built-ins, FunctionTool, AgentTool. +- `references/models.md`: Model selection and authentication. +- `references/llm-agents.md`: Input/output schema, outputKey, includeContents, instruction templating. +- `references/callbacks.md`: Agent/tool callbacks for validation and guardrails. +- `references/samples.md`: Sample repository layout and usage. +- `references/architecture.md`: Orchestrator + workflow patterns and state isolation. diff --git a/skills/.curated/google-adk-js/references/architecture.md b/skills/.curated/google-adk-js/references/architecture.md new file mode 100644 index 0000000..d1fc57d --- /dev/null +++ b/skills/.curated/google-adk-js/references/architecture.md @@ -0,0 +1,51 @@ +# Multi-Agent Architecture (ADK JS) + +Use a root LLM agent as an orchestrator. Let it decide whether to ask clarifying questions or delegate to deterministic workflows. Avoid hardcoded intent routing. + +## Orchestrator + pipeline blueprint +```ts +import {LlmAgent, ParallelAgent, SequentialAgent} from '@google/adk'; + +const inventoryParallel = new ParallelAgent({ + name: 'inventory_parallel', + description: 'Runs independent inventory fetchers in parallel.', + subAgents: [flightAgent, hotelAgent], +}); + +const tripPipeline = new SequentialAgent({ + name: 'trip_pipeline', + description: 'Compiles inventory and itinerary.', + subAgents: [inventoryParallel, itineraryAgent], +}); + +export const rootAgent = new LlmAgent({ + name: 'trip_planner_root', + model: process.env.ADK_MODEL ?? 'gemini-3-flash-preview', + description: 'Orchestrates trip planning and clarifying questions.', + instruction: [ + 'Act as the orchestration layer.', + 'If required trip details are missing, ask one concise question.', + 'If user is greeting/small talk, reply briefly and ask for trip details.', + 'When details are sufficient, transfer to trip_pipeline.', + ].join('\n'), + subAgents: [tripPipeline], +}); +``` + +## Execution semantics to remember +- **SequentialAgent:** shares the same invocation context; state is read/write across steps. +- **ParallelAgent:** runs on branch contexts but shares the same session state (use unique keys). +- **LoopAgent:** repeats until `maxIterations` or a sub-agent escalates with `EventActions.escalate=true`. + +## LLM-driven delegation +- LLM agents can call `transfer_to_agent(agent_name="...")` when subAgents are present. +- Keep sub-agent `description` fields specific so the orchestrator routes correctly. + +## Loop + isolation pattern +- Use `LoopAgent` for repeatable tasks. +- Wrap complex sub-flows as `AgentTool` to isolate state per iteration. +- Persist outputs in `toolContext.state` for downstream agents to summarize. + +## Prompt hygiene +- Add a `beforeModelCallback` to ensure `request.contents` always includes at least one `parts` entry. +- Prefer `includeContents: "default"` for consistent context delivery. diff --git a/skills/.curated/google-adk-js/references/callbacks.md b/skills/.curated/google-adk-js/references/callbacks.md new file mode 100644 index 0000000..737361e --- /dev/null +++ b/skills/.curated/google-adk-js/references/callbacks.md @@ -0,0 +1,25 @@ +# Callbacks (TypeScript ADK) + +## Available callback types +- **Before/after agent:** `beforeAgentCallback`, `afterAgentCallback` +- **Before/after model:** `beforeModelCallback`, `afterModelCallback` +- **Before/after tool:** `beforeToolCallback`, `afterToolCallback` + +Callbacks can observe, modify, or short-circuit execution depending on return value. + +## Common uses +- Guardrails and validation (block a request before the model call). +- Ensure model requests always include `parts` in `contents`. +- Post-process tool results or redact sensitive data. +- Logging and tracing without touching agent logic. +For security guardrails, prefer ADK plugins when possible. + +## Short-circuit rules (high level) +- Returning a `Content` from a `beforeAgentCallback` skips agent execution. +- Returning an `LlmResponse` from a `beforeModelCallback` skips the model call. +- Returning an object from a `beforeToolCallback` skips tool execution and becomes the tool result. +- Returning a value from an `after*` callback replaces the upstream result. + +## Source +- https://google.github.io/adk-docs/callbacks/ +- https://google.github.io/adk-docs/callbacks/types-of-callbacks/ diff --git a/skills/.curated/google-adk-js/references/devtools.md b/skills/.curated/google-adk-js/references/devtools.md new file mode 100644 index 0000000..15daf40 --- /dev/null +++ b/skills/.curated/google-adk-js/references/devtools.md @@ -0,0 +1,23 @@ +# ADK DevTools (TypeScript) + +## Install +```bash +npm install @google/adk-devtools +``` + +## CLI run +```bash +npx @google/adk-devtools run agent.ts +``` + +## Web UI +```bash +npx @google/adk-devtools web +``` + +Default URL: http://localhost:8000 + +Note: ADK Web UI is for development and debugging only. + +## Source +- https://google.github.io/adk-docs/get-started/typescript/ diff --git a/skills/.curated/google-adk-js/references/llm-agents.md b/skills/.curated/google-adk-js/references/llm-agents.md new file mode 100644 index 0000000..aef59a6 --- /dev/null +++ b/skills/.curated/google-adk-js/references/llm-agents.md @@ -0,0 +1,30 @@ +# LLM Agents (TypeScript ADK) + +## Identity + Instructions +- `name` is required and used for routing in multi-agent setups. +- `description` helps other agents decide when to transfer work to this agent. +- `instruction` can be a string template with state placeholders like `{trip_origin}` and `{artifact.summary}`. +- Use `{var?}` to avoid errors when state is missing. + +## Tools +- Pass tools via `tools` on the `LlmAgent`. +- Tools must return an object (not a string). +- For agent-to-agent delegation inside tool calls, wrap sub-agents with `AgentTool`. + +## Structured input/output +- `inputSchema` means the incoming user message must be a JSON string matching the schema. +- `outputSchema` uses `Schema` + `Type` from `@google/genai` and forces JSON output. +- Do not rely on tools when `outputSchema` is set (tool use is not effective). +- `outputKey` saves the agent's final response text into `session.state[outputKey]`. + +## Context control +- `includeContents: "default"` sends prior history; `"none"` makes the agent stateless. +- For system-wide constraints, prefer a root-level global instruction (see multi-agent docs). + +## GenerateContentConfig +Use `GenerateContentConfig` from `@google/genai` for temperature, maxOutputTokens, and safety. +Do not place tools inside `generateContentConfig`. + +## Source +- https://google.github.io/adk-docs/agents/llm-agents/ +- https://google.github.io/adk-docs/agents/multi-agents/ diff --git a/skills/.curated/google-adk-js/references/models.md b/skills/.curated/google-adk-js/references/models.md new file mode 100644 index 0000000..1dd6d34 --- /dev/null +++ b/skills/.curated/google-adk-js/references/models.md @@ -0,0 +1,51 @@ +# Models and Authentication (TypeScript ADK) + +## Model selection +Pass a model string directly to `LlmAgent` for Gemini models. + +```ts +import {LlmAgent} from '@google/adk'; + +const agent = new LlmAgent({ + name: 'example_agent', + model: 'gemini-3-flash-preview', + instruction: 'You are helpful.', +}); +``` +If preview access is not enabled in your Vertex project, use `gemini-2.5-flash`. + +## Google AI Studio (API key) +Set environment variables for local dev: +```bash +export GOOGLE_GENAI_API_KEY="YOUR_GOOGLE_API_KEY" +# or export GEMINI_API_KEY="YOUR_GOOGLE_API_KEY" +export GOOGLE_GENAI_USE_VERTEXAI=FALSE +``` +API keys do not work with Vertex; use ADC or a service account when `GOOGLE_GENAI_USE_VERTEXAI=true`. + +## Vertex AI (Google Cloud) +Use ADC or service account and set: +```bash +export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID" +export GOOGLE_CLOUD_LOCATION="YOUR_VERTEX_AI_LOCATION" # e.g., us-central1 +export GOOGLE_GENAI_USE_VERTEXAI=TRUE +``` + +If using a service account key outside GCP: +```bash +export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json" +``` + +## Gemini 3 preview on Vertex +- Set `GOOGLE_CLOUD_LOCATION=global` for Gemini 3 preview models. +- Ensure your project/region has access to the preview model. +- If you see "Publisher Model ... was not found", verify the model string and region (global). + +## Model overrides +Set a custom model string: +```bash +export ADK_MODEL="gemini-3-flash-preview" +``` + +## Source +- https://google.github.io/adk-docs/agents/models/ diff --git a/skills/.curated/google-adk-js/references/quickstart.md b/skills/.curated/google-adk-js/references/quickstart.md new file mode 100644 index 0000000..d67edfa --- /dev/null +++ b/skills/.curated/google-adk-js/references/quickstart.md @@ -0,0 +1,94 @@ +# TypeScript Quickstart (ADK) + +## Summary +- Use Node.js 20.12.7+ and npm 9.2.0+. +- Create a minimal project with `agent.ts`, `package.json`, and `.env` (generate `tsconfig.json` later). +- Install `@google/adk` and `@google/adk-devtools`. + +## Project structure +``` +my-agent/ + agent.ts + package.json + .env +``` + +## Minimal agent example +```ts +import {FunctionTool, LlmAgent} from '@google/adk'; +import {z} from 'zod'; + +const getCurrentTime = new FunctionTool({ + name: 'get_current_time', + description: 'Returns the current time in a specified city.', + parameters: z.object({ + city: z.string().describe('The city name to retrieve the time for.'), + }), + execute: ({city}) => { + return {status: 'success', report: `The current time in ${city} is 10:30 AM`}; + }, +}); + +export const rootAgent = new LlmAgent({ + name: 'hello_time_agent', + model: 'gemini-3-flash-preview', + description: 'Tells the current time in a specified city.', + instruction: 'Use the get_current_time tool to answer time questions.', + tools: [getCurrentTime], +}); +``` +Note: Docs show `gemini-2.5-flash`. If your project does not have access to Gemini 3 preview, use `gemini-2.5-flash`. + +## Install and configure +```bash +npm init --yes +npm install -D typescript +npx tsc --init +npm install @google/adk @google/adk-devtools zod@^3 +``` + +Update `tsconfig.json`: +```json +{ + "compilerOptions": { + "verbatimModuleSyntax": false + } +} +``` + +Optional: set `main` in `package.json` to `agent.ts`. + +## Compile +```bash +npx tsc +``` + +## API key +Create `.env`: +```bash +echo 'GEMINI_API_KEY="YOUR_API_KEY"' > .env +``` +ADK reads `GEMINI_API_KEY` or `GOOGLE_GENAI_API_KEY` for Gemini API mode. + +## Vertex AI +```bash +export GOOGLE_GENAI_USE_VERTEXAI=true +export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID" +export GOOGLE_CLOUD_LOCATION="us-central1" +``` +For Gemini 3 preview models on Vertex, use `GOOGLE_CLOUD_LOCATION=global`. + +## Run +```bash +npx @google/adk-devtools run agent.ts +``` + +Web dev UI: +```bash +npx @google/adk-devtools web +``` + +Note: ADK Web UI is for development only. + +## Source +- https://google.github.io/adk-docs/get-started/typescript/ diff --git a/skills/.curated/google-adk-js/references/samples.md b/skills/.curated/google-adk-js/references/samples.md new file mode 100644 index 0000000..f907b85 --- /dev/null +++ b/skills/.curated/google-adk-js/references/samples.md @@ -0,0 +1,22 @@ +# ADK TypeScript Samples + +## Repository +- https://github.com/google/adk-samples + +## Layout +The TypeScript samples live under: +``` +adk-samples/typescript + agents/ + / + README.md +``` + +## Typical workflow +1. Clone the repo: `git clone https://github.com/google/adk-samples.git` +2. Go to `adk-samples/typescript`. +3. Pick an agent in `agents/` and follow its README. +4. Copy patterns into your project (agent structure, tools, env vars). + +## Source +- https://github.com/google/adk-samples/tree/main/typescript diff --git a/skills/.curated/google-adk-js/references/tools.md b/skills/.curated/google-adk-js/references/tools.md new file mode 100644 index 0000000..b07e90e --- /dev/null +++ b/skills/.curated/google-adk-js/references/tools.md @@ -0,0 +1,68 @@ +# Tools (TypeScript ADK) + +## Built-in tools +Use built-in tools from `@google/adk` and pass them in `tools`. + +```ts +import {LlmAgent, GOOGLE_SEARCH} from '@google/adk'; + +const agent = new LlmAgent({ + name: 'search_assistant', + model: 'gemini-3-flash-preview', + instruction: 'Answer questions using Google Search when needed.', + tools: [GOOGLE_SEARCH], +}); +``` + +Some tools cannot be combined in a single agent. If you hit a tool limit, check: +- https://google.github.io/adk-docs/tools/limitations/ +If a tool is marked one-tool-per-agent, split it into a dedicated sub-agent and call it via `AgentTool`. + +## FunctionTool pattern +Define parameters with Zod and return an object. + +```ts +import {FunctionTool} from '@google/adk'; +import {z} from 'zod'; + +async function getStockPrice({ticker}: {ticker: string}) { + return {status: 'success', price: '$123.45'}; +} + +const getStockPriceTool = new FunctionTool({ + name: 'get_stock_price', + description: 'Gets the current price of a stock.', + parameters: z.object({ + ticker: z.string().describe('Stock ticker symbol.'), + }), + execute: getStockPrice, +}); +``` + +### Tool schema compatibility +- Pin `zod` to v3 when targeting Vertex tool calls. Zod v4 can emit schema fields that Vertex rejects (e.g. `~standard`, `def`). +- Avoid passing tools via `generateContentConfig.tools`; always use `LlmAgent.tools`. + +## Agent-as-a-Tool +Wrap another agent with `AgentTool`. + +```ts +import {AgentTool, LlmAgent} from '@google/adk'; + +const summarizer = new LlmAgent({ + name: 'summary_agent', + model: 'gemini-3-flash-preview', + instruction: 'Summarize the given text.', +}); + +const mainAgent = new LlmAgent({ + name: 'main_agent', + model: 'gemini-3-flash-preview', + instruction: 'Use the summary_agent for long texts.', + tools: [new AgentTool({agent: summarizer, skipSummarization: true})], +}); +``` + +## Source +- https://google.github.io/adk-docs/tools/ +- https://google.github.io/adk-docs/tools-custom/function-tools/