Service twin · API only
Salesforce
Test revenue agents that manage leads, opportunities, accounts, and customer follow-up.
$ uv tool install blobfish-cli
$ blobfish twin login
$ blobfish twin-runs create --twins salesforce --ttl 60 --waitWhat’s inside
A deterministic, seeded, resettable replica: every operation below executes real state transitions against the twin’s own SQLite state — reads are hash-invariant, writes produce inspectable diffs, and reset restores the seed baseline.
Seeded entities
| Entity | Table | Fields | About |
|---|---|---|---|
| user | users | 7 | Salesforce user — the record owner referenced by owner_id across the CRM. |
| account | accounts | 16 | Account sobject — company record with billing address, firmographics, and a governed engagement lifecycle. |
| contact | contacts | 13 | Contact sobject — person on an account with a consent-aware lifecycle. |
| lead | leads | 16 | Lead sobject — unqualified prospect with the Salesforce default status picklist and conversion lifecycle. |
| opportunity | opportunities | 15 | Opportunity sobject — revenue deal carrying the full Salesforce default stage lifecycle from prospecting to closed_won/closed_lost. |
| opportunity_line_item | opportunity_line_items | 8 | OpportunityLineItem sobject — product line on an opportunity. |
| task | tasks | 11 | Task sobject — follow-up activity with the Salesforce default status picklist (not_started → completed). |
| event | events | 11 | Event sobject — calendar activity (calls, meetings, demos) logged against accounts and people. |
| case | cases | 11 | Case sobject — service request tied to the responsible account and contact (modeled on the Salesforce REST API; outside the Composio toolkit's surface). |
Guarded lifecycles
These state machines are enforced, not decorative: an action whose fromstate doesn’t match is rejected the way the production service rejects it.
account.status
approve: prospect → active
contact.status
verify: new → qualified
lead.status
convert: open_not_contacted|working_contacted → closed_converted
opportunity.stage
close_won: proposal_price_quote|negotiation_review → closed_wonclose_lost: prospecting|qualification|needs_analysis|value_proposition|id_decision_makers|perception_analysis|proposal_price_quote|negotiation_review → closed_lost
task.status
complete: not_started|in_progress|waiting|deferred → completed
case.status
escalate: working|waiting_customer → escalatedclose: new|working|waiting_customer|escalated → closed
Three surfaces, one state
Mount Salesforce in a twin environment and the same seeded state serves vendor-shaped REST operations, an MCP endpoint for tool calling, and a generated bf-twin CLI — with copy-on-write sessions per rollout and a one-call reset to the seed baseline. Prefer raw HTTP? The same create works with curl:
$ curl -sS -X POST https://blobfish.ai/api/v1/twin/environments \
-H "X-API-Key: $BLOBFISH_API_KEY" -H "Content-Type: application/json" \
-d '{"services":["salesforce"],"ttl_minutes":60}'Known limitations
- Composio tool vocabulary is remapped onto an authored coherent sObject model; this IR is not captured Salesforce REST or Hosted MCP JSON.
- Use the sealed Python Salesforce pack for v67 REST schemas and the separate SObject All surface for Hosted MCP tool names and documented inputs.