You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- content/docs/guides/ai-capabilities.mdx: new "Actions as Tools
(auto-exposed)" section between AI Agents and RAG Pipelines —
what gets exposed, plugin wiring (apiActionBaseUrl /
apiActionHeaders), type:'api' body assembly rules, diagnostics.
- skills/objectstack-ai/SKILL.md: add "Auto-Exposed Actions"
subsection under Tool Configuration so action authors don't
hand-author tool defs for headless invocation.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: content/docs/guides/ai-capabilities.mdx
+55-4Lines changed: 55 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,10 +11,11 @@ Complete guide to leveraging AI agents, RAG pipelines, and intelligent automatio
11
11
12
12
1.[AI Architecture](#ai-architecture)
13
13
2.[AI Agents](#ai-agents)
14
-
3.[RAG Pipelines](#rag-pipelines)
15
-
4.[Natural Language Queries](#natural-language-queries)
16
-
5.[Predictive Analytics](#predictive-analytics)
17
-
6.[Best Practices](#best-practices)
14
+
3.[Actions as Tools (auto-exposed)](#actions-as-tools-auto-exposed)
15
+
4.[RAG Pipelines](#rag-pipelines)
16
+
5.[Natural Language Queries](#natural-language-queries)
17
+
6.[Predictive Analytics](#predictive-analytics)
18
+
7.[Best Practices](#best-practices)
18
19
19
20
---
20
21
@@ -356,6 +357,56 @@ Use statistical analysis and ML.`,
356
357
357
358
---
358
359
360
+
## Actions as Tools (auto-exposed)
361
+
362
+
Every declarative {@linkAction} you attach to an object is **automatically exposed as an AI tool**, named `action_<actionName>`. When the LLM picks one, the AI runtime dispatches to the same handler Studio's row toolbar would invoke — your business logic stays in one place.
363
+
364
+
### What gets exposed
365
+
366
+
The AI runtime walks every registered object's `actions[]` and exposes the ones that pass safety + wiring checks. Three action types are supported:
367
+
368
+
|`action.type`| Dispatch path | Wiring needed |
369
+
|:---|:---|:---|
370
+
|`script`|`IDataEngine.executeAction(object, target, ctx)` — the same call Studio makes | none beyond the metadata service |
371
+
|`api`| HTTP call to `action.target` via `ApiActionClient` (default: `fetch`) |`apiBaseUrl` (or a custom `apiClient`) |
372
+
|`flow`|`IAutomationService.execute(target, { triggerData })`|`automation` service registered |
373
+
374
+
Studio-only types (`url`, `modal`, `form`) and any action with `confirmText`, `mode: 'delete'`, or `variant: 'danger'` are skipped — those require Phase-3 HITL approval. Owners can also opt out per action with `aiExposed: false`.
If `automation` is already registered with the kernel, `type:'flow'` actions are picked up automatically — no extra wiring needed.
393
+
394
+
### `type:'api'` body assembly
395
+
396
+
For api actions, the request body is built from three sources (last wins):
397
+
398
+
1.**User-collected params** (the keys the LLM filled in).
399
+
2.**`recordIdParam`** — when row-context, the id is placed flat at `action.recordIdParam`, using `recordIdField` (default `'id'`) to pick the value off the record.
400
+
3.**`bodyExtra`** — constant fields that always override.
401
+
402
+
`bodyShape: { wrap: 'data' }` nests the user params under `data` while keeping `recordIdParam` flat — matching shapes like better-auth's `organization/update`.
403
+
404
+
### Diagnostics
405
+
406
+
`registerActionsAsTools()` returns `{ registered, skipped }`. Studio surfaces the skipped list with reasons (e.g. `"no apiClient or apiBaseUrl configured"`, `"mode='delete' — destructive"`) so action authors can see at a glance whether their action will be LLM-callable.
407
+
408
+
---
409
+
359
410
## RAG Pipelines
360
411
361
412
Retrieval-Augmented Generation (RAG) provides AI with access to your knowledge base.
Copy file name to clipboardExpand all lines: skills/objectstack-ai/SKILL.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -219,6 +219,27 @@ Tools are the atomic operations that skills expose to agents.
219
219
}
220
220
```
221
221
222
+
### Auto-Exposed Actions
223
+
224
+
You usually **don't author tool definitions by hand** for action invocation. Every `Action` you attach to an object via `defineObject({ actions: [...] })` is auto-exposed as a tool named `action_<actionName>` by `registerActionsAsTools()` (invoked from `AIServicePlugin`).
225
+
226
+
Three action types dispatch headlessly:
227
+
228
+
|`action.type`| Dispatch | Wiring |
229
+
|:---|:---|:---|
230
+
|`script`|`IDataEngine.executeAction(object, target, ctx)` — same as Studio's row toolbar | none |
231
+
|`api`| HTTP call to `action.target` (`fetch`-based by default) |`AIServicePlugin({ apiActionBaseUrl, apiActionHeaders })` or custom `apiClient`|
232
+
|`flow`|`IAutomationService.execute(target, { triggerData })`|`automation` service registered with the kernel |
**`type:'api'` body assembly** (last wins): user params → `recordIdParam` (using `recordIdField`, default `'id'`) → `bodyExtra`. `bodyShape: { wrap: 'data' }` nests user params under `data` while keeping `recordIdParam` flat.
240
+
241
+
Use `actionSkipReason(action, ctx)` (exported from `@objectstack/service-ai`) when authoring an action and you want to know *why* it isn't surfacing in chat. Studio's "AI exposure" diagnostics use the same predicate.
0 commit comments