@cloudgrid-io/mcp 0.20.19 → 0.20.21
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/package.json +1 -1
- package/src/corpus/capability-map.md +1 -1
- package/src/corpus/cloudgrid-yaml.md +3 -3
- package/src/corpus/examples/ai-app/index.md +20 -21
- package/src/corpus/templates/_cloudgrid.yaml.reference +2 -2
- package/src/corpus/templates/admin-dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/ai-app/README.md +18 -13
- package/src/corpus/templates/ai-app/cloudgrid.yaml +2 -2
- package/src/corpus/templates/ai-app/index.md +23 -18
- package/src/corpus/templates/ai-app/services/web/app/api/chat/route.js +11 -8
- package/src/corpus/templates/ai-app/services/web/package.json +1 -1
- package/src/corpus/templates/ai-knowledge-base/AGENTS.md +19 -21
- package/src/corpus/templates/ai-knowledge-base/README.md +1 -1
- package/src/corpus/templates/ai-knowledge-base/cloudgrid.yaml +2 -2
- package/src/corpus/templates/ai-knowledge-base/index.md +2 -2
- package/src/corpus/templates/analytics-dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/api-dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/api-docs/cloudgrid.yaml +2 -2
- package/src/corpus/templates/api-service/cloudgrid.yaml +2 -2
- package/src/corpus/templates/app-with-data/cloudgrid.yaml +2 -2
- package/src/corpus/templates/appointment-booking/AGENTS.md +1 -1
- package/src/corpus/templates/appointment-booking/cloudgrid.yaml +2 -2
- package/src/corpus/templates/approval-workflow/AGENTS.md +2 -2
- package/src/corpus/templates/approval-workflow/cloudgrid.yaml +2 -2
- package/src/corpus/templates/billing-dashboard/AGENTS.md +2 -2
- package/src/corpus/templates/billing-dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/blog-cms/cloudgrid.yaml +2 -2
- package/src/corpus/templates/booking-system/AGENTS.md +2 -2
- package/src/corpus/templates/booking-system/cloudgrid.yaml +2 -2
- package/src/corpus/templates/booking-system/index.md +1 -1
- package/src/corpus/templates/calendar-scheduler/AGENTS.md +1 -1
- package/src/corpus/templates/calendar-scheduler/cloudgrid.yaml +2 -2
- package/src/corpus/templates/calendar-scheduler/index.md +1 -1
- package/src/corpus/templates/changelog/cloudgrid.yaml +2 -2
- package/src/corpus/templates/company-website/cloudgrid.yaml +2 -2
- package/src/corpus/templates/course-platform/AGENTS.md +2 -2
- package/src/corpus/templates/course-platform/cloudgrid.yaml +2 -2
- package/src/corpus/templates/crm/cloudgrid.yaml +2 -2
- package/src/corpus/templates/dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/deck/cloudgrid.yaml +2 -2
- package/src/corpus/templates/directory/cloudgrid.yaml +2 -2
- package/src/corpus/templates/docs-site/cloudgrid.yaml +2 -2
- package/src/corpus/templates/erp/AGENTS.md +2 -2
- package/src/corpus/templates/erp/cloudgrid.yaml +2 -2
- package/src/corpus/templates/erp/index.md +1 -1
- package/src/corpus/templates/event-board/cloudgrid.yaml +2 -2
- package/src/corpus/templates/expense-tracker/cloudgrid.yaml +2 -2
- package/src/corpus/templates/feature-request-board/cloudgrid.yaml +2 -2
- package/src/corpus/templates/financial-dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/forum/AGENTS.md +3 -3
- package/src/corpus/templates/forum/cloudgrid.yaml +2 -2
- package/src/corpus/templates/hr-portal/AGENTS.md +1 -1
- package/src/corpus/templates/hr-portal/cloudgrid.yaml +2 -2
- package/src/corpus/templates/internal-tools-portal/AGENTS.md +2 -2
- package/src/corpus/templates/internal-tools-portal/cloudgrid.yaml +2 -2
- package/src/corpus/templates/inventory/cloudgrid.yaml +2 -2
- package/src/corpus/templates/invoice/cloudgrid.yaml +2 -2
- package/src/corpus/templates/job-board/cloudgrid.yaml +2 -2
- package/src/corpus/templates/kanban/cloudgrid.yaml +2 -2
- package/src/corpus/templates/landing-page/cloudgrid.yaml +2 -2
- package/src/corpus/templates/lms/AGENTS.md +3 -3
- package/src/corpus/templates/lms/cloudgrid.yaml +2 -2
- package/src/corpus/templates/marketplace/AGENTS.md +1 -1
- package/src/corpus/templates/marketplace/cloudgrid.yaml +2 -2
- package/src/corpus/templates/marketplace/index.md +1 -1
- package/src/corpus/templates/membership-site/AGENTS.md +1 -1
- package/src/corpus/templates/membership-site/cloudgrid.yaml +2 -2
- package/src/corpus/templates/monitoring-dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/online-store/AGENTS.md +1 -1
- package/src/corpus/templates/online-store/cloudgrid.yaml +2 -2
- package/src/corpus/templates/portfolio/cloudgrid.yaml +2 -2
- package/src/corpus/templates/product-catalog/cloudgrid.yaml +2 -2
- package/src/corpus/templates/product-launch/cloudgrid.yaml +2 -2
- package/src/corpus/templates/project-management/cloudgrid.yaml +2 -2
- package/src/corpus/templates/property-listings/cloudgrid.yaml +2 -2
- package/src/corpus/templates/quiz-platform/cloudgrid.yaml +2 -2
- package/src/corpus/templates/report/cloudgrid.yaml +2 -2
- package/src/corpus/templates/restaurant-reservations/AGENTS.md +2 -2
- package/src/corpus/templates/restaurant-reservations/cloudgrid.yaml +2 -2
- package/src/corpus/templates/revenue-dashboard/cloudgrid.yaml +2 -2
- package/src/corpus/templates/saas-marketing/cloudgrid.yaml +2 -2
- package/src/corpus/templates/semantic-search/cloudgrid.yaml +1 -1
- package/src/corpus/templates/simple-semantic-search/cloudgrid.yaml +3 -3
- package/src/corpus/templates/status-page/cloudgrid.yaml +2 -2
- package/src/corpus/templates/subscription-management/AGENTS.md +1 -1
- package/src/corpus/templates/subscription-management/cloudgrid.yaml +2 -2
- package/src/corpus/templates/task-manager/cloudgrid.yaml +2 -2
- package/src/corpus/templates/ticket-system/cloudgrid.yaml +2 -2
- package/src/corpus/templates/time-tracking/cloudgrid.yaml +2 -2
- package/src/corpus/templates/travel-booking/AGENTS.md +2 -2
- package/src/corpus/templates/travel-booking/cloudgrid.yaml +2 -2
- package/src/corpus/templates/travel-booking/index.md +1 -1
- package/src/corpus/templates/waitlist/cloudgrid.yaml +2 -2
- package/src/corpus/templates/web-app/cloudgrid.yaml +2 -2
- package/src/corpus/workflows/ai-app.md +13 -9
- package/src/corpus/workflows/ai-knowledge-base.md +15 -12
- package/src/session-logger.js +12 -1
- package/src/tools/register.js +5 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudgrid-io/mcp",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.21",
|
|
4
4
|
"description": "Use CloudGrid via MCP to brainstorm, build, deploy, and improve apps, games, websites, dashboards, and tools and get a live URL - templates, recipes, managed databases and AI, instant single-page publish, and full-app deploys, for developers and non-technical users. Three editions: local stdio (full toolset), hosted web (light, CLI-free), and a public docs-search server, over MCP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -159,7 +159,7 @@ engine hint. Cron is NOT a need — it is a **service type** (`type: cron` with
|
|
|
159
159
|
| `vector: pgvector` | pgvector embeddings DB | `VECTOR_PGVECTOR_URL` (+legacy `PGVECTOR_URL`) | **Injects via `needs:`** (#1545 shipped, verified live 2026-07-16) |
|
|
160
160
|
| `object_storage: true` | GCS bucket | `OBJECT_STORAGE_GCS_BUCKET`, `OBJECT_STORAGE_GCS_REGION` | **GATED (#1678)** - rejected at plug-time; use `disk` or a BYO bucket via secret |
|
|
161
161
|
| `disk: true` | Persistent filesystem at `/data` | `DISK_PATH` | Injects via `needs:` |
|
|
162
|
-
| `ai: true` | AI Gateway access | `
|
|
162
|
+
| `ai: true` | AI Gateway access | `RUNTIME_GATEWAY_URL` | Injects via `needs:` |
|
|
163
163
|
| `type: cron` (service) | Scheduled job (`schedule`, `timezone`) | — | Service type, not a need |
|
|
164
164
|
|
|
165
165
|
### Injection status
|
|
@@ -156,7 +156,7 @@ needs:
|
|
|
156
156
|
vector: pgvector # pgvector. Injects VECTOR_PGVECTOR_URL. (#1545 shipped, verified live 2026-07-16.)
|
|
157
157
|
object_storage: true # GATED (platform #1678) - rejected at plug-time; use disk: or a BYO bucket via secret.
|
|
158
158
|
disk: true # Persistent filesystem at /data. Injects DISK_PATH.
|
|
159
|
-
ai: true # AI Gateway access. Injects
|
|
159
|
+
ai: true # AI Gateway access. Injects RUNTIME_GATEWAY_URL.
|
|
160
160
|
|
|
161
161
|
# ─── Inter-entity communication ────────────────────────────────────
|
|
162
162
|
calls: # Entities this app calls (outbound grants).
|
|
@@ -366,7 +366,7 @@ that path. `{ path, expected }` → HTTP with expected status
|
|
|
366
366
|
|
|
367
367
|
String key-values injected at runtime (not build). **Reserved names (rejected):**
|
|
368
368
|
`PORT`, `APP_NAME`, `SERVICE_NAME`, `NODE_ENV`, `MONGODB_URL`, `REDIS_URL`,
|
|
369
|
-
`
|
|
369
|
+
`RUNTIME_GATEWAY_URL`, `N8N_WEBHOOK_URL`, and any key starting with `CLOUDGRID_`. Use
|
|
370
370
|
`grid secrets set` for sensitive values.
|
|
371
371
|
|
|
372
372
|
### Per-service `needs` override
|
|
@@ -407,7 +407,7 @@ service type.**
|
|
|
407
407
|
| `vector` | Vector embeddings DB | `VECTOR_PGVECTOR_URL` (+legacy `PGVECTOR_URL`) | pgvector (Postgres) |
|
|
408
408
|
| `object_storage` | Object/blob bucket - **GATED (#1678)**: rejected at plug-time, use `disk` or a BYO bucket via secret | `OBJECT_STORAGE_GCS_BUCKET`, `OBJECT_STORAGE_GCS_REGION` | GCS |
|
|
409
409
|
| `disk` | Persistent filesystem mount | `DISK_PATH` | PVC |
|
|
410
|
-
| `ai` | AI Gateway access | `
|
|
410
|
+
| `ai` | AI Gateway access | `RUNTIME_GATEWAY_URL` | CloudGrid AI Gateway |
|
|
411
411
|
|
|
412
412
|
`cache`, `kv`, `queue`, `pubsub` all share one physical Redis but each gets a
|
|
413
413
|
distinct env var. `cache` runs `allkeys-lru` eviction (derived data); the other
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Example: ai-app — "Trip Planner Bot"
|
|
2
2
|
|
|
3
3
|
A filled reference imitating the `ai-app` template: a themed AI assistant — a
|
|
4
|
-
travel trip planner. Same stack (Next.js App Router + `@cloudgrid-io/
|
|
4
|
+
travel trip planner. Same stack (Next.js App Router + `@cloudgrid-io/runtime` for the
|
|
5
5
|
grid AI gateway + the `mongodb` driver for chat history), slightly richer than
|
|
6
6
|
the bare chatbot: it gives the assistant a **persona** via a `system` message and
|
|
7
7
|
sends the **prior conversation** as context, so replies stay on-theme and
|
|
@@ -11,8 +11,9 @@ Data persists in the grid-shared Mongo, so the conversation survives refresh.
|
|
|
11
11
|
|
|
12
12
|
**Same four proven rules as the template:** (1) app code lives under
|
|
13
13
|
**`services/web/`** (the service name, NOT the repo root — `path:` is the URL
|
|
14
|
-
mount); (2) the AI call is **zero-config — `
|
|
15
|
-
|
|
14
|
+
mount); (2) the AI call is **zero-config — `runtime.ai.chat({ model, messages })`
|
|
15
|
+
with no key** (the SDK reads `RUNTIME_GATEWAY_URL` and the in-grid identity
|
|
16
|
+
itself); (3) the DB connection string is read **lazily inside
|
|
16
17
|
the `getDb` getter**, never at module top level (a top-level read fails `next
|
|
17
18
|
build`); (4) the datastore is declared with the canonical **`needs: { ai: true,
|
|
18
19
|
database: true }`**. Don't use the deprecated `requires:` alias.
|
|
@@ -48,7 +49,7 @@ needs:
|
|
|
48
49
|
"next": "^15.1.0",
|
|
49
50
|
"react": "^19.0.0",
|
|
50
51
|
"react-dom": "^19.0.0",
|
|
51
|
-
"@cloudgrid-io/
|
|
52
|
+
"@cloudgrid-io/runtime": "^1.0.3",
|
|
52
53
|
"mongodb": "^6.12.0"
|
|
53
54
|
}
|
|
54
55
|
}
|
|
@@ -87,21 +88,18 @@ export async function getDb() {
|
|
|
87
88
|
```js
|
|
88
89
|
// Trip-planner chat route: give the assistant a persona, send the prior
|
|
89
90
|
// conversation as context, ask the grid AI gateway, persist the exchange,
|
|
90
|
-
// return the reply. Zero-config AI —
|
|
91
|
-
// identity.
|
|
91
|
+
// return the reply. Zero-config AI — @cloudgrid-io/runtime reads RUNTIME_GATEWAY_URL
|
|
92
|
+
// (injected by the grid) itself and uses the in-grid identity — no key.
|
|
92
93
|
import { NextResponse } from "next/server";
|
|
93
|
-
import {
|
|
94
|
+
import { runtime } from "@cloudgrid-io/runtime";
|
|
94
95
|
import { getDb } from "../../../lib/db.js";
|
|
95
96
|
|
|
96
97
|
export const dynamic = "force-dynamic";
|
|
97
98
|
|
|
98
|
-
const SYSTEM =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"itineraries, budgets, and practical tips. Ask a clarifying question when the " +
|
|
103
|
-
"destination or dates are unclear.",
|
|
104
|
-
};
|
|
99
|
+
const SYSTEM =
|
|
100
|
+
"You are Trip Planner Bot, a concise, friendly travel assistant. Suggest " +
|
|
101
|
+
"itineraries, budgets, and practical tips. Ask a clarifying question when the " +
|
|
102
|
+
"destination or dates are unclear.";
|
|
105
103
|
|
|
106
104
|
async function messages() {
|
|
107
105
|
return (await getDb()).collection("messages");
|
|
@@ -119,12 +117,13 @@ export async function POST(request) {
|
|
|
119
117
|
prior.reverse();
|
|
120
118
|
const context = prior.map((m) => ({ role: m.role, content: m.content }));
|
|
121
119
|
|
|
122
|
-
// Ask the grid AI gateway: persona + prior turns + the new user
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
120
|
+
// Ask the grid AI gateway: persona (system) + prior turns + the new user
|
|
121
|
+
// message. Chat expects a model and returns { text }.
|
|
122
|
+
const { text: reply } = await runtime.ai.chat({
|
|
123
|
+
model: "claude-haiku",
|
|
124
|
+
system: SYSTEM,
|
|
125
|
+
messages: [...context, { role: "user", content: text }],
|
|
126
126
|
});
|
|
127
|
-
const reply = r.text ?? r.content ?? "";
|
|
128
127
|
|
|
129
128
|
// Persist the exchange.
|
|
130
129
|
const now = new Date();
|
|
@@ -229,8 +228,8 @@ export default function Chat({ initialHistory }) {
|
|
|
229
228
|
- Deploy the same way as the template: `grid dev` locally, `grid plug` to deploy
|
|
230
229
|
(async — poll status to a live URL). Re-plug the same entity to keep one URL.
|
|
231
230
|
- The needs are Mongo + the AI gateway (`needs: { ai: true, database: true }`).
|
|
232
|
-
The AI call is zero-config — `
|
|
233
|
-
identity.
|
|
231
|
+
The AI call is zero-config — `runtime.ai.chat` with no key; the SDK reads
|
|
232
|
+
`RUNTIME_GATEWAY_URL` and the in-grid identity itself.
|
|
234
233
|
- All app code lives under `services/web/`; the connection is read lazily inside
|
|
235
234
|
`getDb`, never at module top level.
|
|
236
235
|
- To answer over your own documents (RAG) you'd add `needs: { vector: pgvector }`
|
|
@@ -96,7 +96,7 @@ name: my-app
|
|
|
96
96
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
97
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
98
|
# disk: true
|
|
99
|
-
# # ai — AI Gateway via @cloudgrid-io/
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
100
100
|
# ai: true
|
|
101
101
|
|
|
102
102
|
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
# path: /api/health
|
|
193
193
|
# expected: "200"
|
|
194
194
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
195
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
195
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
196
196
|
# env:
|
|
197
197
|
# LOG_LEVEL: info
|
|
198
198
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
@@ -96,7 +96,7 @@ name: my-admin
|
|
|
96
96
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
97
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
98
|
# disk: true
|
|
99
|
-
# # ai — AI Gateway via @cloudgrid-io/
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
100
100
|
# ai: true
|
|
101
101
|
|
|
102
102
|
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
# path: /api/health
|
|
193
193
|
# expected: "200"
|
|
194
194
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
195
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
195
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
196
196
|
# env:
|
|
197
197
|
# LOG_LEVEL: info
|
|
198
198
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ai-app template — AI chatbot on Next.js + the grid AI gateway + Mongo
|
|
2
2
|
|
|
3
3
|
A minimal but real, deployable AI chatbot. A Next.js App Router app that calls
|
|
4
|
-
the grid AI gateway (via `@cloudgrid-io/
|
|
4
|
+
the grid AI gateway (via `@cloudgrid-io/runtime`) for replies and persists the
|
|
5
5
|
conversation to the grid-shared MongoDB, so history survives refresh and is
|
|
6
6
|
shared across sessions.
|
|
7
7
|
|
|
@@ -10,8 +10,9 @@ shared across sessions.
|
|
|
10
10
|
You do **not** set an API key or provision a database. In `cloudgrid.yaml` you
|
|
11
11
|
declare `needs: { ai: true, database: true }`, and the grid:
|
|
12
12
|
|
|
13
|
-
- wires the **AI gateway** with the app's in-grid identity — `@cloudgrid-io/
|
|
14
|
-
|
|
13
|
+
- wires the **AI gateway** with the app's in-grid identity — `@cloudgrid-io/runtime`
|
|
14
|
+
reads the gateway URL from the injected `RUNTIME_GATEWAY_URL` itself, so there is
|
|
15
|
+
**no API key to set**; and
|
|
15
16
|
- provisions shared Mongo and injects the connection string as the
|
|
16
17
|
**`DATABASE_MONGODB_URL`** environment variable (plus the legacy `MONGODB_URL`
|
|
17
18
|
alias) — at dev-time (`grid dev`) and at runtime (after `grid plug`).
|
|
@@ -19,15 +20,18 @@ declare `needs: { ai: true, database: true }`, and the grid:
|
|
|
19
20
|
### The AI call
|
|
20
21
|
|
|
21
22
|
```js
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
23
|
+
import { runtime } from "@cloudgrid-io/runtime";
|
|
24
|
+
// Chat expects a model and returns { text }. No key, no baseURL.
|
|
25
|
+
const { text: reply } = await runtime.ai.chat({
|
|
26
|
+
model: "claude-haiku",
|
|
27
|
+
messages: [{ role: "user", content: text }],
|
|
28
|
+
});
|
|
26
29
|
```
|
|
27
30
|
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
key
|
|
31
|
+
`runtime.ai.chat` takes no key — the SDK reads `RUNTIME_GATEWAY_URL` (injected by
|
|
32
|
+
the grid) and uses the in-grid identity, so it only works inside a deployed grid
|
|
33
|
+
app (or under `grid dev`). Do **not** pass or set an API key, and never reference
|
|
34
|
+
the env var yourself.
|
|
31
35
|
|
|
32
36
|
### The database
|
|
33
37
|
|
|
@@ -71,18 +75,19 @@ update the same URL.
|
|
|
71
75
|
|
|
72
76
|
```
|
|
73
77
|
cloudgrid.yaml # name + services.web (nextjs) + needs: { ai: true, database: true }
|
|
74
|
-
services/web/package.json # next, react, react-dom, @cloudgrid-io/
|
|
78
|
+
services/web/package.json # next, react, react-dom, @cloudgrid-io/runtime, mongodb
|
|
75
79
|
services/web/lib/db.js # lazy Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
|
|
76
80
|
services/web/app/layout.js # root layout + inline CSS
|
|
77
81
|
services/web/app/page.js # server component: reads chat history from Mongo
|
|
78
82
|
services/web/app/chat.js # client component: sends messages, renders the log
|
|
79
|
-
services/web/app/api/chat/route.js # POST:
|
|
83
|
+
services/web/app/api/chat/route.js # POST: runtime.ai.chat(...) -> persist -> reply; GET: history
|
|
80
84
|
```
|
|
81
85
|
|
|
82
86
|
## Adapt it
|
|
83
87
|
|
|
84
88
|
- Give the assistant a persona — pass a `{ role: "system", content: "…" }`
|
|
85
|
-
message ahead of the user message in the `chat({ messages })`
|
|
89
|
+
message ahead of the user message in the `runtime.ai.chat({ model, messages })`
|
|
90
|
+
call (or pass `system:` directly alongside `messages`).
|
|
86
91
|
- Send prior turns as context by including the stored history in `messages`.
|
|
87
92
|
- Change the `messages` collection / fields; add users, sessions, titles.
|
|
88
93
|
- Restyle the chat UI in `layout.js` / `chat.js`.
|
|
@@ -96,7 +96,7 @@ name: my-chatbot
|
|
|
96
96
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
97
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
98
|
# disk: true
|
|
99
|
-
# # ai — AI Gateway via @cloudgrid-io/
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
100
100
|
# ai: true
|
|
101
101
|
|
|
102
102
|
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
# path: /api/health
|
|
193
193
|
# expected: "200"
|
|
194
194
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
195
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
195
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
196
196
|
# env:
|
|
197
197
|
# LOG_LEVEL: info
|
|
198
198
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Template: ai-app (Next.js AI chatbot + grid AI gateway + Mongo)
|
|
2
2
|
|
|
3
3
|
A minimal but real, deployable AI chatbot. A Next.js App Router app that calls
|
|
4
|
-
the grid AI gateway (via `@cloudgrid-io/
|
|
4
|
+
the grid AI gateway (via `@cloudgrid-io/runtime`) for replies and persists the
|
|
5
5
|
conversation to the grid-shared MongoDB. History survives refresh and is shared
|
|
6
6
|
across sessions.
|
|
7
7
|
|
|
@@ -11,11 +11,12 @@ across sessions.
|
|
|
11
11
|
`path:` in `cloudgrid.yaml` is the URL mount, NOT the filesystem path. The
|
|
12
12
|
service named `web` → the CLI looks for `services/web/`. Files at the root
|
|
13
13
|
fail with `Error: Service directory not found: …/services/web`.
|
|
14
|
-
2. **The AI call is zero-config — no API key.** `import {
|
|
15
|
-
"@cloudgrid-io/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
2. **The AI call is zero-config — no API key.** `import { runtime } from
|
|
15
|
+
"@cloudgrid-io/runtime"` then `runtime.ai.chat({ model, messages })`. The SDK
|
|
16
|
+
reads the gateway URL from `RUNTIME_GATEWAY_URL` (injected by the grid) itself,
|
|
17
|
+
so it only works inside a deployed grid app (or under `grid dev`). Do NOT pass
|
|
18
|
+
or set an API key, and never reference the env var yourself. Chat expects a
|
|
19
|
+
`model` and returns `{ text }`.
|
|
19
20
|
3. **Read the DB connection string LAZILY (inside the getter), never at module
|
|
20
21
|
top level.** The grid injects it as `DATABASE_MONGODB_URL` (plus the legacy
|
|
21
22
|
`MONGODB_URL` alias) at dev + runtime; the app reads
|
|
@@ -36,12 +37,12 @@ Write these files into the scaffolded app folder — the app code goes under
|
|
|
36
37
|
|
|
37
38
|
```
|
|
38
39
|
cloudgrid.yaml # name + services.web (nextjs) + needs: { ai: true, database: true }
|
|
39
|
-
services/web/package.json # next, react, react-dom, @cloudgrid-io/
|
|
40
|
+
services/web/package.json # next, react, react-dom, @cloudgrid-io/runtime, mongodb
|
|
40
41
|
services/web/lib/db.js # lazy Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
|
|
41
42
|
services/web/app/layout.js # root layout + inline CSS
|
|
42
43
|
services/web/app/page.js # server component: reads chat history from Mongo
|
|
43
44
|
services/web/app/chat.js # client component: sends messages, renders the log
|
|
44
|
-
services/web/app/api/chat/route.js # POST:
|
|
45
|
+
services/web/app/api/chat/route.js # POST: runtime.ai.chat(...) -> persist -> reply; GET: history
|
|
45
46
|
```
|
|
46
47
|
|
|
47
48
|
## cloudgrid.yaml
|
|
@@ -78,7 +79,7 @@ needs:
|
|
|
78
79
|
"next": "^15.1.0",
|
|
79
80
|
"react": "^19.0.0",
|
|
80
81
|
"react-dom": "^19.0.0",
|
|
81
|
-
"@cloudgrid-io/
|
|
82
|
+
"@cloudgrid-io/runtime": "^1.0.3",
|
|
82
83
|
"mongodb": "^6.12.0"
|
|
83
84
|
}
|
|
84
85
|
}
|
|
@@ -118,11 +119,12 @@ export async function getDb() {
|
|
|
118
119
|
// Chat API route: take the user's message, ask the grid AI gateway for a reply,
|
|
119
120
|
// persist the exchange to Mongo, return the reply.
|
|
120
121
|
//
|
|
121
|
-
// The AI call uses @cloudgrid-io/
|
|
122
|
-
//
|
|
123
|
-
// (or under `grid dev`). Do NOT
|
|
122
|
+
// The AI call uses @cloudgrid-io/runtime with ZERO config — no API key. The SDK
|
|
123
|
+
// reads the gateway URL from RUNTIME_GATEWAY_URL (injected by the grid) itself,
|
|
124
|
+
// so it only works inside a deployed grid app (or under `grid dev`). Do NOT set a
|
|
125
|
+
// key or reference the env var yourself.
|
|
124
126
|
import { NextResponse } from "next/server";
|
|
125
|
-
import {
|
|
127
|
+
import { runtime } from "@cloudgrid-io/runtime";
|
|
126
128
|
import { getDb } from "../../../lib/db.js";
|
|
127
129
|
|
|
128
130
|
export const dynamic = "force-dynamic";
|
|
@@ -139,10 +141,12 @@ export async function POST(request) {
|
|
|
139
141
|
return NextResponse.json({ error: "message is required" }, { status: 400 });
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
// 1. Ask the grid AI gateway (zero-config in-grid identity — no key).
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
|
|
144
|
+
// 1. Ask the grid AI gateway (zero-config in-grid identity — no key). Chat
|
|
145
|
+
// expects a model; it returns { text }.
|
|
146
|
+
const { text: reply } = await runtime.ai.chat({
|
|
147
|
+
model: "claude-haiku",
|
|
148
|
+
messages: [{ role: "user", content: text }],
|
|
149
|
+
});
|
|
146
150
|
|
|
147
151
|
// 2. Persist the exchange so the conversation survives refresh.
|
|
148
152
|
const col = await messages();
|
|
@@ -248,7 +252,8 @@ export default function Chat({ initialHistory }) {
|
|
|
248
252
|
## Adapt it
|
|
249
253
|
|
|
250
254
|
- Give the assistant a persona — pass a `{ role: "system", content: "…" }`
|
|
251
|
-
message ahead of the user message in `chat({ messages })
|
|
255
|
+
message ahead of the user message in `runtime.ai.chat({ model, messages })`
|
|
256
|
+
(or pass `system:` directly alongside `messages`).
|
|
252
257
|
- Send prior turns as context by including the stored history in `messages`.
|
|
253
258
|
- Change the `messages` collection / fields; add users, sessions, titles.
|
|
254
259
|
- Run `grid dev` to test locally, `grid plug` to deploy (async — poll to live).
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// Chat API route: takes the user's message, asks the grid AI gateway for a
|
|
2
2
|
// reply, persists the exchange to Mongo, and returns the reply.
|
|
3
3
|
//
|
|
4
|
-
// The AI call uses @cloudgrid-io/
|
|
5
|
-
//
|
|
6
|
-
// (or under `grid dev`). Do
|
|
4
|
+
// The AI call uses @cloudgrid-io/runtime with ZERO config — no API key. The SDK
|
|
5
|
+
// reads the gateway URL from RUNTIME_GATEWAY_URL (injected by the grid) all on
|
|
6
|
+
// its own, so it only works inside a deployed grid app (or under `grid dev`). Do
|
|
7
|
+
// NOT set a key or reference the env var yourself.
|
|
7
8
|
import { NextResponse } from "next/server";
|
|
8
|
-
import {
|
|
9
|
+
import { runtime } from "@cloudgrid-io/runtime";
|
|
9
10
|
import { getDb } from "../../../lib/db.js";
|
|
10
11
|
|
|
11
12
|
// Never cache — always generate/persist live.
|
|
@@ -24,10 +25,12 @@ export async function POST(request) {
|
|
|
24
25
|
return NextResponse.json({ error: "message is required" }, { status: 400 });
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
// 1. Ask the grid AI gateway (zero-config in-grid identity — no key).
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
28
|
+
// 1. Ask the grid AI gateway (zero-config in-grid identity — no key). Chat
|
|
29
|
+
// expects a model; it returns { text }.
|
|
30
|
+
const { text: reply } = await runtime.ai.chat({
|
|
31
|
+
model: "claude-haiku",
|
|
32
|
+
messages: [{ role: "user", content: text }],
|
|
33
|
+
});
|
|
31
34
|
|
|
32
35
|
// 2. Persist the exchange so the conversation survives refresh.
|
|
33
36
|
const col = await messages();
|
|
@@ -10,7 +10,7 @@ as `app-with-data` / `crm`) with a **RAG** loop layered on: ingest documents →
|
|
|
10
10
|
chunk them → embed each chunk → store the vectors → at query time embed the
|
|
11
11
|
question, retrieve the nearest chunks, and ask the model to answer grounded in
|
|
12
12
|
them (with citations). Both the embedding and the answer step run through
|
|
13
|
-
CloudGrid's **AI Gateway** (`@cloudgrid-io/
|
|
13
|
+
CloudGrid's **AI Gateway** (`@cloudgrid-io/runtime`, injected via `needs: { ai: true }`).
|
|
14
14
|
|
|
15
15
|
> **Vector-store status (read this first):** the ideal store for embeddings is
|
|
16
16
|
> `needs: vector` (pgvector on Postgres, injecting `VECTOR_PGVECTOR_URL`), and it
|
|
@@ -32,10 +32,10 @@ URL mount, NOT the filesystem path. Files at the repo root fail with
|
|
|
32
32
|
```
|
|
33
33
|
cloudgrid.yaml # name + services.web(nextjs,/) + needs:{ai:true, database:true}
|
|
34
34
|
services/web/
|
|
35
|
-
package.json # next, react, react-dom, mongodb, @cloudgrid-io/
|
|
35
|
+
package.json # next, react, react-dom, mongodb, @cloudgrid-io/runtime
|
|
36
36
|
lib/
|
|
37
37
|
db.js # lazy Mongo client from DATABASE_MONGODB_URL (legacy MONGODB_URL fallback)
|
|
38
|
-
ai.js #
|
|
38
|
+
ai.js # @cloudgrid-io/runtime AI (auto-reads RUNTIME_GATEWAY_URL) — embed() + chat()
|
|
39
39
|
chunk.js # pure fn: splitIntoChunks(text) -> string[] (e.g. ~800-token windows, overlap)
|
|
40
40
|
retrieve.js # embed query -> cosine-rank chunks in Mongo -> top-k with scores
|
|
41
41
|
app/
|
|
@@ -86,13 +86,13 @@ injected as env vars at `grid dev` (local) and at runtime (after `grid plug`):
|
|
|
86
86
|
| What | Declared in cloudgrid.yaml | Injected env var(s) | Read in code |
|
|
87
87
|
|------|----------------------------|---------------------|--------------|
|
|
88
88
|
| MongoDB | `needs: { database: true }` | `DATABASE_MONGODB_URL` (+ legacy `MONGODB_URL`) | `lib/db.js` |
|
|
89
|
-
| AI Gateway | `needs: { ai: true }` | `
|
|
89
|
+
| AI Gateway | `needs: { ai: true }` | `RUNTIME_GATEWAY_URL` | `lib/ai.js` (via `@cloudgrid-io/runtime`) |
|
|
90
90
|
| Vector store (available — #1545 shipped) | `needs: { vector: pgvector }` | `VECTOR_PGVECTOR_URL` (+ legacy `PGVECTOR_URL`) | `lib/retrieve.js` — not used by this blueprint (Section 7 for the swap) |
|
|
91
91
|
| Auth key (optional) | `vault: { AUTH_PROVIDER_KEY: auth-provider-key }` | `AUTH_PROVIDER_KEY` | `lib/auth.js` |
|
|
92
92
|
| Stripe key (optional) | `vault: { STRIPE_KEY: stripe-live-key }` | `STRIPE_KEY` | `lib/stripe.js` |
|
|
93
93
|
|
|
94
94
|
The **AI Gateway needs no API key** — `needs: { ai: true }` injects
|
|
95
|
-
`
|
|
95
|
+
`RUNTIME_GATEWAY_URL` and `@cloudgrid-io/runtime` routes through it. The `vault:` block only
|
|
96
96
|
**maps** an org vault item key → an env var name; store the real value once with
|
|
97
97
|
`grid secrets set <vault-item-key> <value>`. Never commit a secret; never hardcode
|
|
98
98
|
a connection string.
|
|
@@ -114,23 +114,20 @@ export async function getDb() {
|
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
```js
|
|
117
|
-
// lib/ai.js —
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
globalThis.__ai ??= createClient({ baseURL: url });
|
|
123
|
-
return globalThis.__ai;
|
|
124
|
-
}
|
|
125
|
-
// embed one or many strings -> vectors (used for both indexing and queries)
|
|
117
|
+
// lib/ai.js — CloudGrid runtime AI. No API key and no baseURL: the SDK reads
|
|
118
|
+
// RUNTIME_GATEWAY_URL (injected by needs:{ai:true}) and the in-grid identity
|
|
119
|
+
// itself. Never reference the env var or pass a key.
|
|
120
|
+
import { runtime } from "@cloudgrid-io/runtime";
|
|
121
|
+
// embed one or many strings -> an aligned array of vectors (indexing + queries)
|
|
126
122
|
export async function embed(texts) {
|
|
127
|
-
const
|
|
128
|
-
|
|
123
|
+
const input = Array.isArray(texts) ? texts : [texts];
|
|
124
|
+
const vec = await runtime.ai.embeddings({ text: input }); // batch -> vec.values aligned to input order
|
|
125
|
+
return vec.values; // number[][]; vec also carries .model, .dim, .tokens
|
|
129
126
|
}
|
|
130
|
-
// grounded chat answer
|
|
131
|
-
export async function chat(messages) {
|
|
132
|
-
const
|
|
133
|
-
return
|
|
127
|
+
// grounded chat answer -> string. Chat expects a model and returns { text }.
|
|
128
|
+
export async function chat({ system, messages }) {
|
|
129
|
+
const { text } = await runtime.ai.chat({ model: "claude-haiku", system, messages });
|
|
130
|
+
return text;
|
|
134
131
|
}
|
|
135
132
|
```
|
|
136
133
|
|
|
@@ -176,7 +173,8 @@ export async function retrieve(question, k = 5) {
|
|
|
176
173
|
2. Build a system prompt: *"Answer ONLY from the provided context; if it isn't
|
|
177
174
|
there, say you don't know. Cite the chunks you used."* Put the retrieved chunk
|
|
178
175
|
texts (with ids) in the context.
|
|
179
|
-
3. `chat(
|
|
176
|
+
3. `chat({ system, messages })` via `lib/ai.js` (the grounding instruction is the
|
|
177
|
+
`system`); return the answer plus the source chunks so the
|
|
180
178
|
UI can render **citations**. Grounding + citations are the point — never let the
|
|
181
179
|
model answer from parametric memory alone.
|
|
182
180
|
|
|
@@ -4,7 +4,7 @@ A blueprint for a retrieval-augmented knowledge-base chatbot on CloudGrid: a
|
|
|
4
4
|
persistent Next.js + Mongo app that ingests documents, chunks and embeds them,
|
|
5
5
|
and answers questions grounded in the retrieved chunks (with citations) — the
|
|
6
6
|
`app-with-data` runtime shape with a RAG loop layered on. Embeddings and answers
|
|
7
|
-
run through CloudGrid's AI Gateway (`@cloudgrid-io/
|
|
7
|
+
run through CloudGrid's AI Gateway (`@cloudgrid-io/runtime`, injected via
|
|
8
8
|
`needs: { ai: true }` — works today); the ideal vector store `needs: vector`
|
|
9
9
|
(pgvector) is **now available** — #1545 shipped (verified live 2026-07-16) — but
|
|
10
10
|
this blueprint stores embeddings in Mongo and computes similarity in-app. Because RAG involves choices
|
|
@@ -101,7 +101,7 @@ needs:
|
|
|
101
101
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
102
102
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
103
103
|
# disk: true
|
|
104
|
-
# ai — AI Gateway via @cloudgrid-io/
|
|
104
|
+
# ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
105
105
|
# Powers embeddings (for indexing docs + queries) and chat completions (the
|
|
106
106
|
# answer step). Works today.
|
|
107
107
|
ai: true
|
|
@@ -203,7 +203,7 @@ services:
|
|
|
203
203
|
# path: /api/health
|
|
204
204
|
# expected: "200"
|
|
205
205
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
206
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
206
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
207
207
|
# env:
|
|
208
208
|
# LOG_LEVEL: info
|
|
209
209
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
@@ -21,7 +21,7 @@ the app following it.
|
|
|
21
21
|
`cloudgrid.yaml` is the URL mount, NOT the filesystem path.
|
|
22
22
|
2. **Read injected values LAZILY (inside a getter), never at module top level** —
|
|
23
23
|
a top-level read fails `next build`. The grid injects `DATABASE_MONGODB_URL`
|
|
24
|
-
(+ legacy `MONGODB_URL`) for Mongo and `
|
|
24
|
+
(+ legacy `MONGODB_URL`) for Mongo and `RUNTIME_GATEWAY_URL` for the AI Gateway.
|
|
25
25
|
3. **Declare `needs: { ai: true, database: true }`** (canonical shape). Never
|
|
26
26
|
author `requires:`, and never set `needs:` and `requires:` together (the
|
|
27
27
|
validator rejects the combination).
|
|
@@ -57,7 +57,7 @@ needs:
|
|
|
57
57
|
|
|
58
58
|
> **Capability:** `needs: { database: true }` → the deployer provisions Mongo and
|
|
59
59
|
> injects `DATABASE_MONGODB_URL` (plus legacy `MONGODB_URL`). `needs: { ai: true }`
|
|
60
|
-
> → injects `
|
|
60
|
+
> → injects `RUNTIME_GATEWAY_URL`; `@cloudgrid-io/runtime` routes embeddings + chat through
|
|
61
61
|
> it with no API key to manage. `needs: { vector: pgvector }` (injects
|
|
62
62
|
> `VECTOR_PGVECTOR_URL`) is available (#1545 shipped) but not declared here —
|
|
63
63
|
> this blueprint uses Mongo embeddings. See the capability-map for the full
|
|
@@ -96,7 +96,7 @@ name: analytics-dashboard
|
|
|
96
96
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
97
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
98
|
# disk: true
|
|
99
|
-
# # ai — AI Gateway via @cloudgrid-io/
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
100
100
|
# ai: true
|
|
101
101
|
|
|
102
102
|
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
# path: /api/health
|
|
193
193
|
# expected: "200"
|
|
194
194
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
195
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
195
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
196
196
|
# env:
|
|
197
197
|
# LOG_LEVEL: info
|
|
198
198
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
@@ -96,7 +96,7 @@ name: my-api-dashboard
|
|
|
96
96
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
97
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
98
|
# disk: true
|
|
99
|
-
# # ai — AI Gateway via @cloudgrid-io/
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
100
100
|
# ai: true
|
|
101
101
|
|
|
102
102
|
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
# path: /api/health
|
|
193
193
|
# expected: "200"
|
|
194
194
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
195
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
195
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
196
196
|
# env:
|
|
197
197
|
# LOG_LEVEL: info
|
|
198
198
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
@@ -96,7 +96,7 @@ name: api-docs
|
|
|
96
96
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
97
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
98
|
# disk: true
|
|
99
|
-
# # ai — AI Gateway via @cloudgrid-io/
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
100
100
|
# ai: true
|
|
101
101
|
|
|
102
102
|
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
# path: /api/health
|
|
193
193
|
# expected: "200"
|
|
194
194
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
195
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
195
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
196
196
|
# env:
|
|
197
197
|
# LOG_LEVEL: info
|
|
198
198
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|
|
@@ -96,7 +96,7 @@ name: my-api
|
|
|
96
96
|
# # disk — persistent FS mount (PVC). Injects DISK_PATH. Pins to 1 replica.
|
|
97
97
|
# # true | { size: 1Gi, mount: /var/data } (forbidden: /proc /sys /dev)
|
|
98
98
|
# disk: true
|
|
99
|
-
# # ai — AI Gateway via @cloudgrid-io/
|
|
99
|
+
# # ai — AI Gateway via @cloudgrid-io/runtime. Injects RUNTIME_GATEWAY_URL. true | false.
|
|
100
100
|
# ai: true
|
|
101
101
|
|
|
102
102
|
|
|
@@ -192,7 +192,7 @@ services:
|
|
|
192
192
|
# path: /api/health
|
|
193
193
|
# expected: "200"
|
|
194
194
|
# Static runtime env vars (strings). Reserved: PORT, APP_NAME, SERVICE_NAME,
|
|
195
|
-
# NODE_ENV, MONGODB_URL, REDIS_URL,
|
|
195
|
+
# NODE_ENV, MONGODB_URL, REDIS_URL, RUNTIME_GATEWAY_URL, N8N_WEBHOOK_URL, CLOUDGRID_*.
|
|
196
196
|
# env:
|
|
197
197
|
# LOG_LEVEL: info
|
|
198
198
|
# Sibling services/private resources that must be Ready first (no cron, no cycles).
|