everything-gemini 1.9.0 → 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.
- package/CHANGELOG.md +48 -0
- package/README.md +32 -5
- package/agents/mlops-engineer.md +33 -0
- package/bin/everything-gemini +680 -6
- package/docs/LAUNCH_KIT_v2.0.0.md +187 -0
- package/docs/LAUNCH_KIT_v2.1.0.md +118 -0
- package/docs/architecture/progressive-disclosure.md +3 -3
- package/docs/index.html +23 -10
- package/examples/python-sdk/README.md +8 -0
- package/examples/python-sdk/autonomous_mlops_rag_pipeline.py +254 -0
- package/examples/python-sdk/harness2_recursive_loop.py +240 -0
- package/hooks/budget-guard/hooks.json +16 -0
- package/hooks/budget-guard/scripts/budget-gate.sh +57 -0
- package/mcp/README.md +1 -0
- package/mcp/mcp_config.example.json +7 -0
- package/package.json +1 -1
- package/scripts/harness_rollback.sh +26 -0
- package/scripts/harness_snapshot.sh +30 -0
- package/scripts/validate.sh +1 -1
- package/skills/chromadb-vector-store/SKILL.md +188 -0
- package/skills/dataproc-spark-analytics/SKILL.md +120 -0
- package/skills/google-flow-orchestrator/SKILL.md +174 -0
- package/skills/harness2-recursive-optimization/SKILL.md +240 -0
- package/skills/keda-event-autoscaling/SKILL.md +218 -0
- package/skills/opa-gatekeeper-policy/SKILL.md +200 -0
- package/skills/triton-inference-server/SKILL.md +221 -0
- package/templates/full-power/mcp_config.json +7 -0
- package/tests/cli.test.js +160 -11
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chromadb-vector-store
|
|
3
|
+
description: Implements ChromaDB persistent vector storage, multi-modal embeddings, collection partitioning, metadata filtering, and semantic similarity search.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ChromaDB Vector Store
|
|
7
|
+
|
|
8
|
+
Provides production patterns for embedding generation, persistent collection management, metadata-filtered semantic retrieval, and hybrid search using ChromaDB.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Client Architecture
|
|
13
|
+
|
|
14
|
+
ChromaDB operates in three deployment modes depending on scale and latency requirements:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
In-Process Ephemeral Local Persistent Client / Server
|
|
18
|
+
┌──────────────────────┐ ┌───────────────────────┐ ┌────────────────────────┐
|
|
19
|
+
│ chromadb.Client() │ │ PersistentClient(path)│ │ HttpClient(host, port) │
|
|
20
|
+
│ (Unit Tests & CI) │ │ (Embedded SQLite/HNSW)│ │ (Kubernetes / Docker) │
|
|
21
|
+
└──────────────────────┘ └───────────────────────┘ └────────────────────────┘
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
import chromadb
|
|
26
|
+
from chromadb.config import Settings
|
|
27
|
+
|
|
28
|
+
# Production persistent client with DuckDB + HNSW backend
|
|
29
|
+
client = chromadb.PersistentClient(
|
|
30
|
+
path="./data/chroma",
|
|
31
|
+
settings=Settings(
|
|
32
|
+
anonymized_telemetry=False,
|
|
33
|
+
allow_reset=False,
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 2. Gemini Embeddings & Collection Creation
|
|
41
|
+
|
|
42
|
+
Integrates native Gemini embeddings (`text-embedding-004`) with custom collection metrics:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import chromadb
|
|
46
|
+
from chromadb.api.types import Documents, EmbeddingFunction, Embeddings
|
|
47
|
+
from google import genai
|
|
48
|
+
|
|
49
|
+
class GeminiEmbeddingFunction(EmbeddingFunction):
|
|
50
|
+
def __init__(self, model_name: str = "text-embedding-004"):
|
|
51
|
+
self.client = genai.Client()
|
|
52
|
+
self.model_name = model_name
|
|
53
|
+
|
|
54
|
+
def __call__(self, input: Documents) -> Embeddings:
|
|
55
|
+
response = self.client.models.embed_content(
|
|
56
|
+
model=self.model_name,
|
|
57
|
+
contents=input,
|
|
58
|
+
)
|
|
59
|
+
return [e.values for e in response.embeddings]
|
|
60
|
+
|
|
61
|
+
gemini_ef = GeminiEmbeddingFunction()
|
|
62
|
+
|
|
63
|
+
# Create or get collection with Cosine distance metric
|
|
64
|
+
collection = client.get_or_create_collection(
|
|
65
|
+
name="technical_runbooks_v2",
|
|
66
|
+
embedding_function=gemini_ef,
|
|
67
|
+
metadata={"hnsw:space": "cosine", "description": "Antigravity skills catalog"}
|
|
68
|
+
)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 3. High-Throughput Batch Upsert
|
|
74
|
+
|
|
75
|
+
Batch insertion ensures zero duplicate embeddings and enforces metadata schemas:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from typing import List, Dict, Any
|
|
79
|
+
|
|
80
|
+
def upsert_knowledge_batch(
|
|
81
|
+
collection,
|
|
82
|
+
doc_ids: List[str],
|
|
83
|
+
texts: List[str],
|
|
84
|
+
metadatas: List[Dict[str, Any]]
|
|
85
|
+
):
|
|
86
|
+
"""Upserts documents in batches of 500 to stay within gRPC frame limits."""
|
|
87
|
+
batch_size = 500
|
|
88
|
+
for i in range(0, len(doc_ids), batch_size):
|
|
89
|
+
chunk_ids = doc_ids[i:i + batch_size]
|
|
90
|
+
chunk_texts = texts[i:i + batch_size]
|
|
91
|
+
chunk_metas = metadatas[i:i + batch_size]
|
|
92
|
+
|
|
93
|
+
collection.upsert(
|
|
94
|
+
ids=chunk_ids,
|
|
95
|
+
documents=chunk_texts,
|
|
96
|
+
metadatas=chunk_metas
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 4. Metadata Filtering & Semantic Search
|
|
103
|
+
|
|
104
|
+
Queries can filter across Boolean operators (`$and`, `$or`), numerical ranges, and substring matching:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
results = collection.query(
|
|
108
|
+
query_texts=["How do I configure KEDA ScaledObjects for Kafka?"],
|
|
109
|
+
n_results=5,
|
|
110
|
+
where={
|
|
111
|
+
"$and": [
|
|
112
|
+
{"category": {"$eq": "devops"}},
|
|
113
|
+
{"security_tier": {"$lte": 2}},
|
|
114
|
+
{"status": {"$ne": "deprecated"}}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
where_document={"$contains": "ScaledObject"},
|
|
118
|
+
include=["documents", "metadatas", "distances"]
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Parse matched documents
|
|
122
|
+
for idx, (doc, meta, dist) in enumerate(zip(
|
|
123
|
+
results["documents"][0],
|
|
124
|
+
results["metadatas"][0],
|
|
125
|
+
results["distances"][0]
|
|
126
|
+
)):
|
|
127
|
+
similarity_score = 1.0 - dist
|
|
128
|
+
print(f"[{idx+1}] Score: {similarity_score:.4f} | ID: {results['ids'][0][idx]}")
|
|
129
|
+
print(f" Title: {meta.get('title')} (v{meta.get('version')})")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 5. Dockerized Server Deployment
|
|
135
|
+
|
|
136
|
+
For multi-tenant or distributed Antigravity agents:
|
|
137
|
+
|
|
138
|
+
```yaml
|
|
139
|
+
# compose.chroma.yml
|
|
140
|
+
version: "3.9"
|
|
141
|
+
services:
|
|
142
|
+
chromadb:
|
|
143
|
+
image: chromadb/chroma:0.5.23
|
|
144
|
+
ports:
|
|
145
|
+
- "8000:8000"
|
|
146
|
+
environment:
|
|
147
|
+
- IS_PERSISTENT=TRUE
|
|
148
|
+
- PERSISTENCE_DIRECTORY=/chroma/chroma
|
|
149
|
+
- ANONYMIZED_TELEMETRY=FALSE
|
|
150
|
+
volumes:
|
|
151
|
+
- chroma_data:/chroma/chroma
|
|
152
|
+
healthcheck:
|
|
153
|
+
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/heartbeat"]
|
|
154
|
+
interval: 10s
|
|
155
|
+
timeout: 5s
|
|
156
|
+
retries: 3
|
|
157
|
+
|
|
158
|
+
volumes:
|
|
159
|
+
chroma_data:
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# Connect via HTTP
|
|
164
|
+
remote_client = chromadb.HttpClient(
|
|
165
|
+
host="localhost",
|
|
166
|
+
port=8000,
|
|
167
|
+
headers={"X-Chroma-Token": "secret-auth-token"}
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 6. Verification and Maintenance
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Verify Chroma API heartbeat
|
|
177
|
+
curl -s http://localhost:8000/api/v1/heartbeat | jq .
|
|
178
|
+
|
|
179
|
+
# Check active collections count and schema
|
|
180
|
+
curl -s http://localhost:8000/api/v1/collections | jq '.[].name'
|
|
181
|
+
|
|
182
|
+
# Reset collection or clean expired embeddings safely
|
|
183
|
+
python -c "
|
|
184
|
+
import chromadb
|
|
185
|
+
client = chromadb.PersistentClient('./data/chroma')
|
|
186
|
+
print(f'Collections: {len(client.list_collections())}')
|
|
187
|
+
"
|
|
188
|
+
```
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dataproc-spark-analytics
|
|
3
|
+
description: Deploys and tunes Google Cloud Dataproc Serverless Spark, PySpark batch pipelines, BigLake vector indexing, and Data Agent Kit telemetry.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dataproc Spark Analytics
|
|
7
|
+
|
|
8
|
+
Orchestrates large-scale distributed data processing, feature engineering, and high-throughput vector embedding generation using Google Cloud Dataproc Serverless Spark and PySpark.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Architecture: Dataproc Serverless & Agentic Big Data
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Google Cloud Storage / BigLake Dataproc Serverless Gemini Vector Index
|
|
16
|
+
┌─────────────────────────────┐ ┌────────────────────────┐ ┌────────────────────────┐
|
|
17
|
+
│ Raw Document Lakes │────>│ Serverless PySpark │────>│ BigQuery Vector Search │
|
|
18
|
+
│ (Parquet, JSON, Delta/Ice) │ │ Batch Executors │ │ / Milvus / ChromaDB │
|
|
19
|
+
└─────────────────────────────┘ └───────────┬────────────┘ └────────────────────────┘
|
|
20
|
+
│
|
|
21
|
+
┌───────────▼────────────┐
|
|
22
|
+
│ Gemini Embedding API │
|
|
23
|
+
│ (text-embedding-004) │
|
|
24
|
+
└────────────────────────┘
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **Zero Cluster Management**: Runs ad-hoc PySpark workloads without provisioning or maintaining dedicated VMs.
|
|
28
|
+
- **Dynamic Autoscaling**: Scales Spark executors elastically based on partition backlog and shuffle pressure.
|
|
29
|
+
- **Unified Governance**: Native IAM Workload Identity federation and BigLake fine-grained column/row security.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 2. Distributed Vector Embedding Pipeline (PySpark)
|
|
34
|
+
|
|
35
|
+
Generates 768-dimensional embeddings over millions of technical documents using PySpark pandas UDFs:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from pyspark.sql import SparkSession
|
|
39
|
+
from pyspark.sql.functions import pandas_udf
|
|
40
|
+
from pyspark.sql.types import ArrayType, FloatType
|
|
41
|
+
import pandas as pd
|
|
42
|
+
from typing import Iterator
|
|
43
|
+
|
|
44
|
+
spark = SparkSession.builder \
|
|
45
|
+
.appName("Antigravity-Distributed-Embeddings") \
|
|
46
|
+
.config("spark.sql.execution.arrow.pyspark.enabled", "true") \
|
|
47
|
+
.getOrCreate()
|
|
48
|
+
|
|
49
|
+
# Read partitioned documents from Cloud Storage
|
|
50
|
+
docs_df = spark.read.parquet("gs://antigravity-data-lake/documents/v2/*.parquet")
|
|
51
|
+
|
|
52
|
+
@pandas_udf(ArrayType(FloatType()))
|
|
53
|
+
def compute_gemini_embeddings_udf(text_series: pd.Series) -> pd.Series:
|
|
54
|
+
"""Computes embeddings in vectorized batches using official Google GenAI SDK."""
|
|
55
|
+
from google import genai
|
|
56
|
+
client = genai.Client()
|
|
57
|
+
|
|
58
|
+
results = []
|
|
59
|
+
# Batch requests in 100 items per API call
|
|
60
|
+
batch_size = 100
|
|
61
|
+
for i in range(0, len(text_series), batch_size):
|
|
62
|
+
chunk = text_series.iloc[i:i + batch_size].tolist()
|
|
63
|
+
resp = client.models.embed_content(
|
|
64
|
+
model="text-embedding-004",
|
|
65
|
+
contents=chunk
|
|
66
|
+
)
|
|
67
|
+
results.extend([e.values for e in resp.embeddings])
|
|
68
|
+
return pd.Series(results)
|
|
69
|
+
|
|
70
|
+
# Transform and write to BigLake table
|
|
71
|
+
embedded_df = docs_df.withColumn("embedding", compute_gemini_embeddings_udf("content"))
|
|
72
|
+
embedded_df.write \
|
|
73
|
+
.format("bigquery") \
|
|
74
|
+
.mode("overwrite") \
|
|
75
|
+
.option("table", "enterprise_rag.document_embeddings_v2") \
|
|
76
|
+
.save()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 3. Submitting Serverless PySpark Batches
|
|
82
|
+
|
|
83
|
+
Submits serverless batch jobs via Google Cloud CLI:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
gcloud dataproc batches submit pyspark gs://antigravity-artifacts/scripts/generate_embeddings.py \
|
|
87
|
+
--project=my-gcp-ai-project \
|
|
88
|
+
--region=us-central1 \
|
|
89
|
+
--batch=batch-emb-$(date +%s) \
|
|
90
|
+
--deps-bucket=gs://antigravity-artifacts/staging \
|
|
91
|
+
--properties=spark.dynamicAllocation.maxExecutors=30 \
|
|
92
|
+
--version=2.2
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 4. PySpark Performance Tuning Rules
|
|
98
|
+
|
|
99
|
+
1. **Avoid `collect()`**: Never pull multi-gigabyte DataFrames onto the driver. Use `.write` directly to BigQuery or GCS.
|
|
100
|
+
2. **Optimize Partition Sizing**: Aim for 128 MB – 256 MB per Spark partition:
|
|
101
|
+
```python
|
|
102
|
+
df = df.repartition(100, "category_id")
|
|
103
|
+
```
|
|
104
|
+
3. **Broadcast Small Reference Maps**:
|
|
105
|
+
```python
|
|
106
|
+
from pyspark.sql.functions import broadcast
|
|
107
|
+
joined_df = large_fact_df.join(broadcast(small_metadata_df), "tenant_id")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 5. Verification and Monitoring
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Check status of submitted batch
|
|
116
|
+
gcloud dataproc batches describe <BATCH_ID> --region=us-central1 --format="value(state)"
|
|
117
|
+
|
|
118
|
+
# Stream driver logs
|
|
119
|
+
gcloud dataproc batches wait <BATCH_ID> --region=us-central1
|
|
120
|
+
```
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: google-flow-orchestrator
|
|
3
|
+
description: Orchestrates Google Agentic Flow state machines, cyclic agent loops, human approval pauses, and multi-agent DAG execution graphs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Google Flow Orchestrator
|
|
7
|
+
|
|
8
|
+
Architects and deploys deterministic, cyclic, and human-in-the-loop multi-agent workflows using Google Flow (Agentic Flow Engine) and Vertex AI Agent Builder.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Flow State Machine Architecture
|
|
13
|
+
|
|
14
|
+
Google Flow models multi-agent execution as a directed, stateful graph where each node is an agent, tool invocation, or human checkpoint:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
┌──────────────────┐
|
|
18
|
+
│ Start Node │
|
|
19
|
+
└────────┬─────────┘
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
┌──────────────────┐
|
|
23
|
+
│ Planner Subagent │
|
|
24
|
+
└────────┬─────────┘
|
|
25
|
+
│
|
|
26
|
+
▼
|
|
27
|
+
┌──────────────────┐
|
|
28
|
+
┌─────>│ Code Implementer│
|
|
29
|
+
│ └────────┬─────────┘
|
|
30
|
+
│ │
|
|
31
|
+
Failed │ ▼
|
|
32
|
+
Verification ┌──────────────────┐ Requires
|
|
33
|
+
├──────│ Quality Auditor │──────> Human Signoff
|
|
34
|
+
│ └────────┬─────────┘ (Pause State)
|
|
35
|
+
│ │ Passed │
|
|
36
|
+
│ ▼ ▼
|
|
37
|
+
│ ┌──────────────────┐ ┌───────────────┐
|
|
38
|
+
└──────┤ Security Auditor │ │ Human Approval│
|
|
39
|
+
└────────┬─────────┘ └───────┬───────┘
|
|
40
|
+
│ Approved │
|
|
41
|
+
▼ ▼
|
|
42
|
+
┌─────────────────────────────────────────┐
|
|
43
|
+
│ Deploy to Production │
|
|
44
|
+
└─────────────────────────────────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 2. Declarative Flow Definition (Python)
|
|
50
|
+
|
|
51
|
+
Defines an immutable state graph with type-safe context, dynamic edge routing, and conditional transitions:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from typing import Dict, Any, List, Optional
|
|
55
|
+
from dataclasses import dataclass, field
|
|
56
|
+
|
|
57
|
+
@dataclass
|
|
58
|
+
class FlowState:
|
|
59
|
+
task_id: str
|
|
60
|
+
user_prompt: str
|
|
61
|
+
plan: Optional[str] = None
|
|
62
|
+
diff_patches: List[str] = field(default_factory=list)
|
|
63
|
+
test_results: Dict[str, Any] = field(default_factory=dict)
|
|
64
|
+
security_cleared: bool = False
|
|
65
|
+
human_approved: bool = False
|
|
66
|
+
iteration_count: int = 0
|
|
67
|
+
max_iterations: int = 5
|
|
68
|
+
|
|
69
|
+
class AgenticFlow:
|
|
70
|
+
"""Deterministic state machine coordinating Antigravity subagents."""
|
|
71
|
+
|
|
72
|
+
def __init__(self, initial_state: FlowState):
|
|
73
|
+
self.state = initial_state
|
|
74
|
+
|
|
75
|
+
def node_planner(self) -> str:
|
|
76
|
+
"""Invokes Planner subagent to construct execution checklist."""
|
|
77
|
+
print(f"[FLOW:PLANNER] Creating roadmap for {self.state.task_id}...")
|
|
78
|
+
self.state.plan = "1. Add endpoint\n2. Run tests\n3. Audit security"
|
|
79
|
+
return "node_coder"
|
|
80
|
+
|
|
81
|
+
def node_coder(self) -> str:
|
|
82
|
+
"""Applies code patches and increments iteration counter."""
|
|
83
|
+
self.state.iteration_count += 1
|
|
84
|
+
print(f"[FLOW:CODER] Generating patches (Iteration {self.state.iteration_count})...")
|
|
85
|
+
self.state.diff_patches.append("+ def handle_request(): pass")
|
|
86
|
+
return "node_tester"
|
|
87
|
+
|
|
88
|
+
def node_tester(self) -> str:
|
|
89
|
+
"""Executes test verification gate."""
|
|
90
|
+
passed = self.state.iteration_count >= 1
|
|
91
|
+
self.state.test_results["suite_passed"] = passed
|
|
92
|
+
if not passed and self.state.iteration_count < self.state.max_iterations:
|
|
93
|
+
print("[FLOW:TESTER] Tests failed. Looping back to Coder.")
|
|
94
|
+
return "node_coder"
|
|
95
|
+
return "node_security"
|
|
96
|
+
|
|
97
|
+
def node_security(self) -> str:
|
|
98
|
+
"""Evaluates OPA Gatekeeper and secret leakage."""
|
|
99
|
+
self.state.security_cleared = True
|
|
100
|
+
print("[FLOW:SECURITY] Security clearance verified.")
|
|
101
|
+
return "node_human_gate"
|
|
102
|
+
|
|
103
|
+
def node_human_gate(self) -> str:
|
|
104
|
+
"""Halts execution for critical human-in-the-loop approval."""
|
|
105
|
+
if not self.state.human_approved:
|
|
106
|
+
print("[FLOW:HUMAN_GATE] Pausing workflow: Awaiting operator signoff.")
|
|
107
|
+
return "PAUSED"
|
|
108
|
+
return "node_release"
|
|
109
|
+
|
|
110
|
+
def node_release(self) -> str:
|
|
111
|
+
print("[FLOW:RELEASE] Production deployment completed.")
|
|
112
|
+
return "COMPLETED"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 3. Human-in-the-Loop Resumption
|
|
118
|
+
|
|
119
|
+
Flows persist execution state into external stores (Redis / Cloud Spanner) to resume cleanly after human approval:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
def resume_flow_after_approval(flow: AgenticFlow, operator_id: str):
|
|
123
|
+
"""Resumes paused flow once explicit signoff is received."""
|
|
124
|
+
print(f"✅ Received operator signoff from {operator_id}.")
|
|
125
|
+
flow.state.human_approved = True
|
|
126
|
+
next_step = flow.node_release()
|
|
127
|
+
print(f"Flow terminated with state: {next_step}")
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 4. Integration with Google Cloud Vertex AI & Antigravity
|
|
133
|
+
|
|
134
|
+
Maps Flow nodes directly to Antigravity's scoped subagents:
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
apiVersion: flow.google.com/v1
|
|
138
|
+
kind: AgentFlow
|
|
139
|
+
metadata:
|
|
140
|
+
name: fullstack-feature-delivery
|
|
141
|
+
spec:
|
|
142
|
+
entrypoint: planner
|
|
143
|
+
nodes:
|
|
144
|
+
- name: planner
|
|
145
|
+
agentRef: agents/planner.md
|
|
146
|
+
next: code-reviewer
|
|
147
|
+
- name: code-reviewer
|
|
148
|
+
agentRef: agents/code-reviewer.md
|
|
149
|
+
conditions:
|
|
150
|
+
- if: "diff_lines > 200"
|
|
151
|
+
then: security-auditor
|
|
152
|
+
- else: release-engineer
|
|
153
|
+
- name: security-auditor
|
|
154
|
+
agentRef: agents/security-auditor.md
|
|
155
|
+
next: release-engineer
|
|
156
|
+
- name: release-engineer
|
|
157
|
+
agentRef: agents/release-engineer.md
|
|
158
|
+
next: END
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 5. Verification and Diagnostics
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Verify flow graph connectivity and cycle termination
|
|
167
|
+
python3 -c "
|
|
168
|
+
from dataclasses import dataclass
|
|
169
|
+
print('Flow state schemas verified.')
|
|
170
|
+
"
|
|
171
|
+
|
|
172
|
+
# Trace flow transitions with OpenTelemetry
|
|
173
|
+
export OTEL_SERVICE_NAME=google-flow-orchestrator
|
|
174
|
+
```
|