# How to Integrate Neuro-SAN Studio with External Agent Frameworks: Agentforce, Agentspace, CrewAI, and A2A

> Integrate Neuro-SAN Studio with Agentforce, Agentspace, CrewAI, and A2A using Coded-Tool architecture. Seamlessly wrap external services into your agent networks for enhanced functionality. Learn how today.

- Repository: [Cognizant AI Lab/neuro-san-studio](https://github.com/cognizant-ai-lab/neuro-san-studio)
- Tags: how-to-guide
- Published: 2026-02-27

---

**Neuro-SAN Studio integrates with external agent frameworks like Agentforce, Agentspace, CrewAI, and A2A through a unified Coded-Tool architecture that wraps external services as invocable tools within agent networks.**

The **cognizant-ai-lab/neuro-san-studio** repository provides a pluggable integration layer that lets you embed Salesforce Agentforce sessions, Google Cloud Agentspace searches, and CrewAI research pipelines directly into Neuro-SAN agent networks. By implementing the `CodedTool` interface, each external framework becomes a reusable component that can be invoked locally, exposed via the A2A (AI-to-AI) protocol, or chained with other agents.

## Understanding the Coded-Tool Architecture

All external framework integrations in Neuro-SAN Studio rely on the `CodedTool` abstract base class defined in `neuro_san.interfaces.coded_tool`. This interface requires implementing the `invoke` method:

```python
def invoke(self, args: Dict[str, Any], sly_data: Dict[str, Any]) -> Union[Dict, str]

```

The **sly_data** dictionary serves as a private bulletin board that persists across agent invocations. Framework-specific tools store session identifiers, OAuth tokens, and conversation context here, ensuring that subsequent calls maintain continuity with external services.

## Integrating with Salesforce Agentforce

The Agentforce integration wraps Salesforce's conversational AI API as a CodedTool, managing OAuth authentication and session persistence automatically.

### Configuration and Authentication

The `AgentforceAdapter` class in [`coded_tools/tools/agentforce/agentforce_adapter.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/coded_tools/tools/agentforce/agentforce_adapter.py) reads four environment variables:

- `AGENTFORCE_MY_DOMAIN_URL`
- `AGENTFORCE_AGENT_ID`
- `AGENTFORCE_CLIENT_ID`
- `AGENTFORCE_CLIENT_SECRET`

If any variable is missing, the adapter enters **mock mode**, returning static responses defined in [`agentforce_api.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/agentforce_api.py) (lines 29-46). This allows local testing and CI pipelines without live Salesforce credentials.

### Session Management and Invocation

When `AgentforceAPI.invoke` is called, it checks `sly_data` for an existing `session_id`. If absent, it calls `AgentforceAdapter.create_session()` to obtain an OAuth token and initialize a new Salesforce session. Subsequent invocations reuse this session via `post_message`.

```python
from coded_tools.tools.agentforce.agentforce_api import AgentforceAPI

# Initialize the tool

agentforce = AgentforceAPI()
sly_data = {}

# First call creates session

response = agentforce.invoke(
    {"inquiry": "List Jane Doe's recent cases"},
    sly_data
)

# Follow-up uses same session

response2 = agentforce.invoke(
    {"inquiry": "jdoe@example.com"},
    sly_data
)

```

## Integrating with Google Cloud Agentspace

The Agentspace integration enables semantic search against Google Cloud Discovery Engine through the `AgentSpaceSearch` CodedTool.

### Environment Setup

The tool requires three environment variables defined in [`coded_tools/tools/agentspace_adapter/agentspace_adapter.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/coded_tools/tools/agentspace_adapter/agentspace_adapter.py):

- `GCP_PROJECT_ID`
- `GCP_LOCATION`
- `ENGINE_ID`

### Performing Searches

The `invoke` method accepts a `search_query` argument and returns a `SearchPager` containing Discovery Engine results:

```python
from coded_tools.tools.agentspace_adapter.agentspace_adapter import AgentSpaceSearch

search_tool = AgentSpaceSearch()

# Execute search

pager = search_tool.invoke(
    {"search_query": "latest advances in quantum computing"},
    {}
)

# Extract snippets

snippets = [result.document.snippet for result in pager]

```

## Integrating with CrewAI and A2A Protocol

Neuro-SAN Studio exposes CrewAI agents through the A2A (AI-to-AI) protocol, allowing external services to invoke complex multi-agent workflows via HTTP.

### CrewAI Research Report Implementation

The `CrewAiResearchReport` class in [`servers/a2a/agent.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/servers/a2a/agent.py) orchestrates two CrewAI agents: a researcher and a reporting analyst. When `ainvoke(topic)` is called, it runs the crew asynchronously and returns a markdown report.

```python
from servers.a2a.agent import CrewAiResearchReport

# Initialize research agent

research_agent = CrewAiResearchReport()

# Run async research

report = await research_agent.ainvoke("artificial intelligence trends")

```

### A2A Server Configuration

The A2A server in [`servers/a2a/server.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/servers/a2a/server.py) performs three critical functions:

1. **Defines an `AgentSkill`** describing the capability (e.g., "Research_Report")
2. **Creates an `AgentCard`** advertising the skill, endpoint URL, and version
3. **Wires a `CrewAiAgentExecutor`** to handle incoming requests

The `CrewAiAgentExecutor` class in [`servers/a2a/agent_executor.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/servers/a2a/agent_executor.py) bridges the A2A protocol to CrewAI by implementing the `execute` method, which extracts the topic from the request and calls `CrewAiResearchReport.ainvoke`.

### Starting and Testing the A2A Server

Start the server:

```bash
python servers/a2a/server.py --host 0.0.0.0 --port 9999

```

Verify the AgentCard is accessible:

```bash
curl http://localhost:9999/

```

Invoke the research skill:

```bash
curl -X POST http://localhost:9999/ \
  -H "Content-Type: application/json" \
  -d '{"input": {"text": "machine learning"}, "metadata": {}}'

```

## Registry Configuration for Neuro-SAN Networks

To use external framework tools within a Neuro-SAN agent network, register them in the HOCON configuration files located in `registries/tools/`.

For Agentforce, ensure `registries/tools/agentforce.hocon` contains:

```hocon
tools {
  agentforce {
    class = "agentforce_api.AgentforceAPI"
  }
}

```

Neuro-SAN automatically loads these definitions when initializing the agent network, making the tools available for invocation by other agents in the system.

## Summary

- **Coded-Tool Interface**: All external integrations implement `CodedTool` with `invoke(args, sly_data)`, using `sly_data` to persist session state across calls.

- **Agentforce Integration**: Configure via environment variables (`AGENTFORCE_*`); the `AgentforceAPI` class handles OAuth, session creation, and message posting automatically.

- **Agentspace Integration**: Set `GCP_PROJECT_ID`, `GCP_LOCATION`, and `ENGINE_ID`; use `AgentSpaceSearch` to query Google Cloud Discovery Engine.

- **CrewAI and A2A**: Wrap CrewAI agents with `CrewAiAgentExecutor`, expose via the A2A server in [`servers/a2a/server.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/servers/a2a/server.py), and invoke via HTTP POST requests following the A2A protocol.

- **Configuration**: Register tools in HOCON files under `registries/tools/` and store secrets in `.env` files excluded from version control.

## Frequently Asked Questions

### How does Neuro-SAN Studio maintain session state with external agents like Agentforce?

Neuro-SAN uses the `sly_data` dictionary, a private bulletin board passed to every `CodedTool.invoke()` call. The `AgentforceAPI` stores the Salesforce `session_id` and OAuth tokens in `sly_data`, ensuring subsequent invocations reuse the same conversation context without requiring re-authentication.

### Can I test the Agentforce integration without live Salesforce credentials?

Yes. If the required environment variables (`AGENTFORCE_MY_DOMAIN_URL`, `AGENTFORCE_AGENT_ID`, `AGENTFORCE_CLIENT_ID`, `AGENTFORCE_CLIENT_SECRET`) are missing, the `AgentforceAdapter` enters mock mode. The tool returns static responses defined in [`agentforce_api.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/agentforce_api.py), allowing local development and CI testing without API access.

### What is the difference between using a CodedTool directly and exposing it via A2A?

Using a `CodedTool` directly involves instantiating the class (e.g., `AgentforceAPI()`) and calling `invoke()` within a Neuro-SAN agent network. Exposing via A2A involves running [`servers/a2a/server.py`](https://github.com/cognizant-ai-lab/neuro-san-studio/blob/main/servers/a2a/server.py), which wraps the tool (or a CrewAI agent) in an HTTP endpoint following the AI-to-AI protocol. A2A enables external services to invoke your agents via standard HTTP POST requests, while direct CodedTool usage is internal to Neuro-SAN networks.

### How do I configure the Agentspace search tool for Google Cloud?

Set three environment variables in your `.env` file: `GCP_PROJECT_ID` for your Google Cloud project, `GCP_LOCATION` (typically "global"), and `ENGINE_ID` for your Discovery Engine identifier. The `AgentSpaceSearch` class reads these values in its constructor and uses them to initialize the `SearchServiceClient` when `invoke()` is called.