everything-gemini 1.8.0 → 2.0.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 +47 -0
- package/CONTRIBUTING.md +5 -0
- package/README.md +28 -9
- package/agents/mlops-engineer.md +33 -0
- package/agents/platform-engineer.md +33 -0
- package/bin/everything-gemini +390 -18
- package/docs/LAUNCH_KIT_v2.0.0.md +187 -0
- package/docs/architecture/progressive-disclosure.md +3 -3
- package/docs/index.html +23 -7
- package/examples/python-sdk/README.md +8 -0
- package/examples/python-sdk/autonomous_mlops_rag_pipeline.py +254 -0
- package/examples/python-sdk/platform_provisioning_pipeline.py +193 -0
- package/mcp/README.md +2 -0
- package/mcp/mcp_config.example.json +11 -0
- package/package.json +1 -1
- package/scripts/validate.sh +1 -1
- package/skills/chromadb-vector-store/SKILL.md +188 -0
- package/skills/cloudflare-r2-object-storage/SKILL.md +143 -0
- package/skills/distributed-rate-limiting/SKILL.md +138 -0
- package/skills/keda-event-autoscaling/SKILL.md +218 -0
- package/skills/milvus-vector-clustering/SKILL.md +134 -0
- package/skills/opa-gatekeeper-policy/SKILL.md +200 -0
- package/skills/triton-inference-server/SKILL.md +221 -0
- package/skills/vault-secrets-management/SKILL.md +129 -0
- package/templates/full-power/mcp_config.json +11 -0
- package/tests/cli.test.js +118 -11
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Everything Gemini (everything-gemini) Python SDK Example
|
|
4
|
+
Cloud Platform Provisioning & Zero-Trust Infrastructure Pipeline
|
|
5
|
+
|
|
6
|
+
Orchestrates a 4-stage automated cloud delivery loop:
|
|
7
|
+
Architect -> Platform Engineer -> Security Auditor -> Release Engineer
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
import json
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from typing import List, Dict, Any, Optional
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class PlatformWorkloadRequest:
|
|
17
|
+
workload_id: str
|
|
18
|
+
environment: str # staging, production
|
|
19
|
+
cloud_provider: str # gcp, aws, azure
|
|
20
|
+
cluster_region: str
|
|
21
|
+
expected_qps: int
|
|
22
|
+
data_retention_days: int
|
|
23
|
+
services: List[str] = field(default_factory=list)
|
|
24
|
+
compliance_frameworks: List[str] = field(default_factory=list)
|
|
25
|
+
|
|
26
|
+
class PlatformProvisioningPipeline:
|
|
27
|
+
"""Automates multi-agent cloud platform provisioning and compliance auditing."""
|
|
28
|
+
|
|
29
|
+
def __init__(self, request: PlatformWorkloadRequest):
|
|
30
|
+
self.request = request
|
|
31
|
+
self.audit_trail: List[Dict[str, Any]] = []
|
|
32
|
+
self.iac_manifests: Dict[str, str] = {}
|
|
33
|
+
self.security_clearance: bool = False
|
|
34
|
+
self.deployment_ready: bool = False
|
|
35
|
+
|
|
36
|
+
def log_event(self, agent: str, phase: str, status: str, details: str):
|
|
37
|
+
event = {
|
|
38
|
+
"agent": agent,
|
|
39
|
+
"phase": phase,
|
|
40
|
+
"status": status,
|
|
41
|
+
"details": details
|
|
42
|
+
}
|
|
43
|
+
self.audit_trail.append(event)
|
|
44
|
+
print(f"[{agent.upper()}] ({phase}): {status} - {details}")
|
|
45
|
+
|
|
46
|
+
def stage_1_architecture_blueprint(self) -> bool:
|
|
47
|
+
"""Stage 1: Architect subagent designs high-availability topology and VPC segmentation."""
|
|
48
|
+
self.log_event(
|
|
49
|
+
agent="architect",
|
|
50
|
+
phase="topology_design",
|
|
51
|
+
status="DESIGNED",
|
|
52
|
+
details=f"Designed multi-zone VPC topology in {self.request.cluster_region} for {len(self.request.services)} services."
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Architectural scaling rules
|
|
56
|
+
if self.request.expected_qps > 5000:
|
|
57
|
+
topology = "multi-region-active-active"
|
|
58
|
+
else:
|
|
59
|
+
topology = "multi-zone-ha-regional"
|
|
60
|
+
|
|
61
|
+
self.log_event(
|
|
62
|
+
agent="architect",
|
|
63
|
+
phase="scaling_strategy",
|
|
64
|
+
status="CONFIRMED",
|
|
65
|
+
details=f"Selected topology: {topology} with horizontal pod autoscaling (HPA) target 75% CPU."
|
|
66
|
+
)
|
|
67
|
+
return True
|
|
68
|
+
|
|
69
|
+
def stage_2_platform_provisioning(self) -> bool:
|
|
70
|
+
"""Stage 2: Platform Engineer generates Terraform/Helm modules and sizes compute resources."""
|
|
71
|
+
self.log_event(
|
|
72
|
+
agent="platform-engineer",
|
|
73
|
+
phase="iac_generation",
|
|
74
|
+
status="GENERATED",
|
|
75
|
+
details="Generated Terraform modules for GKE/EKS cluster, node pools, and VPC CNI."
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# Resource right-sizing
|
|
79
|
+
cpu_request = "500m" if self.request.expected_qps < 1000 else "2000m"
|
|
80
|
+
ram_request = "1Gi" if self.request.expected_qps < 1000 else "4Gi"
|
|
81
|
+
|
|
82
|
+
self.iac_manifests["helm_values"] = f"""
|
|
83
|
+
replicaCount: 3
|
|
84
|
+
resources:
|
|
85
|
+
requests:
|
|
86
|
+
cpu: {cpu_request}
|
|
87
|
+
memory: {ram_request}
|
|
88
|
+
limits:
|
|
89
|
+
cpu: {cpu_request}
|
|
90
|
+
memory: {ram_request}
|
|
91
|
+
autoscaling:
|
|
92
|
+
enabled: true
|
|
93
|
+
minReplicas: 3
|
|
94
|
+
maxReplicas: 20
|
|
95
|
+
targetCPUUtilizationPercentage: 75
|
|
96
|
+
"""
|
|
97
|
+
self.log_event(
|
|
98
|
+
agent="platform-engineer",
|
|
99
|
+
phase="resource_sizing",
|
|
100
|
+
status="OPTIMIZED",
|
|
101
|
+
details=f"Container resource requests sized to {cpu_request} CPU, {ram_request} RAM per pod."
|
|
102
|
+
)
|
|
103
|
+
return True
|
|
104
|
+
|
|
105
|
+
def stage_3_security_and_compliance_gate(self) -> bool:
|
|
106
|
+
"""Stage 3: Security Auditor validates zero-trust network policies, RBAC, and Vault secrets."""
|
|
107
|
+
self.log_event(
|
|
108
|
+
agent="security-auditor",
|
|
109
|
+
phase="policy_scan",
|
|
110
|
+
status="INSPECTING",
|
|
111
|
+
details=f"Scanning against compliance standards: {', '.join(self.request.compliance_frameworks)}."
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Check for zero-trust network boundaries
|
|
115
|
+
has_ebpf_mtls = True
|
|
116
|
+
has_ephemeral_secrets = True
|
|
117
|
+
|
|
118
|
+
if has_ebpf_mtls and has_ephemeral_secrets:
|
|
119
|
+
self.security_clearance = True
|
|
120
|
+
self.log_event(
|
|
121
|
+
agent="security-auditor",
|
|
122
|
+
phase="zero_trust_verification",
|
|
123
|
+
status="APPROVED",
|
|
124
|
+
details="Zero-trust CiliumNetworkPolicy, Workload Identity, and Vault AppRole verified with zero findings."
|
|
125
|
+
)
|
|
126
|
+
return True
|
|
127
|
+
else:
|
|
128
|
+
self.log_event(
|
|
129
|
+
agent="security-auditor",
|
|
130
|
+
phase="zero_trust_verification",
|
|
131
|
+
status="REJECTED",
|
|
132
|
+
details="Missing automated mTLS or ephemeral secret rotation."
|
|
133
|
+
)
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
def stage_4_release_and_canary_plan(self) -> bool:
|
|
137
|
+
"""Stage 4: Release Engineer compiles progressive delivery plan and automated rollback triggers."""
|
|
138
|
+
if not self.security_clearance:
|
|
139
|
+
print("[RELEASE-ENGINEER] Blocked: Security clearance not granted.")
|
|
140
|
+
return False
|
|
141
|
+
|
|
142
|
+
self.log_event(
|
|
143
|
+
agent="release-engineer",
|
|
144
|
+
phase="canary_orchestration",
|
|
145
|
+
status="SCHEDULED",
|
|
146
|
+
details="Formulated 5% -> 25% -> 100% canary rollout with automated rollback on error rate > 0.5%."
|
|
147
|
+
)
|
|
148
|
+
self.deployment_ready = True
|
|
149
|
+
return True
|
|
150
|
+
|
|
151
|
+
def execute(self) -> Dict[str, Any]:
|
|
152
|
+
"""Execute full platform delivery pipeline."""
|
|
153
|
+
print(f"\n🚀 Initiating Platform Provisioning Pipeline for '{self.request.workload_id}' ({self.request.environment})...\n")
|
|
154
|
+
|
|
155
|
+
ok = self.stage_1_architecture_blueprint()
|
|
156
|
+
if ok:
|
|
157
|
+
ok = self.stage_2_platform_provisioning()
|
|
158
|
+
if ok:
|
|
159
|
+
ok = self.stage_3_security_and_compliance_gate()
|
|
160
|
+
if ok:
|
|
161
|
+
ok = self.stage_4_release_and_canary_plan()
|
|
162
|
+
|
|
163
|
+
report = {
|
|
164
|
+
"workload_id": self.request.workload_id,
|
|
165
|
+
"environment": self.request.environment,
|
|
166
|
+
"cloud_provider": self.request.cloud_provider,
|
|
167
|
+
"security_clearance": self.security_clearance,
|
|
168
|
+
"deployment_ready": self.deployment_ready,
|
|
169
|
+
"audit_trail_events": len(self.audit_trail),
|
|
170
|
+
"status": "APPROVED" if self.deployment_ready else "BLOCKED"
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
print(f"\n✨ Platform Provisioning Pipeline Complete: Status = {report['status']}")
|
|
174
|
+
return report
|
|
175
|
+
|
|
176
|
+
def main():
|
|
177
|
+
sample_request = PlatformWorkloadRequest(
|
|
178
|
+
workload_id="ai-vector-search-cluster",
|
|
179
|
+
environment="production",
|
|
180
|
+
cloud_provider="gcp",
|
|
181
|
+
cluster_region="us-central1",
|
|
182
|
+
expected_qps=8500,
|
|
183
|
+
data_retention_days=90,
|
|
184
|
+
services=["vector-ingestion", "milvus-cluster", "query-gateway"],
|
|
185
|
+
compliance_frameworks=["SOC2-Type2", "ISO-27001"]
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
pipeline = PlatformProvisioningPipeline(sample_request)
|
|
189
|
+
report = pipeline.execute()
|
|
190
|
+
print("\n" + json.dumps(report, indent=2))
|
|
191
|
+
|
|
192
|
+
if __name__ == "__main__":
|
|
193
|
+
main()
|
package/mcp/README.md
CHANGED
|
@@ -55,6 +55,8 @@ Everything Gemini bundles ready-to-use blueprints in `mcp/mcp_config.example.jso
|
|
|
55
55
|
| **`filesystem`** | `@modelcontextprotocol/server-filesystem` | Direct multi-directory filesystem inspection | Stdio |
|
|
56
56
|
| **`sentry`** | `@modelcontextprotocol/server-sentry` | Real-time production error tracking, issue triage, and stacktrace analysis | Stdio |
|
|
57
57
|
| **`slack`** | `@modelcontextprotocol/server-slack` | Automated incident channels, alert broadcasts, and team collaboration | Stdio |
|
|
58
|
+
| **`puppeteer`** | `@modelcontextprotocol/server-puppeteer` | Headless browser automation, screenshot diffing, and dynamic web crawling | Stdio |
|
|
59
|
+
| **`brave-search`** | `@modelcontextprotocol/server-brave-search` | Grounded live web search, documentation retrieval, and internet research | Stdio |
|
|
58
60
|
|
|
59
61
|
## Tool Auto-Discovery & Execution
|
|
60
62
|
Once connected, tools declared by MCP servers are automatically injected into the agent's system prompt and executed through Antigravity's Language Server. Inspect active MCP servers in the Antigravity UI via **Additional Options (...) > MCP Servers**.
|
|
@@ -60,6 +60,17 @@
|
|
|
60
60
|
"SLACK_BOT_TOKEN": "YOUR_SLACK_BOT_TOKEN",
|
|
61
61
|
"SLACK_TEAM_ID": "YOUR_SLACK_TEAM_ID"
|
|
62
62
|
}
|
|
63
|
+
},
|
|
64
|
+
"puppeteer": {
|
|
65
|
+
"command": "npx",
|
|
66
|
+
"args": ["-y", "@modelcontextprotocol/server-puppeteer"]
|
|
67
|
+
},
|
|
68
|
+
"brave-search": {
|
|
69
|
+
"command": "npx",
|
|
70
|
+
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
|
|
71
|
+
"env": {
|
|
72
|
+
"BRAVE_API_KEY": "YOUR_BRAVE_API_KEY"
|
|
73
|
+
}
|
|
63
74
|
}
|
|
64
75
|
}
|
|
65
76
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "everything-gemini",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Everything Gemini (everything-gemini) - The Ultimate Agent Harness, Multi-Agent Orchestrator & Performance Suite for Gemini & Google Antigravity",
|
|
5
5
|
"main": "bin/everything-gemini",
|
|
6
6
|
"bin": {
|
package/scripts/validate.sh
CHANGED
|
@@ -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,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cloudflare-r2-object-storage
|
|
3
|
+
description: >-
|
|
4
|
+
Architects, configures, and integrates Cloudflare R2 zero-egress object storage using S3-compatible APIs, pre-signed upload URLs, multipart streaming, and edge CDN distribution.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Cloudflare R2 Object Storage & Edge Distribution
|
|
8
|
+
|
|
9
|
+
This skill guides the implementation of zero-egress fee object storage using Cloudflare R2 with S3-compatible APIs, pre-signed URLs, multipart uploads, and edge CDN distribution.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ⚡ Architectural Comparison: R2 vs Standard S3
|
|
14
|
+
|
|
15
|
+
| Feature | Cloudflare R2 | Standard AWS S3 |
|
|
16
|
+
| :--- | :--- | :--- |
|
|
17
|
+
| **Data Egress Fees** | **$0.00 / GB (Free)** | ~$0.09 / GB |
|
|
18
|
+
| **API Compatibility** | Full S3 API v4 signature | Native AWS S3 |
|
|
19
|
+
| **Edge Integration** | Native Cloudflare Workers & CDN | CloudFront integration required |
|
|
20
|
+
| **Storage Pricing** | $0.015 / GB-month | $0.023 / GB-month |
|
|
21
|
+
| **Global Replication** | Automatic across edge locations | Cross-Region Replication (CRR) billed |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🛠️ TypeScript S3 Client Configuration (`@aws-sdk/client-s3`)
|
|
26
|
+
|
|
27
|
+
R2 endpoints use account-specific URLs with AWS Signature Version 4:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
31
|
+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
32
|
+
|
|
33
|
+
const ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID!;
|
|
34
|
+
const R2_ACCESS_KEY_ID = process.env.R2_ACCESS_KEY_ID!;
|
|
35
|
+
const R2_SECRET_ACCESS_KEY = process.env.R2_SECRET_ACCESS_KEY!;
|
|
36
|
+
|
|
37
|
+
export const r2Client = new S3Client({
|
|
38
|
+
region: 'auto',
|
|
39
|
+
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
|
40
|
+
credentials: {
|
|
41
|
+
accessKeyId: R2_ACCESS_KEY_ID,
|
|
42
|
+
secretAccessKey: R2_SECRET_ACCESS_KEY,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 📤 Pre-Signed URLs for Direct Browser Uploads
|
|
50
|
+
|
|
51
|
+
Prevent API server bottlenecking by generating short-lived pre-signed upload URLs:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export async function generateUploadUrl(key: string, contentType: string, expiresInSeconds = 300) {
|
|
55
|
+
const command = new PutObjectCommand({
|
|
56
|
+
Bucket: 'enterprise-artifacts',
|
|
57
|
+
Key: key,
|
|
58
|
+
ContentType: contentType,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const uploadUrl = await getSignedUrl(r2Client, command, { expiresIn: expiresInSeconds });
|
|
62
|
+
return {
|
|
63
|
+
uploadUrl,
|
|
64
|
+
key,
|
|
65
|
+
publicUrl: `https://cdn.example.com/${key}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 📦 High-Throughput Multipart Uploads (Node.js / Python)
|
|
73
|
+
|
|
74
|
+
For files exceeding 100MB, use parallel multipart uploads with the Upload helper:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { Upload } from '@aws-sdk/lib-storage';
|
|
78
|
+
import fs from 'node:fs';
|
|
79
|
+
|
|
80
|
+
export async function uploadLargeArchive(filePath: string, destinationKey: string) {
|
|
81
|
+
const fileStream = fs.createReadStream(filePath);
|
|
82
|
+
|
|
83
|
+
const parallelUpload = new Upload({
|
|
84
|
+
client: r2Client,
|
|
85
|
+
params: {
|
|
86
|
+
Bucket: 'enterprise-artifacts',
|
|
87
|
+
Key: destinationKey,
|
|
88
|
+
Body: fileStream,
|
|
89
|
+
ContentType: 'application/octet-stream',
|
|
90
|
+
},
|
|
91
|
+
queueSize: 4, // 4 concurrent part uploads
|
|
92
|
+
partSize: 10 * 1024 * 1024, // 10MB chunk size
|
|
93
|
+
leavePartsOnError: false,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
parallelUpload.on('httpUploadProgress', (progress) => {
|
|
97
|
+
console.log(`Uploaded ${progress.loaded} of ${progress.total} bytes`);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return await parallelUpload.done();
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🌐 Custom Domain & Cloudflare CDN Caching Rule
|
|
107
|
+
|
|
108
|
+
Expose R2 buckets through a custom domain with edge cache headers:
|
|
109
|
+
|
|
110
|
+
```javascript
|
|
111
|
+
// Cloudflare Worker Edge Proxy
|
|
112
|
+
export default {
|
|
113
|
+
async fetch(request, env) {
|
|
114
|
+
const url = new URL(request.url);
|
|
115
|
+
const key = url.pathname.slice(1);
|
|
116
|
+
|
|
117
|
+
if (request.method !== 'GET') {
|
|
118
|
+
return new Response('Method Not Allowed', { status: 405 });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const object = await env.MY_R2_BUCKET.get(key);
|
|
122
|
+
if (!object) {
|
|
123
|
+
return new Response('Not Found', { status: 404 });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const headers = new Headers();
|
|
127
|
+
object.writeHttpMetadata(headers);
|
|
128
|
+
headers.set('etag', object.httpEtag);
|
|
129
|
+
headers.set('Cache-Control', 'public, max-age=31536000, immutable');
|
|
130
|
+
|
|
131
|
+
return new Response(object.body, { headers });
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 📋 Architectural Rules & Best Practices
|
|
139
|
+
|
|
140
|
+
1. **Bucket Region**: Always set region to `auto` in AWS S3 SDK clients; R2 automatically routes storage to the lowest-latency regional cluster.
|
|
141
|
+
2. **CORS Headers**: Set permissive CORS rules (`AllowedOrigins`, `AllowedMethods: ["PUT", "GET"]`) on the R2 bucket for direct browser pre-signed uploads.
|
|
142
|
+
3. **Multipart Cleanup**: Configure bucket lifecycle rules to automatically abort incomplete multipart uploads after 7 days (`AbortIncompleteMultipartUpload`).
|
|
143
|
+
4. **Zero-Egress Strategy**: Route public media and file downloads through Cloudflare Custom Domains or Workers to benefit from zero bandwidth charges.
|