mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-30 11:43:26 +08:00
513 lines
25 KiB
Markdown
513 lines
25 KiB
Markdown
# sObject field reference — architecture skill
|
|
|
|
Field reference for the 13 sObjects this skill queries across the 15
|
|
SOQL templates under `assets/soql/`. Two are reached via the Data API
|
|
(`BotDefinition`, `BotVersion`); the remaining 11 are Tooling-only.
|
|
|
|
**Source of truth: the live org** (`sf sobject describe --sobject <Name>
|
|
[--use-tooling-api]`). Schemas verified against live Salesforce API
|
|
v66.0 via `sf sobject describe` on `my-org-alias` + `my-org-alias-2`,
|
|
2026-05-02. Official Salesforce Help pages describe logical structures
|
|
that frequently diverge from the physical fields the REST / Tooling API
|
|
actually expose. When a Help page disagrees with a live describe, trust
|
|
the live describe — the names in this reference are what you query.
|
|
|
|
The source of truth for "mandatory" is `scripts/probe_channels.py`'s
|
|
`MANDATORY_FIELDS` map. A probe that sees any `[mandatory]` field
|
|
missing flips to `status: "PROBE_FAILED"` — the skill aborts with a
|
|
clean error rather than producing a subtly-wrong tree. `[optional]`
|
|
fields degrade gracefully — missing ones are recorded but don't block
|
|
the run.
|
|
|
|
---
|
|
|
|
## Casing gotchas
|
|
|
|
- **Mixed case is mandatory for `GenAi*` sObjects.** API names are
|
|
`GenAiPlannerDefinition`, `GenAiPluginDefinition`, `GenAiFunctionDefinition`,
|
|
`GenAiPluginFunctionDef`, `GenAiPluginInstructionDef`,
|
|
`GenAiPlannerFunctionDef`, `GenAiPlannerAttrDefinition`. Lowercase
|
|
variants (`genai_planner_definition`, `genaiplannerdefinition`) do not
|
|
resolve. The SOQL parser is case-insensitive on keywords but
|
|
sObject + field names must match the describe output for Tooling API
|
|
calls to route correctly.
|
|
- **`GenAiPluginFunctionDef` vs `GenAiPlannerFunctionDef` are different
|
|
tables.** Plugin-scope join (topic → function, via `PluginId`) vs
|
|
planner-bundle-scope join (planner → function, via `PlannerId`). Both
|
|
are 10-field join tables with nearly identical shape; keep them
|
|
straight.
|
|
- **`BotVersion.DeveloperName` is the version id, not the version
|
|
label.** `DeveloperName` on BotVersion is the version API name (e.g.
|
|
`v5`), used as the second path segment under
|
|
`<org_id15>/<agent>__<version>/`. `MasterLabel` is the
|
|
human-readable label (e.g. "Version 5 — ported from staging"). Never
|
|
mix them — the data dir layout and the SKILL.md input contract both
|
|
key on `DeveloperName`.
|
|
- **`complexvalue` fields require single-row retrieval.** `Metadata`
|
|
(on `Flow`, `FlowDefinition`, `GenAiPluginDefinition`,
|
|
`GenAiFunctionDefinition`), `SymbolTable` (on `ApexClass`), and
|
|
`AgentGraph` (on `GenAiPlannerDefinition`, often null in practice) are
|
|
`complexvalue` types. Salesforce enforces
|
|
`MALFORMED_QUERY: When retrieving results with Metadata or FullName
|
|
fields, the query qualifications must specify no more than one row for
|
|
retrieval.` Batch IN-clause SELECTs that return ≥2 rows fail. Use a
|
|
single-row equality (`WHERE Id = '<id>'`) per fetch; parallelize
|
|
across ids via `concurrent.futures`. `ApexClass.Body` +
|
|
`ApexClass.SymbolTable` is the one notable exception: the
|
|
`Name IN (...)` batch works even though `SymbolTable` is complex.
|
|
|
|
---
|
|
|
|
## Cross-sObject join map
|
|
|
|
Every edge is strictly **forward** from the entry query
|
|
(`GenAiPlannerDefinition WHERE DeveloperName = :planner_name`). No
|
|
backward lookups.
|
|
|
|
```text
|
|
BotDefinition (Data API, PK Id, matched by DeveloperName)
|
|
└── BotVersion (Data API, FK BotDefinitionId)
|
|
│ [resolved to planner name via Bot metadata retrieve]
|
|
▼
|
|
GenAiPlannerDefinition (Tooling, PK Id, matched by DeveloperName)
|
|
│
|
|
├── GenAiPluginDefinition ← WHERE PlannerId = :plannerId
|
|
│ ├── GenAiPluginInstructionDef ← WHERE GenAiPluginDefinitionId IN (:topic_ids)
|
|
│ ├── GenAiPluginFunctionDef ← WHERE PluginId IN (:topic_ids)
|
|
│ │ └── Function picklist → GenAiFunctionDefinition.Id
|
|
│ └── GenAiFunctionDefinition ← WHERE PluginId IN (:topic_ids)
|
|
│
|
|
├── GenAiPlannerFunctionDef ← WHERE PlannerId = :plannerId
|
|
│ └── Plugin picklist → GenAiPluginDefinition.Id (or external via retrieve)
|
|
│
|
|
├── GenAiFunctionDefinition ← WHERE PluginId IN (:topic_ids)
|
|
│ │ (single-query — see functions_by_plugins.soql)
|
|
│ │
|
|
│ └── InvocationTargetType + InvocationTarget route to:
|
|
│ ├── flow → FlowDefinition (batch IN) → Flow.Metadata (parallel single-row)
|
|
│ ├── apex → ApexClass (batch IN, Body + SymbolTable)
|
|
│ ├── standardInvocableAction → (no further fetch — declared only)
|
|
│ └── generatePromptResponse → GenAiPromptTemplate (Metadata API retrieve)
|
|
│
|
|
└── GenAiPlannerAttrDefinition ← WHERE ParentId IN (:function_ids, :planner_id)
|
|
(polymorphic ParentId: GenAiFunctionDefinition OR GenAiPlannerDefinition)
|
|
```
|
|
|
|
Per-channel row counts + `_unresolved[]` reasons are recorded in
|
|
`metadata_tree.json` under `_channels` and `_unresolved` keys.
|
|
|
|
---
|
|
|
|
## Data API sObjects (2)
|
|
|
|
### `BotDefinition` (Data API) — one row per agent
|
|
|
|
Root of the agent metadata. Matched by `DeveloperName`; the rest of the
|
|
tree is resolved forward from the `BotVersion` child.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `DeveloperName` | string | no | yes | [mandatory] |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `AgentType` | picklist | yes | yes | [optional] — discriminator for classic vs NGA in some orgs |
|
|
| `Type` | picklist | yes | yes | [optional] |
|
|
| `AgentTemplate` | string | yes | yes | [optional] — e.g. `SvcCopilotTmpl__EinsteinAgentKind` |
|
|
| `BotSource` | picklist | yes | yes | [optional] |
|
|
| `AgentUser` | reference | yes | yes | [optional] — FK to `User` |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `LastModifiedDate` | datetime | no | yes | [optional] |
|
|
| `SystemModstamp` | datetime | no | yes | [optional] |
|
|
|
|
### `BotVersion` (Data API) — one row per agent version
|
|
|
|
Resolves the active version (or user-pinned version) for a given bot.
|
|
Parent relationship: `BotDefinition` via `BotDefinitionId`.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `BotDefinitionId` | reference | no | yes | [mandatory] |
|
|
| `DeveloperName` | string | no | yes | [optional] — version id (e.g. `v5`) |
|
|
| `MasterLabel` | string | yes | yes | [optional] — human label |
|
|
| `Status` | picklist | yes | yes | [optional] — `Active` on the current published version |
|
|
| `VersionNumber` | int | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `AiReplyRecordVisibility` | picklist | yes | yes | [optional] |
|
|
| `ResponseDelayMilliseconds` | int | yes | yes | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `LastModifiedDate` | datetime | no | yes | [optional] |
|
|
|
|
---
|
|
|
|
## Tooling API sObjects (11)
|
|
|
|
All sObjects in this section are reachable via the Tooling API only
|
|
(`sf data query --use-tooling-api` or `sf sobject describe --use-tooling-api`).
|
|
|
|
### `ApexClass` (Tooling) — Apex source + parsed AST
|
|
|
|
Source + full method/property AST for Apex referenced by
|
|
`GenAiFunctionDefinition.InvocationTarget` when
|
|
`InvocationTargetType = 'apex'`. Batch-safe on `Name IN (...)` or
|
|
`Id IN (...)` (despite `SymbolTable` being `complexvalue`, Salesforce
|
|
permits the batch for this particular sObject — verified live).
|
|
|
|
**Note:** `SymbolTable` is **not part of `FIELDS(ALL)`** and must be
|
|
named explicitly in the SELECT.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `Name` | string | no | yes | [mandatory] |
|
|
| `Body` | textarea | yes | no | [optional] — full Apex source |
|
|
| `SymbolTable` | complexvalue | yes | no | [optional] — parsed AST (methods, params, annotations, line/col) |
|
|
| `ApiVersion` | double | no | yes | [optional] |
|
|
| `IsValid` | boolean | no | yes | [optional] |
|
|
| `Status` | picklist | no | yes | [optional] |
|
|
| `LengthWithoutComments` | int | yes | yes | [optional] |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `FullName` | string | yes | no | [optional] — complexvalue companion |
|
|
| `Metadata` | complexvalue | yes | no | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `LastModifiedDate` | datetime | no | yes | [optional] |
|
|
| `SystemModstamp` | datetime | no | yes | [optional] |
|
|
|
|
**Single-row requirement for complexvalue columns:** `Metadata` and
|
|
`FullName` on `ApexClass` follow the standard `MALFORMED_QUERY` rule —
|
|
batch IN-clause SELECTs that return ≥2 rows fail when these two are
|
|
selected. `Body` + `SymbolTable` are the exception (batch works).
|
|
Comments in `assets/soql/apex_class_bodies_by_ids.soql` +
|
|
`apex_class_bodies_by_names.soql` pin this.
|
|
|
|
### `Flow` (Tooling) — Flow version body
|
|
|
|
Single-row retrieval required — `Metadata` and `FullName` are both
|
|
`complexvalue`. Fired once per `activeVersionId` returned by
|
|
`FlowDefinition`; parallelized via `ThreadPoolExecutor`.
|
|
|
|
**Filterability quirk:** `FullName` is selectable but **not filterable**
|
|
(`INVALID_FIELD: field 'FullName' can not be filtered in a query call`).
|
|
Filter by `Id` instead.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `DefinitionId` | reference | no | yes | [mandatory] |
|
|
| `FullName` | string | yes | **no** | [optional] — complexvalue companion; not filterable |
|
|
| `Metadata` | complexvalue | yes | no | [optional] — full flow JSON (actionCalls, subflows, variables, decisions, formulas, assignments, apexPluginCalls) |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `VersionNumber` | int | yes | yes | [optional] |
|
|
| `ProcessType` | picklist | yes | yes | [optional] |
|
|
| `Status` | picklist | yes | yes | [optional] |
|
|
| `ApiVersion` | double | yes | yes | [optional] |
|
|
| `IsActive` | boolean | no | yes | [optional] |
|
|
| `IsTemplate` | boolean | no | yes | [optional] |
|
|
| `RunInMode` | picklist | yes | yes | [optional] |
|
|
| `Environments` | picklist | yes | yes | [optional] |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `OverriddenFlowId` | reference | yes | yes | [optional] |
|
|
| `SourceTemplateId` | reference | yes | yes | [optional] |
|
|
| `TriggerType` | picklist | yes | yes | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `LastModifiedDate` | datetime | no | yes | [optional] |
|
|
| `SystemModstamp` | datetime | no | yes | [optional] |
|
|
| `InstalledPackageName` | string | yes | yes | [optional] |
|
|
|
|
**Single-row requirement:** `Metadata` and `FullName` force
|
|
`WHERE Id = '<version_id>'`. The SOQL asset `flow_metadata_by_id.soql`
|
|
encodes this as a single `Id = '...'` predicate.
|
|
|
|
### `FlowDefinition` (Tooling) — Flow versioning index
|
|
|
|
Two-hop feeder to `Flow`. Batch IN-clause works. Returns
|
|
`ActiveVersionId` + `LatestVersionId` — the skill prefers active.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `DeveloperName` | string | no | yes | [mandatory] |
|
|
| `ActiveVersionId` | reference | yes | yes | [optional] — FK to `Flow.Id` |
|
|
| `LatestVersionId` | reference | yes | yes | [optional] — FK to `Flow.Id` |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `Metadata` | complexvalue | yes | no | [optional] — definition-level metadata (may carry what the Flow hop provides on some orgs) |
|
|
| `FullName` | string | yes | no | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `LastModifiedDate` | datetime | no | yes | [optional] |
|
|
| `SystemModstamp` | datetime | no | yes | [optional] |
|
|
|
|
### `GenAiPlannerDefinition` (Tooling) — planner root
|
|
|
|
Entry query for the tree. Matched by `DeveloperName` (the
|
|
`<genAiPlannerName>` extracted from the Bot metadata retrieve). The
|
|
`PlannerType` picklist is the classifier for classic ReAct vs NGA.
|
|
|
|
**Seven-value `PlannerType` picklist** (verified consistent across
|
|
`my-org-alias`, `my-org-alias-2`, `my-org-alias-3`): grouped by
|
|
namespace — `AiCopilot__*` = classic ReAct family,
|
|
`Atlas__*` = NGA family. `startswith("Atlas__")` is a clean
|
|
classic-vs-NGA discriminator.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `DeveloperName` | string | no | yes | [mandatory] |
|
|
| `PlannerType` | picklist | yes | yes | [mandatory] |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `Capabilities` | textarea | yes | no | [optional] — null in every row tested on both classic + NGA |
|
|
| `AgentGraph` | complexvalue | yes | no | [optional] — null in every row tested; single-row rule still applies |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `Metadata` | complexvalue | yes | no | [optional] |
|
|
| `FullName` | string | yes | no | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `LastModifiedDate` | datetime | no | yes | [optional] |
|
|
| `SystemModstamp` | datetime | no | yes | [optional] |
|
|
|
|
**Single-row requirement for complexvalue columns:** `AgentGraph`,
|
|
`Metadata`, `FullName` — select individually; entry query pins
|
|
`WHERE DeveloperName = '...' LIMIT 1`.
|
|
|
|
### `GenAiPluginDefinition` (Tooling) — topics
|
|
|
|
All topics for a planner via `WHERE PlannerId = :plannerId`. Carries
|
|
`PluginType` + `Scope` for topic classification and `CanEscalate` /
|
|
`IsLocal` for behavior flags.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `DeveloperName` | string | no | yes | [mandatory] |
|
|
| `PluginType` | picklist | yes | yes | [optional] — topic type classifier |
|
|
| `Scope` | textarea | yes | no | [optional] — natural-language topic scope |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `CanEscalate` | boolean | yes | yes | [optional] |
|
|
| `IsLocal` | boolean | yes | yes | [optional] |
|
|
| `Source` | picklist | yes | yes | [optional] |
|
|
| `ParentId` | reference | yes | yes | [optional] — planner FK (sometimes referred to as `PlannerId` in SOQL filter clauses) |
|
|
| `LocalDeveloperName` | string | yes | yes | [optional] |
|
|
| `Language` | picklist | yes | yes | [optional] |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `Metadata` | complexvalue | yes | no | [optional] |
|
|
| `FullName` | string | yes | no | [optional] |
|
|
| `ClassificationDescription` | textarea | yes | no | [optional] |
|
|
| `GenAiFunctionInvoker` | string | yes | yes | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
|
|
**Single-row requirement:** `Metadata` + `FullName` require per-id
|
|
retrieval. The production path doesn't SELECT `Metadata` on this sObject
|
|
(see `plugins_by_planner.soql`) — it pulls `Scope` + scalar fields
|
|
instead, which batch-safely over `PlannerId = :id`.
|
|
|
|
### `GenAiPluginFunctionDef` (Tooling) — plugin-function join
|
|
|
|
Join table: `GenAiPluginDefinition` → `GenAiFunctionDefinition`. Batch-
|
|
safe on `PluginId IN (...)`.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `PluginId` | reference | no | yes | [mandatory] |
|
|
| `Function` | picklist | yes | yes | [optional] — references `GenAiFunctionDefinition.Id` |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `SystemModstamp` | datetime | no | yes | [optional] |
|
|
|
|
### `GenAiPluginInstructionDef` (Tooling) — per-topic instructions
|
|
|
|
Per-topic instruction text + ordering. Batch-safe on
|
|
`GenAiPluginDefinitionId IN (...)`.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `GenAiPluginDefinitionId` | reference | no | yes | [mandatory] |
|
|
| `DeveloperName` | string | no | yes | [optional] |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] — the instruction text |
|
|
| `SortOrder` | int | yes | yes | [optional] |
|
|
| `Language` | picklist | yes | yes | [optional] |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `FullName` | string | yes | no | [optional] |
|
|
| `Metadata` | complexvalue | yes | no | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
|
|
**Single-row requirement:** `Metadata` + `FullName` complexvalue pair;
|
|
the production SOQL omits them (scalar fields batch-safely).
|
|
|
|
### `GenAiFunctionDefinition` (Tooling) — actions
|
|
|
|
The actions. Combined single-query fetches both bundle-scope (`PlannerId`)
|
|
and topic-scope (`PluginId IN`) functions. `InvocationTargetType`
|
|
+ `InvocationTarget` route to the downstream fetch (Flow, Apex, prompt,
|
|
standard invocable).
|
|
|
|
**`InvocationTarget` format varies by planner shape** (the ID-prefix
|
|
router lives in `scripts/resolve_invocation_target.py`):
|
|
- Classic ReAct: DeveloperName string (e.g. `AGNT_SetUserSelectedOption`).
|
|
- NGA: Salesforce 15/18-char Id (e.g. `01pVF...` = ApexClass,
|
|
`300VF...` = FlowDefinition, `0hf...` = GenAiPromptTemplate).
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `DeveloperName` | string | no | yes | [mandatory] |
|
|
| `InvocationTarget` | string | yes | yes | [mandatory] |
|
|
| `InvocationTargetType` | picklist | yes | yes | [optional] — `flow` / `apex` / `standardInvocableAction` / `generatePromptResponse` |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `IsLocal` | boolean | yes | yes | [optional] |
|
|
| `IsConfirmationRequired` | boolean | yes | yes | [optional] |
|
|
| `IsIncludeInProgressIndicator` | boolean | yes | yes | [optional] |
|
|
| `ProgressIndicatorMessage` | string | yes | yes | [optional] |
|
|
| `Source` | picklist | yes | yes | [optional] |
|
|
| `PluginId` | reference | yes | yes | [optional] — topic-scope FK (null for bundle-scope functions) |
|
|
| `PlannerId` | reference | yes | yes | [optional] — bundle-scope FK (null on NGA — attachment is plugin-only) |
|
|
| `ParentId` | reference | yes | yes | [optional] |
|
|
| `LocalDeveloperName` | string | yes | yes | [optional] |
|
|
| `Language` | picklist | yes | yes | [optional] |
|
|
| `InvocationTargetApiName` | string | yes | yes | [optional] |
|
|
| `MissingValuePromptMessage` | string | yes | yes | [optional] |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `Metadata` | complexvalue | yes | no | [optional] |
|
|
| `FullName` | string | yes | no | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
|
|
**Single-row requirement:** `Metadata` + `FullName` complexvalue
|
|
columns; production SOQL omits both to keep the `PlannerId / PluginId IN`
|
|
batch path intact.
|
|
|
|
### `GenAiPlannerFunctionDef` (Tooling) — planner-bundle join
|
|
|
|
Bundle-scope join: planner → function. Analogous to
|
|
`GenAiPluginFunctionDef` but keyed on `PlannerId`. Batch-safe on
|
|
`PlannerId = :id`.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `PlannerId` | reference | no | yes | [mandatory] |
|
|
| `Plugin` | picklist | yes | yes | [optional] — references plugin DeveloperName / id |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
| `SystemModstamp` | datetime | no | yes | [optional] |
|
|
|
|
### `GenAiPlannerAttrDefinition` (Tooling) — parameter mappings
|
|
|
|
The `attributeMappings` — I/O parameter bindings between actions and
|
|
the planner. **Polymorphic `ParentId`**: points at either a
|
|
`GenAiFunctionDefinition` (function-scope mappings) or
|
|
`GenAiPlannerDefinition` (bundle-scope mappings). The production SOQL
|
|
passes the union of function ids + planner id via
|
|
`WHERE ParentId IN (:function_ids, :planner_id)`.
|
|
|
|
`MappingType` is the `input` / `output` picklist; `ParameterName`
|
|
identifies the bound variable on the planner side.
|
|
|
|
| Name | Type | Nillable | Filterable | Tag |
|
|
|---|---|---|---|---|
|
|
| `Id` | id | no | yes | [mandatory] |
|
|
| `ParentId` | reference | yes | yes | [optional] — polymorphic: GenAiFunctionDefinition \| GenAiPlannerDefinition |
|
|
| `DeveloperName` | string | no | yes | [optional] |
|
|
| `MasterLabel` | string | yes | yes | [optional] |
|
|
| `Description` | textarea | yes | no | [optional] |
|
|
| `MappingType` | picklist | yes | yes | [optional] — `input` / `output` |
|
|
| `ParameterName` | string | yes | yes | [optional] |
|
|
| `Language` | picklist | yes | yes | [optional] |
|
|
| `NamespacePrefix` | string | yes | yes | [optional] |
|
|
| `ManageableState` | picklist | yes | yes | [optional] |
|
|
| `IsDeleted` | boolean | no | yes | [optional] |
|
|
| `CreatedById` | reference | no | yes | [optional] |
|
|
| `CreatedDate` | datetime | no | yes | [optional] |
|
|
| `LastModifiedById` | reference | no | yes | [optional] |
|
|
|
|
---
|
|
|
|
## Known picklist values (live-API verified, 2026-05-02)
|
|
|
|
| sObject | Field | Values |
|
|
|---|---|---|
|
|
| `GenAiPlannerDefinition` | `PlannerType` | Seven values split by namespace. Classic family: `AiCopilot__ReAct`, `AiCopilot__ReactAiPlannerV1`, `AiCopilot__SequentialPlannerIntentClassifier`. NGA family: `Atlas__ConcurrentMultiAgentOrchestration`, `Atlas__AnthropicCompatibleV1`, `Atlas__AtlasReactV1`, `Atlas__MainSubAgent` (exact set may vary by release — `startswith("Atlas__")` is the stable classic-vs-NGA discriminator). |
|
|
| `GenAiFunctionDefinition` | `InvocationTargetType` | `flow`, `apex`, `standardInvocableAction`, `generatePromptResponse` |
|
|
| `GenAiPlannerAttrDefinition` | `MappingType` | `input`, `output` |
|
|
| `BotVersion` | `Status` | `Inactive`, `Active` (active = currently published version) |
|
|
|
|
---
|
|
|
|
## Mandatory-field enforcement
|
|
|
|
The `[mandatory]` tags above mirror `scripts/probe_channels.py`:
|
|
|
|
```python
|
|
MANDATORY_FIELDS: Dict[str, set[str]] = {
|
|
"BotDefinition": {"Id", "DeveloperName"},
|
|
"BotVersion": {"Id", "BotDefinitionId"},
|
|
"ApexClass": {"Id", "Name"},
|
|
"Flow": {"Id", "MasterLabel", "DefinitionId"},
|
|
"FlowDefinition": {"Id", "DeveloperName"},
|
|
"GenAiPlannerDefinition": {"Id", "DeveloperName", "PlannerType"},
|
|
"GenAiPluginDefinition": {"Id", "DeveloperName"},
|
|
"GenAiFunctionDefinition": {"Id", "DeveloperName", "InvocationTarget"},
|
|
"GenAiPlannerAttrDefinition": {"Id"},
|
|
}
|
|
```
|
|
|
|
`GenAiPluginFunctionDef`, `GenAiPluginInstructionDef`, and
|
|
`GenAiPlannerFunctionDef` don't appear in `MANDATORY_FIELDS` — they're
|
|
join tables whose `Id` + FK columns are present by construction on
|
|
every query. The per-sObject tables above tag their FK columns as
|
|
`[mandatory]` because the SOQL assets SELECT them; a probe that saw
|
|
them missing would still flip `PROBE_FAILED` via the `Id` check, but
|
|
the tag reflects "the skill's SOQL will fail if this column is gone."
|
|
|
|
When a Salesforce quarterly release renames or removes a
|
|
`[mandatory]` field, run with `--reprobe` to force a fresh describe and
|
|
surface the drift cleanly.
|