@intentsolutionsio/jeremy-genkit-pro 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,493 @@
1
+ # Examples — Genkit Production Expert
2
+
3
+ ## Example 1: Question-Answering Flow with Zod Schemas
4
+
5
+ A simple Genkit flow with typed input/output, temperature tuning, and token monitoring.
6
+
7
+ ### Setup
8
+
9
+ ```bash
10
+ npm install genkit @genkit-ai/googleai zod
11
+ npm install -D typescript tsx
12
+ ```
13
+
14
+ ### Flow Implementation
15
+
16
+ ```typescript
17
+ // src/qa-flow.ts
18
+ import { genkit, z } from "genkit";
19
+ import { googleAI, gemini25Flash } from "@genkit-ai/googleai";
20
+
21
+ const ai = genkit({
22
+ plugins: [googleAI()],
23
+ });
24
+
25
+ // Strict input/output schemas
26
+ const QuestionInput = z.object({
27
+ question: z.string().min(3).describe("The user question"),
28
+ context: z.string().optional().describe("Optional context to ground the answer"),
29
+ maxWords: z.number().min(10).max(500).default(150),
30
+ });
31
+
32
+ const AnswerOutput = z.object({
33
+ answer: z.string(),
34
+ confidence: z.enum(["high", "medium", "low"]),
35
+ tokenUsage: z.object({
36
+ input: z.number(),
37
+ output: z.number(),
38
+ }),
39
+ });
40
+
41
+ export const qaFlow = ai.defineFlow(
42
+ {
43
+ name: "question-answer",
44
+ inputSchema: QuestionInput,
45
+ outputSchema: AnswerOutput,
46
+ },
47
+ async (input) => {
48
+ const contextBlock = input.context
49
+ ? `\n\nContext:\n${input.context}`
50
+ : "";
51
+
52
+ const { text, usage } = await ai.generate({
53
+ model: gemini25Flash,
54
+ prompt: `Answer the following question in at most ${input.maxWords} words.
55
+ If you are unsure, say so and rate your confidence as "low".${contextBlock}
56
+
57
+ Question: ${input.question}
58
+
59
+ Respond in JSON format:
60
+ {"answer": "...", "confidence": "high|medium|low"}`,
61
+ config: {
62
+ temperature: 0.3,
63
+ maxOutputTokens: 1024,
64
+ },
65
+ });
66
+
67
+ const parsed = JSON.parse(text);
68
+
69
+ return {
70
+ answer: parsed.answer,
71
+ confidence: parsed.confidence,
72
+ tokenUsage: {
73
+ input: usage?.inputTokens ?? 0,
74
+ output: usage?.outputTokens ?? 0,
75
+ },
76
+ };
77
+ }
78
+ );
79
+
80
+ // Start local server for testing with Genkit Developer UI
81
+ ai.startFlowServer({ flows: [qaFlow] });
82
+ ```
83
+
84
+ ### Local Testing
85
+
86
+ ```bash
87
+ # Start the Genkit dev server
88
+ npx genkit start -- tsx src/qa-flow.ts
89
+
90
+ # Test with curl
91
+ curl -X POST http://localhost:3400/question-answer \
92
+ -H "Content-Type: application/json" \
93
+ -d '{"question": "What is Firebase Genkit?", "maxWords": 100}'
94
+ ```
95
+
96
+ ### Expected Output
97
+
98
+ ```json
99
+ {
100
+ "answer": "Firebase Genkit is an open-source framework for building AI-powered applications. It provides a unified API for defining flows (multi-step AI pipelines), tools (external capabilities), and retrievers (document search). Genkit supports multiple model providers including Google Gemini, has built-in observability via OpenTelemetry, and deploys to Firebase Functions or Cloud Run. It is available for Node.js, Python, and Go.",
101
+ "confidence": "high",
102
+ "tokenUsage": {
103
+ "input": 82,
104
+ "output": 94
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### Deploy to Firebase Functions
110
+
111
+ ```typescript
112
+ // src/index.ts — Firebase Functions entry point
113
+ import { onFlow } from "@genkit-ai/firebase/functions";
114
+ import { qaFlow } from "./qa-flow";
115
+
116
+ export const questionAnswer = onFlow(
117
+ {
118
+ name: "question-answer",
119
+ httpsOptions: {
120
+ cors: true,
121
+ memory: "512MiB",
122
+ minInstances: 1,
123
+ },
124
+ },
125
+ qaFlow
126
+ );
127
+ ```
128
+
129
+ ```bash
130
+ firebase deploy --only functions
131
+ # Function URL: https://us-central1-my-project.cloudfunctions.net/questionAnswer
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Example 2: RAG Flow with Firestore Vector Search
137
+
138
+ Retrieve documents, inject as context, and generate grounded answers with source citations.
139
+
140
+ ```typescript
141
+ // src/rag-flow.ts
142
+ import { genkit, z } from "genkit";
143
+ import { googleAI, gemini25Flash, textEmbedding004 } from "@genkit-ai/googleai";
144
+ import { Firestore, FieldValue } from "firebase-admin/firestore";
145
+ import { initializeApp } from "firebase-admin/app";
146
+
147
+ initializeApp();
148
+ const db = new Firestore();
149
+
150
+ const ai = genkit({
151
+ plugins: [googleAI()],
152
+ });
153
+
154
+ // Retriever: query Firestore vector index
155
+ const docRetriever = ai.defineRetriever(
156
+ { name: "firestore-knowledge-base" },
157
+ async (query: string, options?: { k?: number }) => {
158
+ const k = options?.k ?? 5;
159
+
160
+ // Generate query embedding
161
+ const { embedding } = await ai.embed({
162
+ embedder: textEmbedding004,
163
+ content: query,
164
+ });
165
+
166
+ // Vector similarity search in Firestore
167
+ const snapshot = await db
168
+ .collection("knowledge_base")
169
+ .findNearest("embedding", embedding, {
170
+ limit: k,
171
+ distanceMeasure: "COSINE",
172
+ })
173
+ .get();
174
+
175
+ return snapshot.docs.map((doc) => ({
176
+ content: doc.data().text as string,
177
+ metadata: {
178
+ id: doc.id,
179
+ title: doc.data().title as string,
180
+ category: doc.data().category as string,
181
+ lastUpdated: doc.data().updatedAt?.toDate()?.toISOString() ?? "",
182
+ },
183
+ }));
184
+ }
185
+ );
186
+
187
+ // Indexer: add documents to the vector store
188
+ const docIndexer = ai.defineIndexer(
189
+ { name: "firestore-indexer" },
190
+ async (docs) => {
191
+ const batch = db.batch();
192
+ for (const doc of docs) {
193
+ const { embedding } = await ai.embed({
194
+ embedder: textEmbedding004,
195
+ content: doc.content,
196
+ });
197
+ const ref = db.collection("knowledge_base").doc();
198
+ batch.set(ref, {
199
+ text: doc.content,
200
+ title: doc.metadata?.title ?? "Untitled",
201
+ category: doc.metadata?.category ?? "general",
202
+ embedding,
203
+ updatedAt: FieldValue.serverTimestamp(),
204
+ });
205
+ }
206
+ await batch.commit();
207
+ }
208
+ );
209
+
210
+ // RAG flow
211
+ const RagInput = z.object({
212
+ question: z.string().min(1),
213
+ topK: z.number().min(1).max(20).default(5),
214
+ });
215
+
216
+ const RagOutput = z.object({
217
+ answer: z.string(),
218
+ sources: z.array(z.object({
219
+ title: z.string(),
220
+ category: z.string(),
221
+ snippet: z.string(),
222
+ })),
223
+ cached: z.boolean(),
224
+ });
225
+
226
+ // Simple in-memory cache for repeated queries
227
+ const queryCache = new Map<string, { result: z.infer<typeof RagOutput>; expiry: number }>();
228
+ const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
229
+
230
+ export const ragFlow = ai.defineFlow(
231
+ {
232
+ name: "rag-search",
233
+ inputSchema: RagInput,
234
+ outputSchema: RagOutput,
235
+ },
236
+ async (input) => {
237
+ // Check cache
238
+ const cacheKey = `${input.question}:${input.topK}`;
239
+ const cached = queryCache.get(cacheKey);
240
+ if (cached && cached.expiry > Date.now()) {
241
+ return { ...cached.result, cached: true };
242
+ }
243
+
244
+ // Retrieve relevant documents
245
+ const docs = await ai.retrieve({
246
+ retriever: docRetriever,
247
+ query: input.question,
248
+ options: { k: input.topK },
249
+ });
250
+
251
+ if (docs.length === 0) {
252
+ return {
253
+ answer: "I could not find any relevant documents to answer your question.",
254
+ sources: [],
255
+ cached: false,
256
+ };
257
+ }
258
+
259
+ // Build numbered context
260
+ const context = docs
261
+ .map((d, i) => `[${i + 1}] (${d.metadata?.category}) ${d.metadata?.title}\n${d.content}`)
262
+ .join("\n\n---\n\n");
263
+
264
+ // Generate grounded answer
265
+ const { text } = await ai.generate({
266
+ model: gemini25Flash,
267
+ prompt: `You are a knowledge base assistant. Answer ONLY using the provided sources.
268
+ Cite sources using [1], [2], etc. If the sources don't cover the question, say so.
269
+
270
+ Sources:
271
+ ${context}
272
+
273
+ Question: ${input.question}`,
274
+ config: { temperature: 0.2, maxOutputTokens: 1024 },
275
+ });
276
+
277
+ const result: z.infer<typeof RagOutput> = {
278
+ answer: text,
279
+ sources: docs.map((d) => ({
280
+ title: d.metadata?.title ?? "Unknown",
281
+ category: d.metadata?.category ?? "general",
282
+ snippet: d.content.substring(0, 150) + "...",
283
+ })),
284
+ cached: false,
285
+ };
286
+
287
+ // Cache the result
288
+ queryCache.set(cacheKey, { result, expiry: Date.now() + CACHE_TTL_MS });
289
+
290
+ return result;
291
+ }
292
+ );
293
+
294
+ ai.startFlowServer({ flows: [ragFlow] });
295
+ ```
296
+
297
+ ### Expected Output
298
+
299
+ ```json
300
+ {
301
+ "answer": "To set up VPC Service Controls for Vertex AI, you need to: 1) Create an access policy and service perimeter in Access Context Manager [1], 2) Add aiplatform.googleapis.com to the restricted services list [1], 3) Configure access levels for your CI/CD service accounts [2], and 4) Test access from both inside and outside the perimeter [3]. Changes propagate within 30 minutes.",
302
+ "sources": [
303
+ {
304
+ "title": "VPC-SC Configuration Guide",
305
+ "category": "security",
306
+ "snippet": "VPC Service Controls create a security perimeter around GCP resources. To configure for Vertex AI..."
307
+ },
308
+ {
309
+ "title": "CI/CD Pipeline Security",
310
+ "category": "devops",
311
+ "snippet": "Service accounts used in CI/CD pipelines need explicit access levels in the VPC-SC perimeter..."
312
+ },
313
+ {
314
+ "title": "Agent Engine Deployment Checklist",
315
+ "category": "deployment",
316
+ "snippet": "Before deploying to production, verify that VPC-SC perimeters allow the agent service account..."
317
+ }
318
+ ],
319
+ "cached": false
320
+ }
321
+ ```
322
+
323
+ ---
324
+
325
+ ## Example 3: Multi-Tool Agent Flow
326
+
327
+ Define tools with typed schemas, route user queries, and trace tool execution.
328
+
329
+ ```typescript
330
+ // src/agent-flow.ts
331
+ import { genkit, z } from "genkit";
332
+ import { googleAI, gemini25Flash } from "@genkit-ai/googleai";
333
+
334
+ const ai = genkit({
335
+ plugins: [googleAI()],
336
+ });
337
+
338
+ // Tool 1: Weather lookup
339
+ const getWeather = ai.defineTool(
340
+ {
341
+ name: "getWeather",
342
+ description: "Get current weather for a city",
343
+ inputSchema: z.object({
344
+ city: z.string().describe("City name, e.g. 'San Francisco'"),
345
+ }),
346
+ outputSchema: z.object({
347
+ city: z.string(),
348
+ tempF: z.number(),
349
+ condition: z.string(),
350
+ humidity: z.number(),
351
+ }),
352
+ },
353
+ async ({ city }) => {
354
+ // In production, call a real weather API
355
+ const mockWeather: Record<string, { tempF: number; condition: string; humidity: number }> = {
356
+ "san francisco": { tempF: 62, condition: "Foggy", humidity: 78 },
357
+ "new york": { tempF: 45, condition: "Cloudy", humidity: 55 },
358
+ "austin": { tempF: 85, condition: "Sunny", humidity: 40 },
359
+ };
360
+ const data = mockWeather[city.toLowerCase()] ?? { tempF: 70, condition: "Unknown", humidity: 50 };
361
+ return { city, ...data };
362
+ }
363
+ );
364
+
365
+ // Tool 2: Calendar event creation
366
+ const createEvent = ai.defineTool(
367
+ {
368
+ name: "createEvent",
369
+ description: "Create a calendar event",
370
+ inputSchema: z.object({
371
+ title: z.string(),
372
+ date: z.string().describe("ISO date string, e.g. 2025-03-20"),
373
+ startTime: z.string().describe("Start time, e.g. 14:00"),
374
+ durationMinutes: z.number().min(15).max(480),
375
+ }),
376
+ outputSchema: z.object({
377
+ eventId: z.string(),
378
+ title: z.string(),
379
+ scheduledAt: z.string(),
380
+ confirmed: z.boolean(),
381
+ }),
382
+ },
383
+ async ({ title, date, startTime, durationMinutes }) => {
384
+ const eventId = `evt_${Date.now().toString(36)}`;
385
+ return {
386
+ eventId,
387
+ title,
388
+ scheduledAt: `${date}T${startTime}:00`,
389
+ confirmed: true,
390
+ };
391
+ }
392
+ );
393
+
394
+ // Agent flow with multi-turn tool usage
395
+ const AgentInput = z.object({
396
+ message: z.string(),
397
+ sessionId: z.string().optional(),
398
+ });
399
+
400
+ const AgentOutput = z.object({
401
+ reply: z.string(),
402
+ toolsUsed: z.array(z.string()),
403
+ });
404
+
405
+ export const agentFlow = ai.defineFlow(
406
+ {
407
+ name: "assistant-agent",
408
+ inputSchema: AgentInput,
409
+ outputSchema: AgentOutput,
410
+ },
411
+ async (input) => {
412
+ const { text, toolRequests } = await ai.generate({
413
+ model: gemini25Flash,
414
+ tools: [getWeather, createEvent],
415
+ prompt: input.message,
416
+ system: `You are a helpful assistant with access to weather and calendar tools.
417
+ Use tools when the user asks about weather or wants to schedule something.
418
+ Be concise in your responses.`,
419
+ config: { temperature: 0.5 },
420
+ });
421
+
422
+ const toolsUsed = (toolRequests ?? []).map((t) => t.toolName);
423
+
424
+ return {
425
+ reply: text,
426
+ toolsUsed,
427
+ };
428
+ }
429
+ );
430
+
431
+ ai.startFlowServer({ flows: [agentFlow] });
432
+ ```
433
+
434
+ ### Testing
435
+
436
+ ```bash
437
+ # Weather query
438
+ curl -X POST http://localhost:3400/assistant-agent \
439
+ -H "Content-Type: application/json" \
440
+ -d '{"message": "What is the weather in San Francisco?"}'
441
+
442
+ # Calendar + weather combined
443
+ curl -X POST http://localhost:3400/assistant-agent \
444
+ -H "Content-Type: application/json" \
445
+ -d '{"message": "Schedule a picnic tomorrow at 2pm for 2 hours. Also check the weather in Austin."}'
446
+ ```
447
+
448
+ ### Expected Output
449
+
450
+ Weather query:
451
+ ```json
452
+ {
453
+ "reply": "The weather in San Francisco is currently 62F and foggy with 78% humidity. You might want to bring a jacket!",
454
+ "toolsUsed": ["getWeather"]
455
+ }
456
+ ```
457
+
458
+ Combined query:
459
+ ```json
460
+ {
461
+ "reply": "I've scheduled your picnic for tomorrow at 2:00 PM (2 hours). The weather in Austin looks great - 85F, sunny, and 40% humidity. Perfect picnic weather!",
462
+ "toolsUsed": ["createEvent", "getWeather"]
463
+ }
464
+ ```
465
+
466
+ ### Cloud Run Deployment
467
+
468
+ ```bash
469
+ # Dockerfile
470
+ cat > Dockerfile << 'DOCKERFILE'
471
+ FROM node:20-slim
472
+ WORKDIR /app
473
+ COPY package*.json ./
474
+ RUN npm ci --production
475
+ COPY dist/ ./dist/
476
+ ENV PORT=8080
477
+ EXPOSE 8080
478
+ CMD ["node", "dist/agent-flow.js"]
479
+ DOCKERFILE
480
+
481
+ # Deploy
482
+ gcloud run deploy genkit-agent \
483
+ --source . \
484
+ --region us-central1 \
485
+ --memory 512Mi \
486
+ --min-instances 2 \
487
+ --max-instances 10 \
488
+ --set-secrets "GOOGLE_GENAI_API_KEY=genai-api-key:latest" \
489
+ --allow-unauthenticated
490
+ ```
491
+
492
+ ---
493
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
@@ -0,0 +1,55 @@
1
+ # How It Works
2
+
3
+ ## How It Works
4
+
5
+ ### Phase 1: Requirements Analysis
6
+ ```
7
+ User Request → Analyze needs → Determine:
8
+ - Target language (Node.js/Python/Go)
9
+ - Flow complexity (simple/multi-step/RAG)
10
+ - Model requirements (Gemini version, custom models)
11
+ - Deployment target (Firebase/Cloud Run/local)
12
+ ```
13
+
14
+ ### Phase 2: Project Setup
15
+ ```
16
+ Check existing project → If new:
17
+ - Initialize project structure
18
+ - Install dependencies
19
+ - Configure environment variables
20
+ - Set up TypeScript/Python/Go config
21
+
22
+ If existing:
23
+ - Analyze current structure
24
+ - Identify integration points
25
+ - Preserve existing code
26
+ ```
27
+
28
+ ### Phase 3: Implementation
29
+ ```
30
+ Design flow architecture → Implement:
31
+ - Input/output schemas (Zod/Pydantic/Go structs)
32
+ - Model configuration
33
+ - Tool definitions (if needed)
34
+ - Retriever setup (for RAG)
35
+ - Error handling
36
+ - Tracing configuration
37
+ ```
38
+
39
+ ### Phase 4: Testing & Validation
40
+ ```
41
+ Create test cases → Run locally:
42
+ - Genkit Developer UI
43
+ - Unit tests
44
+ - Integration tests
45
+ - Token usage analysis
46
+ ```
47
+
48
+ ### Phase 5: Production Deployment
49
+ ```
50
+ Configure deployment → Deploy:
51
+ - Firebase Functions (with AI monitoring)
52
+ - Cloud Run (with auto-scaling)
53
+ - Set up monitoring dashboards
54
+ - Configure alerting
55
+ ```
@@ -0,0 +1,40 @@
1
+ # Production Best Practices Applied
2
+
3
+ ## Production Best Practices Applied
4
+
5
+ ### 1. Schema Validation
6
+ - All inputs/outputs use Zod (TS), Pydantic (Python), or structs (Go)
7
+ - Prevents runtime errors from malformed data
8
+
9
+ ### 2. Error Handling
10
+ ```typescript
11
+ try {
12
+ const result = await ai.generate({...});
13
+ return result;
14
+ } catch (error) {
15
+ if (error.code === 'SAFETY_BLOCK') {
16
+ // Handle safety filters
17
+ } else if (error.code === 'QUOTA_EXCEEDED') {
18
+ // Handle rate limits
19
+ }
20
+ throw error;
21
+ }
22
+ ```
23
+
24
+ ### 3. Cost Optimization
25
+ - Context caching for repeated prompts
26
+ - Token usage monitoring
27
+ - Temperature tuning for use case
28
+ - Model selection (Flash vs Pro)
29
+
30
+ ### 4. Monitoring
31
+ - OpenTelemetry tracing enabled
32
+ - Custom span attributes
33
+ - Firebase Console integration
34
+ - Alert configuration
35
+
36
+ ### 5. Security
37
+ - Environment variable management
38
+ - API key rotation support
39
+ - Input sanitization
40
+ - Output filtering
@@ -0,0 +1,105 @@
1
+ # Workflow Examples
2
+
3
+ ## Workflow Examples
4
+
5
+ ### Example 1: Simple Question-Answering Flow
6
+
7
+ **User Request**: "Create a Genkit flow that answers user questions using Gemini 2.5 Flash"
8
+
9
+ **Skill Response**:
10
+ 1. Creates TypeScript project (default)
11
+ 2. Implements flow with input validation:
12
+ ```typescript
13
+ const qaFlow = ai.defineFlow(
14
+ {
15
+ name: 'qaFlow',
16
+ inputSchema: z.object({ question: z.string() }),
17
+ outputSchema: z.object({ answer: z.string() }),
18
+ },
19
+ async (input) => {
20
+ const { text } = await ai.generate({
21
+ model: gemini25Flash,
22
+ prompt: `Answer this question: ${input.question}`,
23
+ config: { temperature: 0.3 }, // Lower for factual answers
24
+ });
25
+ return { answer: text };
26
+ }
27
+ );
28
+ ```
29
+ 3. Sets up local testing
30
+ 4. Provides deployment instructions
31
+
32
+ ### Example 2: RAG System with Vector Search
33
+
34
+ **User Request**: "Implement RAG with Genkit for our documentation search"
35
+
36
+ **Skill Response**:
37
+ 1. Analyzes document storage needs
38
+ 2. Implements retriever with embeddings:
39
+ ```typescript
40
+ const docRetriever = ai.defineRetriever(
41
+ {
42
+ name: 'docRetriever',
43
+ configSchema: z.object({ k: z.number().default(5) }),
44
+ },
45
+ async (query, config) => {
46
+ // Generate embedding
47
+ const embedding = await ai.embed({
48
+ embedder: textEmbedding004,
49
+ content: query,
50
+ });
51
+
52
+ // Search vector database
53
+ const results = await vectorDB.search(embedding, config.k);
54
+ return results.map(doc => ({
55
+ content: doc.text,
56
+ metadata: { source: doc.source },
57
+ }));
58
+ }
59
+ );
60
+ ```
61
+ 3. Creates RAG flow combining retrieval + generation
62
+ 4. Sets up vector database connection
63
+ 5. Implements caching for efficiency
64
+
65
+ ### Example 3: Multi-Agent Tool Calling
66
+
67
+ **User Request**: "Create a Genkit agent with weather and calendar tools"
68
+
69
+ **Skill Response**:
70
+ 1. Defines tools with proper schemas:
71
+ ```typescript
72
+ const weatherTool = ai.defineTool({
73
+ name: 'getWeather',
74
+ description: 'Get current weather for a location',
75
+ inputSchema: z.object({ location: z.string() }),
76
+ outputSchema: z.object({
77
+ temp: z.number(),
78
+ conditions: z.string(),
79
+ }),
80
+ }, async ({ location }) => {
81
+ // Call weather API
82
+ });
83
+
84
+ const calendarTool = ai.defineTool({
85
+ name: 'checkCalendar',
86
+ description: 'Check calendar availability',
87
+ inputSchema: z.object({ date: z.string() }),
88
+ outputSchema: z.object({ available: z.boolean() }),
89
+ }, async ({ date }) => {
90
+ // Check calendar API
91
+ });
92
+ ```
93
+ 2. Creates agent flow with tool access:
94
+ ```typescript
95
+ const agentFlow = ai.defineFlow(async (userQuery) => {
96
+ const { text } = await ai.generate({
97
+ model: gemini25Flash,
98
+ prompt: userQuery,
99
+ tools: [weatherTool, calendarTool],
100
+ });
101
+ return text;
102
+ });
103
+ ```
104
+ 3. Implements proper error handling
105
+ 4. Sets up tool execution tracing