Skip to main content

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 or internal APIs with domain-specific requirements.
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
Example use cases:
  • 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: allowed_tools semantics for /agent/query:
  • Omit/null → role presets may enable tools
  • [] → tools disabled
  • ["name", …] → only these tools are available (names must match registered tools)
Register in 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: revenuetotal_revenue
  • Metric prefixing: usersmy: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 pass allowed_tools, only the listed tools will be available to the LLM. Pass an empty list [] to disable tools.

Best Practices

✅ Good: Transform field names, inject defaults
❌ Bad: Business logic in adapter
✅ Good:
❌ Bad:

Testing & Verification

Unit Test Adapter

Integration Test

Troubleshooting

Symptom: Logs show “Vendor adapter ” applied” (empty string)Fix:
Symptom: ImportError: No module named 'myvendor'Fix:
Symptom: API receives original body, not transformedDebug:
Check:
  1. Adapter registered in __init__.py
  2. Vendor name matches in config
  3. auth_config.vendor field present
  4. Adapter returns modified dict (not None)
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
Three components:
  1. Vendor Adapter - Request/response transformations
  2. Config Overlay - Tool configurations
  3. Vendor Role - Specialized agent (optional)
Quick reference:

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