Overview
The vendor adapter pattern allows you to integrate domain-specific agents and tools into Shannon without polluting the core codebase. This pattern maintains clean separation between:- Generic Shannon infrastructure (committed to open source)
- Vendor-specific implementations (kept private or in separate repositories)
Zero Core Changes
No modifications to Shannon’s core codebase required
Clean Separation
Generic infrastructure vs. vendor-specific logic
Easy Maintenance
Vendor logic isolated in separate directories
Graceful Fallback
Shannon works even without vendor modules
When to Use Vendor Adapters
Use vendor adapters when:- Integrating proprietary/internal APIs with domain-specific requirements
- Need custom request/response transformations for OpenAPI tools
- Building specialized agents for specific business domains
- Field naming conventions differ from your internal systems
- Require dynamic parameter injection from session context
- Need custom authentication or header logic
- Analytics platforms (metrics aliasing, time range normalization)
- E-commerce systems (product field mapping, SKU transformations)
- CRM integrations (contact field normalization)
- Internal microservices (custom auth tokens, tenant IDs)
- Domain-specific data validation
Architecture
File Structure
Component Responsibilities
Quick Start Example
Let’s create a complete vendor integration for a fictional analytics platform called “DataInsight”.1
Create Vendor Adapter
Create
python/llm-service/llm_service/tools/vendor_adapters/datainsight.py:2
Register Adapter
Edit
python/llm-service/llm_service/tools/vendor_adapters/__init__.py:3
Create Config Overlay
Create
config/overlays/shannon.datainsight.yaml:4
Create Vendor Role (Optional)
Create
python/llm-service/llm_service/roles/datainsight/analytics_agent.py:Note:Register inallowed_toolssemantics for/agent/query:
- Omit/
null→ role presets may enable tools[]→ tools disabled["name", …]→ only these tools are available (names must match registered tools)
python/llm-service/llm_service/roles/presets.py:5
Add Environment Variables
Add to
.env:6
Test Integration
Rebuild and test:
Component Guide
1. Vendor Adapter Class
Purpose: Transform requests/responses for vendor-specific API conventions Common transformation patterns:- Field aliasing:
revenue→total_revenue - Metric prefixing:
users→my:users - Time range normalization:
{start, end}→{startTime, endTime} - Sort format conversion:
{field, order}→{column, direction} - Filter structure reshaping: list → object with logic operators
- Default injection: Add missing required fields from session context
2. Config Overlay
Purpose: Define vendor-specific tool configurations without modifying base config Header values:"${ENV_VAR}"- Resolved from environment variables- Static strings - Used as-is
Dynamic header templating from the request body (e.g.,
{{body.field}}) is not supported. If headers must depend on body/session values, either:- Define those headers as explicit header parameters in the OpenAPI spec and pass them as tool parameters, or
- Use a vendor adapter to shape the request body, while headers remain static/env-driven.
3. Vendor Role
Purpose: Specialized agent with domain-specific knowledge and tool restrictions Template:Note: When you explicitly passallowed_tools, only the listed tools will be available to the LLM. Pass an empty list[]to disable tools.
Best Practices
Keep Adapters Generic
Keep Adapters Generic
✅ Good: Transform field names, inject defaults❌ Bad: Business logic in adapter
Use Graceful Fallback
Use Graceful Fallback
Document Transformations
Document Transformations
Keep Secrets in Environment
Keep Secrets in Environment
✅ Good:❌ Bad:
Test in Isolation
Test in Isolation
Validate Before Transforming
Validate Before Transforming
Testing & Verification
Unit Test Adapter
Integration Test
Troubleshooting
Adapter Not Loading
Adapter Not Loading
Symptom: Logs show “Vendor adapter ” applied” (empty string)Fix:
Imports Failing
Imports Failing
Symptom:
ImportError: No module named 'myvendor'Fix:Transformations Not Applied
Transformations Not Applied
Symptom: API receives original body, not transformedDebug:Check:
- Adapter registered in
__init__.py - Vendor name matches in config
auth_config.vendorfield present- Adapter returns modified dict (not None)
Session Params Not Injected
Session Params Not Injected
Symptom:
prompt_params is None in adapterCause: Orchestrator not sending session contextFix: Ensure context sent in gRPC request:Summary
Vendor Adapter Benefits
- ✅ Clean separation: generic code vs. vendor-specific
- ✅ No Shannon core changes required
- ✅ Conditional loading with graceful fallback
- ✅ Environment-based secrets management
- ✅ Testable in isolation
- ✅ Easy to maintain and extend
- Vendor Adapter - Request/response transformations
- Config Overlay - Tool configurations
- Vendor Role - Specialized agent (optional)
Next Steps
Custom Tools
Learn how to add custom tools
Extending Shannon
Explore other extension methods
Configuration
Complete configuration reference
Architecture
Understand Shannon’s architecture