ruvector/examples/python-salesforce-agentforce/README.md
rUv 87ca4dd52b
feat(ruvector-py): Python SDK, CLI and MCP server (ADR-352) (#1117)
Adds the ruvector Python package (crates/ruvector-py): Rust core via PyO3/maturin (RaBitQ and HNSW indexes, collections, graph, GNN, clustering, SONA), a CLI, a stdio and HTTP MCP server with bearer auth, and LangChain, LlamaIndex and Salesforce integrations.

Pre-publish hardening from an independent review: generic-CPU aarch64 wheel, request and size bounds, widget escaping, fail-closed network exposure and a read-only serve mode, MIT licence file, NaN and infinity rejection, click and rich as base dependencies, sdist job and tag-equals-version gate, atomic save and validated load, and HNSW metadata JSON converter fixes (exact large integers, no silent NaN or surrogate corruption).

Verified before merge: 272 pytest and 50 cargo tests, all six wheel and sdist build jobs, twine check on every artifact, clean-venv install of the CI wheel. The two failing checks (npm audit, Tests core-and-rest) also fail on main and are not changed by this PR.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01EwK8N12XfJiMbebRbWeoob
2026-10-09 16:23:02 -07:00

65 lines
3.9 KiB
Markdown

# RuVector + Salesforce Agentforce (example)
**Everything under this directory is illustrative, not validated against a real Salesforce
org or the current Salesforce Metadata API schema.** This session's task boundary was "mock
the Salesforce APIs, do not hit a real org" (ADR-352), so these metadata sketches were written
from Salesforce's public documentation on External Services and Named Credentials, not confirmed
by importing them into a live org's Setup UI or by a Metadata API `describe` call. Treat them as
a starting point — review and adjust in your own org (ideally in a scratch/sandbox org first)
before deploying anything here.
## What this demonstrates
`ruvector`'s Salesforce integration (`ruvector[salesforce]`, see
`docs/adr/ADR-352-ruvector-python-sdk-cli-mcp.md`'s "Integrations" section for the full writeup
of what was and wasn't verified) exposes three vector operations — search, upsert, and a
grounding-context join — as plain HTTP actions, fronted by a generated OpenAPI 3.0 document. The
extension point used is **External Services + OpenAPI**, confirmed to be the self-service,
no-special-access path (Data Cloud's retrieval surface doesn't accept an arbitrary external
vector store, and Agentforce's own MCP client is Beta/AE-tier-gated — neither was buildable or
verifiable in this session; see the ADR for the research that established this).
## Steps (sketch — verify each against your own org)
1. **Run the `ruvector` MCP server with Salesforce actions enabled:**
```bash
export RUVECTOR_SALESFORCE_ACTION_TOKEN="<a real secret, not this placeholder>"
export RUVECTOR_ENABLE_SALESFORCE_ACTIONS=1
ruvector serve --http --host 0.0.0.0 --port 8420
```
The OpenAPI document this External Service imports is served at
`http://<host>:8420/salesforce/openapi.json` (no auth required on that one GET — see
`ruvector.salesforce_routes` for why only the three action routes are bearer-gated).
2. **Create a Named Credential** pointing at that host — `namedCredentials/` has a sketch. The
action token goes in the Named Credential's auth configuration, not in any metadata file
committed here.
3. **Register an External Service** from the OpenAPI URL above —
`externalServiceRegistrations/` has a sketch of the registration metadata. Salesforce's UI
path (Setup → External Services → New External Service → "From API Specification") is the
reliable way to do this interactively; the metadata file is for tracking the result in source
control afterward, not for a blind deploy.
4. **Expose the resulting actions to an Agentforce agent** via Setup → Agentforce Studio, adding
the registered External Service's operations (`search`, `upsert`, `ground`) as agent actions.
This step is pure org configuration with no `ruvector`-specific metadata to track here.
## What's explicitly out of scope here
- **Agentforce MCP registration** — not built. Documented in the ADR as a beta/AE-tier-gated
option for a future session with real access to verify against, not something this example
pretends to demonstrate.
- **Data Cloud "bring your own retriever"** — not applicable; its grounding surface queries
Data Cloud's own indexed data, not an arbitrary external vector store over HTTP (see the ADR's
research findings).
- **`genAiFunctions/RuVector_Search.genAiFunction-meta.xml`** — included as a sketch per a later
design review, with its `invocationTargetType` field left as a literal, commented
`UNCONFIRMED_PLACEHOLDER` rather than a guessed value. Real research confirmed `flow` and
`slack` as two valid values for this field but could not confirm what an External-Service-backed
action resolves to or who/what sets it — which is exactly why step 4 above still says to
register through the UI rather than hand-authoring this file for a real deploy. See the file's
own header comment and ADR-352's Integrations section for the
sources checked.