@layers/amba 4.0.3 → 4.0.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layers/amba",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "description": "amba — agent-native backend-as-a-service. Functions, collections, storage, AI, email, queues, sites — one CLI to spin up your project and ship to production. `npx @layers/amba init` to start.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -49,8 +49,8 @@
49
49
  "tsdown": "^0.12.5",
50
50
  "typescript": "^5.8.3",
51
51
  "vitest": "^3.2.4",
52
- "@layers/amba-mcp": "4.0.2",
53
- "@layers/amba-shared": "4.0.2"
52
+ "@layers/amba-mcp": "4.0.6",
53
+ "@layers/amba-shared": "4.0.4"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "tsdown && tsc --emitDeclarationOnly",
@@ -71,6 +71,8 @@ Check whether a project exists in this directory:
71
71
 
72
72
  > **If you don't see Amba MCP tools available** (no `mcp__amba__*` in your tool list), Amba's MCP server isn't wired into your agent's tool surface this session. Run `npx -y @layers/amba init` via your bash tool — it provisions the account/project, writes `.env.local`, installs this skill, and wires the MCP entry into the user's agent config so the typed tools light up on the next agent launch.
73
73
  >
74
+ > **If your harness ALSO blocks that bash command** (a locked-down agent: no installer, no network egress, no settings edits) — do NOT try to add the MCP server yourself, run the installer another way, or edit your own settings/permissions to authorize it. Refusing to self-modify or widen your own permissions is correct; don't circumvent it. Instead, ask the developer to run **one** command in **their own** terminal (not subject to your sandbox): `npx @layers/amba init`. It creates the account with no browser and writes `AMBA_PROJECT_ID` + `AMBA_CLIENT_KEY` to `.env.local`. Ask them to run it, say when it's done, then resume from Step 0 by reading `.env.local`. Pasting an `amb_ck_…` client key is the last-resort lite path — enough to wire `Amba.configure()` + verify events land, but a client key alone can't do admin provisioning (achievements, collections, segments), which needs the PAT/server key.
75
+ >
74
76
  > Do not pause to ask the user about restarting. You have **three** working paths for admin operations in this session, in order of preference:
75
77
  >
76
78
  > 1. **POST JSON-RPC directly to `https://mcp.amba.dev/mcp`** (recommended — full 178-tool surface, no client wiring needed). Amba's MCP is plain HTTP, not stdio. Read the PAT from `~/.amba/credentials.json` (`.pat` field), then `curl` (or `fetch`) the endpoint:
@@ -15,7 +15,7 @@ A collection is a schema-first table inside the project's isolated tenant databa
15
15
  | `amba_collections_create` / `amba_create_collection` | Create a typed collection. | `{ project_id, name: "todos", columns: [{ name: "title", type: "text", nullable: false }, { name: "done", type: "boolean", nullable: false, default: false }, { name: "due_at", type: "timestamptz", nullable: true }] }` |
16
16
  | `amba_collections_list` / `amba_list_collections` | List collections in this project. | `{ project_id }` |
17
17
  | `amba_collections_get` / `amba_get_collection` | Read one collection's schema. | `{ project_id, collection_name: "todos" }` |
18
- | `amba_collections_alter` / `amba_alter_collection` | Add / drop columns, add / drop indexes. | `{ project_id, collection_name: "todos", add_columns: [{ name: "priority", type: "int", nullable: true }] }` |
18
+ | `amba_collections_alter` / `amba_alter_collection` | Add / drop columns, add / drop indexes. | `{ project_id, collection_name: "todos", add_columns: [{ name: "priority", type: "integer", nullable: true }] }` |
19
19
  | `amba_collections_delete` / `amba_delete_collection` | Drop the table (destructive). | `{ project_id, collection_name }` |
20
20
  | `amba_admin_insert_row` | Insert a row as the developer (bypasses user-scope). Useful for seed data. | `{ project_id, collection: "todos", row: { title: "Sample todo", done: false } }` |
21
21
  | `amba_admin_list_rows` | Read rows as the developer (bypasses user-scope — sees every user's rows). | `{ project_id, collection: "todos", limit: 100 }` |
@@ -28,7 +28,7 @@ A collection is a schema-first table inside the project's isolated tenant databa
28
28
  | `amba_client_find_rows` | Filter / sort / paginate rows (end-user). | `{ project_id, api_key, session_token, collection, filter: {...}, order_by: [...], limit: 50 }` |
29
29
  | `amba_client_find_nearest_rows` | Vector-similarity search (rows with a `vector(<dim>)` column). | `{ project_id, api_key, session_token, collection, vector_column: "embedding", query_vector: [...], k: 10 }` |
30
30
 
31
- Column types: `text`, `int`, `bigint`, `float`, `boolean`, `timestamptz`, `date`, `json`, `jsonb`, `uuid`, `vector(<dim>)` (e.g. `vector(1536)` for OpenAI embeddings).
31
+ Column types: `text`, `integer`, `bigint`, `numeric`, `boolean`, `timestamptz`, `date`, `jsonb`, `uuid`, `vector(<dim>)` (e.g. `vector(1536)` for OpenAI embeddings), plus array forms `text[]`, `integer[]`, `bigint[]`, `numeric[]`, `boolean[]`, `uuid[]`. Use `integer` (not `int`), `numeric` (not `float`/`real`/`double`), and `jsonb` (not `json`) — the validator rejects the aliases.
32
32
 
33
33
  ### Functions (serverless code)
34
34
 
@@ -48,16 +48,21 @@ Run user code in a sandbox triggered by HTTP, cron, or webhook. The function get
48
48
 
49
49
  ### AI prompts
50
50
 
51
- Managed LLM templates: stored prompt with model + system message + variables, callable by name from the SDK. The actual LLM call is rewritten per-tenant — the customer's API keys (Anthropic / OpenAI) live in the tenant secrets, never on the device.
51
+ Managed LLM templates: a stored prompt with provider + model + system message, invoked by name from the SDK. The actual LLM call is rewritten server-side per-tenant — the customer's provider API key (Anthropic / OpenAI / Mistral / Gemini) stays server-side, never on the device.
52
+
53
+ **Two steps, in order:** register the provider key with `amba_ai_providers_set`, then create prompts against it. A prompt registered before its provider has a key still saves, but invocations fail with `provider_not_configured` (424) until the key is set. The provider key is **not** a function secret — `amba_secrets_set` writes function-scoped Worker secrets the AI gateway never reads; provider keys live in a separate gateway-owned store set only via `amba_ai_providers_set`.
52
54
 
53
55
  | Tool | Purpose | Example args |
54
56
  | --- | --- | --- |
55
- | `amba_ai_prompts_create` / `amba_create_ai_prompt` | Create a prompt template. | `{ project_id, key: "summarize", model: "claude-opus-4-5", system: "Summarize the user's text in 2 sentences.", variables: ["text"] }` |
57
+ | `amba_ai_providers_set` | Register / rotate the upstream provider API key. **Do this first.** | `{ project_id, provider: "anthropic", api_key: "sk-ant-..." }` |
58
+ | `amba_ai_providers_list` | List registered providers (`configured` = key set). | `{ project_id }` |
59
+ | `amba_ai_providers_delete` | Revoke a provider key (fails if prompts still reference it). | `{ project_id, provider: "anthropic" }` |
60
+ | `amba_ai_prompts_create` / `amba_create_ai_prompt` | Create a prompt template. | `{ project_id, name: "summarize", provider: "anthropic", model: "claude-opus-4-5", system_prompt: "Summarize the user's text in 2 sentences.", client_invokable: true }` |
56
61
  | `amba_ai_prompts_list` / `amba_list_ai_prompts` | List prompts. | `{ project_id }` |
57
- | `amba_ai_prompts_get` / `amba_get_ai_prompt` | Read one prompt. | `{ project_id, key }` |
58
- | `amba_ai_prompts_update` / `amba_update_ai_prompt` | Edit a prompt (model swap, system message change). | `{ project_id, key, system: "..." }` |
59
- | `amba_ai_prompts_invoke` / `amba_invoke_ai_prompt` | Invoke a prompt server-side (no client involvement — admin testing). | `{ project_id, key, variables: { text: "..." } }` |
60
- | `amba_ai_prompts_delete` / `amba_delete_ai_prompt` | Delete. | `{ project_id, key }` |
62
+ | `amba_ai_prompts_get` / `amba_get_ai_prompt` | Read one prompt. | `{ project_id, name }` |
63
+ | `amba_ai_prompts_update` / `amba_update_ai_prompt` | Edit a prompt (replaces all fields; bumps version). | `{ project_id, name, provider, model, system_prompt: "..." }` |
64
+ | `amba_ai_prompts_invoke` / `amba_invoke_ai_prompt` | Invoke a prompt server-side (admin testing). `messages` is a provider-shaped array. | `{ project_id, name, messages: [{ role: "user", content: "..." }] }` |
65
+ | `amba_ai_prompts_delete` / `amba_delete_ai_prompt` | Delete. | `{ project_id, name }` |
61
66
 
62
67
  ### Analytics + events + sessions
63
68
 
@@ -75,7 +80,7 @@ Managed LLM templates: stored prompt with model + system message + variables, ca
75
80
 
76
81
  | Tool | Purpose | Example args |
77
82
  | --- | --- | --- |
78
- | `amba_secrets_set` / `amba_set_secret` | Set a tenant secret (encrypted at rest). Use for third-party API keys called from functions. | `{ project_id, name: "OPENAI_API_KEY", value: "sk-..." }` |
83
+ | `amba_secrets_set` / `amba_set_secret` | Set a **function-scoped** secret (encrypted at rest; bound on the next deploy). For third-party API keys called from your functions — NOT AI provider keys (use `amba_ai_providers_set` for those). | `{ project_id, name: "STRIPE_WEBHOOK_SECRET", value: "whsec_..." }` |
79
84
  | `amba_secrets_get` / `amba_get_secret` | Read a secret (returns `"<redacted>"` unless explicitly requested). | `{ project_id, name }` |
80
85
  | `amba_secrets_list` / `amba_list_secrets` | List secret names. | `{ project_id }` |
81
86
  | `amba_secrets_delete` / `amba_delete_secret` | Delete. | `{ project_id, name }` |
@@ -138,9 +143,9 @@ const newTodo = await Amba.collections.insert('todos', {
138
143
  await Amba.collections.update('todos', newTodo.id, { done: true });
139
144
  await Amba.collections.delete('todos', newTodo.id);
140
145
 
141
- // AI — call a managed prompt
146
+ // AI — call a managed prompt (prompt_slug names the registered prompt)
142
147
  const response = await Amba.ai.anthropic.messages.create({
143
- prompt_key: 'summarize',
148
+ prompt_slug: 'summarize',
144
149
  variables: { text: 'A long article about backend services …' },
145
150
  });
146
151
  // response.content — the model's reply
@@ -230,8 +235,7 @@ try await Amba.events.track("app_opened", properties: ["source": "deep_link"])
230
235
 
231
236
  // AI
232
237
  let reply = try await Amba.ai.anthropic.messages.create(
233
- promptKey: "summarize",
234
- variables: ["text": "A long article..."]
238
+ request: AiMessageRequest(promptSlug: "summarize", variables: ["text": "A long article..."])
235
239
  )
236
240
  ```
237
241
 
@@ -248,8 +252,7 @@ val showBeta = Amba.flags.get("beta_feature")
248
252
  Amba.events.track("app_opened", mapOf("source" to "deep_link"))
249
253
 
250
254
  val reply = Amba.ai.anthropic.messages.create(
251
- promptKey = "summarize",
252
- variables = mapOf("text" to "A long article…")
255
+ AiMessageRequest(promptSlug = "summarize", variables = mapOf("text" to "A long article…"))
253
256
  )
254
257
  ```
255
258
 
@@ -268,7 +271,7 @@ final showBeta = await Amba.flags.get('beta_feature');
268
271
  await Amba.events.track('app_opened', {'source': 'deep_link'});
269
272
 
270
273
  final reply = await Amba.ai.anthropic.messages.create(
271
- promptKey: 'summarize',
274
+ promptSlug: 'summarize',
272
275
  variables: {'text': 'A long article…'},
273
276
  );
274
277
  ```
@@ -333,7 +336,7 @@ Batch.
333
336
  2. Before creating:
334
337
  - `amba_collections_list` — match on `name`. Collisions: never silently recreate (data loss). Offer `amba_collections_alter` to add new columns instead.
335
338
  - `amba_functions_list` — match on `name`. Collisions: ask to redeploy (with the new source) or skip.
336
- - `amba_ai_prompts_list` — match on `key`. Same.
339
+ - `amba_ai_prompts_list` — match on `name`. Same. (And `amba_ai_providers_list` — match on `provider`; re-running `amba_ai_providers_set` rotates the key in place.)
337
340
  - `amba_integrations_list` — match on `provider`. Same.
338
341
  - `amba_configs_list` — match on `key`. Same.
339
342