Org Introspection. Two layers, one assistant.
FlowMason ships two introspection layers so the assistant knows about your org's automation, not just its schema. INV-1 reads on-demand at request time. INV-2 harvests nightly into a snapshot table the assistant searches via tool-calling.
INV-1. On-demand per-turn excerpt
FMOrgIntrospector.scopedExcerpt(objectApiNames) reads Tooling at request time and threads a per-turn org-context excerpt into the LLM prompt. Capped at orgChatManifestMaxKb (default 8 KB ≈ 2000 tokens).
What's in the excerpt
- Triggers per SObject + their active state
- Active flows referencing the SObject
- Validation rules + error messages (formulas optional)
- Dependency degree (how many components reference this one)
- Perm-set FLS labels for the SObject's fields
Enable
// INV-1 master switch (per-turn introspection)
FMConfig.set('orgChatManifestEnabled', 'true');
// Optional tuning
FMConfig.set('orgChatManifestMaxKb', '8'); // hard cap (default 8 KB)
FMConfig.set('orgChatManifestIncludeFormulas', 'false'); // formulas off by default Tooling auth
Primary: Named Credential callout:FMTooling bound to a Named Principal w/ View All Setup. Fallback: session-id (engages automatically when the NC is absent). Pure-Apex collectors. No external service.
The 6 collectors
FMObjectsCollector— describe + custom-object metadataFMApexCollector— Apex classes + triggers per SObjectFMFlowsCollector— activeFlowDefinitionViewrowsFMValidationRulesCollector— validation rules + active flagFMDependencyCollector—MetadataComponentDependencydegreeFMPermSetFlsCollector— perm-set FLS labels
INV-2. Nightly inventory harvest
FMOrgInventoryHarvester walks 5 component types in a single Queueable transaction (refactored from chained Queueables which hit the 5-deep dev-org cap). Stores results in FM_Org_Inventory_Snapshot__c. The assistant searches it via the inventory_search tool.
What it harvests
ApexClass— Tooling RESTApexTrigger— Tooling REST (capturesTableEnumOrId)FlowDefinitionView— standard SOQL underSYSTEM_MODE(NOT a Tooling sObject)ValidationRule— Tooling REST (capturesEntityDefinition.QualifiedApiName)PermissionSet— standard SOQL underSYSTEM_MODE
Schedule + first run
// Assign the operations permset to the service user
// (one-time): FlowMason_Org_Chat_Inventory_Admin
// Schedule nightly cron (default 0 0 2 * * ? *)
FMOrgInventoryScheduler.ensureScheduled();
// Force first harvest now (don't wait for the cron)
String jobId = FMOrgInventoryHarvester.enqueue();
System.debug('Harvest job: ' + jobId);
// Verify rows landed
System.debug([
SELECT Component_Type__c, COUNT(Id) c
FROM FM_Org_Inventory_Snapshot__c
GROUP BY Component_Type__c
]); Cron + single-flight
- Default cron:
0 0 2 * * ? *(02:00 UTC daily). Override viaFM_Config.orgChatInventoryCron. - Single-flight key on
local.FMLLMCache(invharvinflight, 900s TTL) prevents duplicate enqueue. - Per-run
Snapshot_Run_Id__ctags rows for the cleanupfinalize()step. - Telemetry:
FlowMasonRun__ewithAction__c = org_inventory_harvest_completed+ per-type row counts.
Common failure modes
F1. "sObject type 'FlowDefinitionView' is not supported"
Cause: someone reverted the routing. Tooling REST doesn't expose FlowDefinitionView or PermissionSet; both must go through standard Database.query under SYSTEM_MODE. Fix in harvestType.
F2. System.AsyncException: Maximum stack depth has been reached
Cause: chained-Queueable harvester re-introduced. Chain depth cap is 5 in dev orgs. Single execute() walks all types in one transaction.
F3. Schedulable blocks redeploy
Symptom: "Cannot delete this class because it is referenced elsewhere." Recovery:
// Recovery — abort cron, redeploy, reschedule
for (CronTrigger ct : [
SELECT Id FROM CronTrigger
WHERE CronJobDetail.Name = 'FM Org Inventory Nightly'
]) {
System.abortJob(ct.Id);
}
// sf project deploy start --target-org Flowmason \
// --source-dir force-app/main/default/classes/FMOrgInventoryHarvester.cls
FMOrgInventoryScheduler.ensureScheduled(); F4. Inventory stale / partial run
Force a fresh harvest: FMOrgInventoryHarvester.enqueue();. Single-flight cache prevents duplicate enqueue.
F5. Single-flight cache wedge
Symptom: enqueue() returns same job id repeatedly. Evict manually:
Cache.OrgPartition p = Cache.Org.getPartition('local.FMLLMCache');
p.remove('invharvinflight'); Disable
No MDT switch — disablement is operational. Abort the cron:
for (CronTrigger ct : [
SELECT Id FROM CronTrigger
WHERE CronJobDetail.Name = 'FM Org Inventory Nightly'
]) {
System.abortJob(ct.Id);
} The inventory_search tool degrades to "inventory not yet harvested" when the table is empty.
Related
- Org Chat — the primary consumer
- Tool-calling — how
inventory_search+lookup_metadataget exposed to the model