{"id":10590,"plugin_id":"plugin_asdk_app_6a5a6880b6dc8191897d607c3256652d","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T22:57:33.221Z","digest":"b4473882d61096fc27ccb5ed44b6c3a7b94541bdeb70265a69ba8b43c1cbff02","against":null,"payload":{"description":"Put one Salesforce field under AI maintenance with a clearskies workflow: after a relevant call, AI finds the right record, checks the transcript is actually useful, generates a value, and writes it to the field. Use when a RevOps user wants AI to automatically keep a specific SFDC field up to date from meeting content — e.g. \"have AI keep Opportunity Next Steps updated\", \"auto-fill our Onboarding Next Step field after calls\", \"update a chosen SFDC field automatically after customer meetings\", or when they pick a field for AI to own. Builds the call-ended → role filter → find record → relevance-agent → should-continue gate → generation-agent → updateSalesforce pattern, using two reusable field-agnostic agents with all field-specifics in the step messages. It proposes or drafts first and never publishes or edits a live workflow without explicit approval.","included_files":[{"relative_path":"references/generic-ai-update-pattern.md","size_in_bytes":11993}],"name":"ai-update-salesforce-field","skill_md_contents":"---\nname: ai-update-salesforce-field\ndescription: >-\n  Put one Salesforce field under AI maintenance with a clearskies workflow: after a\n  relevant call, AI finds the right record, checks the transcript is actually useful,\n  generates a value, and writes it to the field. Use when a RevOps user wants AI to\n  automatically keep a specific SFDC field up to date from meeting content — e.g.\n  \"have AI keep Opportunity Next Steps updated\", \"auto-fill our Onboarding Next Step\n  field after calls\", \"update a chosen SFDC field automatically after customer meetings\",\n  or\n  when they pick a field for AI to own. Builds the call-ended → role filter → find\n  record → relevance-agent → should-continue gate → generation-agent → updateSalesforce\n  pattern, using two reusable field-agnostic agents with all field-specifics in the step\n  messages. It proposes or drafts first and never publishes or edits a live workflow\n  without explicit approval.\n---\n\n# Auto-update a Salesforce field with AI\n\nThis skill helps RevOps put **one Salesforce field under AI maintenance**. After a\nqualifying call ends, the workflow finds the Salesforce record tied to the meeting's\naccount, scores whether the transcript is genuinely relevant to the target field,\ngenerates the field's new value if so, and writes it back to Salesforce.\n\nTwo AI steps do the work, and both are **reusable and field-agnostic**: a **relevance\nagent** and a **generation agent**. Their templates carry no field- or organization-specific\ncontent — everything specific to a field arrives in the step `userMessage`. So the same\ntwo agents serve every field you put under AI maintenance; only the messages change.\n\nIt is the field-specific recipe on top of the general clearskies mechanics — for node\nshapes, validation, and safe publishing, defer to the **clearskies-workflow-builder**\nskill and `workflow_capabilities_get`.\n\n## Load connected-data context\n\nSearch first with `schema_search` for the target field concept and record lookup\nrelationship. Use the ranked matches to select candidate objects and fields, then call\n`object_get_fields_schema` for the target and lookup objects before building filters or\nwrites. Disclose search warnings and never treat search as exhaustive proof. Use\n`object_definitions_list` only when a complete configured object list is required. Always use\n`object_get_fields_schema` to verify the complete target and lookup object schemas before\nbuilding the workflow.\n\n## Operating rule\n\nBuild from the reference pattern, but **never publish or modify a live workflow until\nthe user explicitly approves that side effect.** Default to a proposed config, or a\ndraft plus a dry run. A test run (`workflow_test_run_start`) is always safe — it never\nwrites to Salesforce — so **always dry-run a valid *and* an invalid case before\npublishing.** `workflow_validate` confirms shape and that references resolve, but it\ndoes not prove the workflow behaves correctly at runtime.\n\nRead [references/generic-ai-update-pattern.md](references/generic-ai-update-pattern.md)\nbefore generating a config, prompt, or draft — it holds both reusable agent templates\nand their `userMessage` templates.\n\n## What it builds\n\n```\ntrigger-1 (callEnded)\n → filter-1  role gate on meeting.attendees.UserRoleId\n → find-1    the target Salesforce record for {{meeting.accounts.Id}}\n → filter-2  require find-1.records to be non-empty\n → agent-1   reusable RELEVANCE agent (field-specifics in its userMessage)\n → filter-3  continue only if agent-1's output has should_continue: true\n → agent-2   reusable GENERATION agent (field-specifics in its userMessage)\n → updateSalesforce: write {{agent-2.output}} to the field on {{find-1.records.sfRecordId}}\n```\n\nEach line shows the node **id** (a `{{...}}` reference handle — it must stay in the\n`<type>-<n>` form, e.g. `agent-1`); the ids are numbered in flow order here. Set a\ndescriptive `data.label` on every node (e.g. *Evaluate relevance*, *Generate field\nupdate*, *Find target record*) — that's the human-readable name shown in the UI.\n\nThe order matters: **cheap deterministic filters run first** (role, record-exists, and\nany RevOps-chosen gates), **then** the relevance agent and its `should_continue` gate,\nand only then the generation agent and the write. Nothing is written unless the\ntranscript actually clears the relevance bar — this controls cost and prevents\nlow-quality or empty updates.\n\n`callEnded` requires a filter immediately after the trigger; the role gate (`filter-1`)\nsatisfies that requirement while also scoping the workflow to the right people.\n\n## Intake — what to confirm with RevOps\n\nAsk only for what's missing. If the user names a target field and gives enough context,\ninfer the obvious pieces and confirm them in the proposal rather than blocking.\n\n1. **Target field** — `sobjectType` (e.g. `Opportunity`, `Account`,\n   `Custom_Object__c`), the field API name, and the human-readable label.\n2. **Field semantics** — a definition; what belongs; what must *not* go in it; the\n   desired output format (concise note, bullets, plain text, JSON).\n3. **Record lookup** — how to find the record from the meeting (usually the target\n   object's account field `isIn {{meeting.accounts.Id}}`); any exclusions (status not\n   `Complete`, closed opportunities, inactive records, record type); the lookup `limit`\n   (default `1`, since the write targets a single record).\n4. **Deterministic filters before the AI steps** — the role gate is the baseline;\n   optionally require an external attendee, a minimum duration, an account segment, an\n   opportunity stage, a title pattern, an owner/role, or \"not a placeholder/hold\".\n5. **Relevance gate** — the score threshold (default `> 3`; raise it to be stricter).\n   Use the **reusable relevance agent**; put all field-specific details in its `agent-1`\n   `userMessage`, not in the agent template.\n6. **Agents & workflow handling** — reuse the existing reusable relevance/generation\n   agents or create them (their templates are field-agnostic); the workflow name;\n   whether to produce a proposed config, a validate-only check, or a created draft\n   (default to a proposed config / validate-only when unsure); and a real test meeting\n   id to dry-run against, if available.\n\n## Build procedure\n\n1. Confirm the desired output — a proposed config, a draft, or (with approval) a\n   published workflow. Default to a proposed config / draft.\n2. Gather the customizations above.\n3. Load the reference pattern and resolve the concrete ids it needs (`sobjectType`,\n   field API names, the account-lookup field, role ids/names, and the two agent ids) —\n   get role ids and the account-lookup field id from an existing workflow's config\n   (`workflows_list includeConfig:true`) or `object_get_fields_schema` rather than\n   hardcoding or guessing them.\n4. Assemble the graph in the order above. Reference the two **reusable** agents by id and\n   put everything field-specific in their `userMessage`s (field label, API name,\n   definition, what-belongs, exclusions, threshold for `agent-1`; plus output format and\n   optional domain context for `agent-2`). Keep the agent templates field-agnostic.\n5. Produce the **required fields** from the final config — at minimum:\n   `meeting.id`, `meeting.accounts.Id`, `meeting.attendees.UserRoleId`,\n   `find-1.records`, `find-1.records.sfRecordId`, `agent-1.output`, `agent-2.output` —\n   plus any field introduced by custom filters or lookup conditions.\n6. If the workflow MCP tools are available, use `workflow_capabilities_get` and\n   `workflow_variables_get` to confirm shapes/variables, `workflow_validate` to check\n   the graph, then `workflow_test_run_start` to dry-run. Only after approval use\n   `workflows_create`/`workflows_update`, and only after explicit publish approval use\n   `workflows_publish`.\n7. If tools are unavailable or the user only wants a plan, output the config summary and\n   the exact node/edge JSON for review.\n\n## The relevance gate\n\nRelevance is enforced in two nodes: the reusable **relevance agent** (`agent-1`) scores\nthe transcript 0–10 against the field's definition and returns JSON\n(`should_continue`, `score`, `reason`, `relevant_details_found`); then **`filter-3`**\ncontinues only when `should_continue` is true. Keep the threshold at `> 3` unless the\nuser wants stricter gating, and pass it — with the field definition — in the `agent-1`\n`userMessage`. The agent template and both `userMessage` templates are in the reference\nfile.\n\n## Review checklist\n\nBefore presenting the proposed workflow, confirm:\n\n- The update field belongs to the **same object** returned by `find-1`.\n- `updateSalesforce.field` uses `find-1.records.<Field_API_Name>` and `recordId` is\n  `{{find-1.records.sfRecordId}}`.\n- The reusable relevance and generation agent **templates contain no organization- or\n  field-specific details** — all of that lives in the `agent-1` / `agent-2`\n  `userMessage`s (field label, API name, definition, what-belongs, exclusions,\n  threshold, output format).\n- Each node has a descriptive `data.label` (e.g. *Evaluate relevance*, *Generate field\n  update*, *Find target record*); node **ids** stay in the `<type>-<n>` form because\n  `{{...}}` references depend on them.\n- `filter-3` gates on `agent-1`'s `should_continue`, and it sits between the two agents.\n- Deterministic filters appear **before** the relevance agent.\n- `find-1.limit` is `1` (the write is single-record); if RevOps needs to update several\n  records per call, wrap the update in a `loop` instead.\n- Structured filter `fieldId`s (the role gate and the account lookup) are real for this\n  organization — confirm them in a dry run; if `find-1` fails at runtime with `\"filter field\n  not found\"`, switch that condition to an `aiFindPrompt`.\n- Both a relevant meeting (proceeds and writes) and an irrelevant one (stops at\n  `filter-3`, writes nothing) have been dry-run before any publish.\n- Nothing is created or published without explicit user approval.\n\n## Reference & helper files\n\n- `references/generic-ai-update-pattern.md` — the node-by-node template: baseline graph,\n  baseline filters, both **reusable agent templates** (relevance + generation), both\n  agent `userMessage` templates, the `should_continue` filter, the `updateSalesforce`\n  node, the required fields list, and the proposal output shape. Read it before\n  generating anything.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}