Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.shannon.run/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Shannon uses feature flags to control optional features, experimental functionality, and enterprise extensions without modifying code. This allows clean separation between:
  • Open-source core features (available to all)
  • Enterprise/private features (gated behind flags)
  • Experimental features (toggleable for testing)

Zero Recompilation

Enable/disable features without rebuilding services

Environment-Based

Different flags for dev/staging/production

Clean Separation

Enterprise features isolated from OSS core

Gradual Rollout

Test new features before full deployment

Configuration

Configuration File

Feature flags are defined in config/shannon.yaml under the features section:
# config/shannon.yaml
features:
  # Enterprise workflow features
  ads_research: false              # Ads research workflow (enterprise)
  advanced_synthesis: false        # Advanced synthesis templates

  # Experimental features
  parallel_streaming: true         # Multi-agent parallel streaming
  enhanced_memory: false           # Enhanced vector memory

  # Custom integrations
  vendor_tools_enabled: false      # Enable vendor-specific tools

Environment Variables

Feature flags can be overridden via environment variables:
# .env
SHANNON_FEATURE_ADS_RESEARCH=true
SHANNON_FEATURE_PARALLEL_STREAMING=false
Naming convention: SHANNON_FEATURE_<FLAG_NAME_UPPERCASE>

Priority Order

  1. Environment variables (highest priority)
  2. Config overlays (config/overlays/shannon.{env}.yaml)
  3. Base config (config/shannon.yaml)
  4. Code defaults (lowest priority)

Usage Patterns

In Go Code (Orchestrator)

package main

import (
    "github.com/Kocoro-lab/Shannon/go/orchestrator/internal/config"
)

func routeWorkflow(ctx context.Context, req *pb.Request) error {
    cfg, _ := config.LoadShannon()

    // Check feature flag
    if cfg.Features.AdsResearch {
        return routeToAdsResearchWorkflow(ctx, req)
    }

    return routeToStandardWorkflow(ctx, req)
}

In Python Code (LLM Service)

from llm_service.config import load_shannon_config

config = load_shannon_config()

# Check feature flag
if config.get("features", {}).get("vendor_tools_enabled"):
    from llm_service.tools.vendor import register_vendor_tools
    register_vendor_tools()

Conditional Imports Pattern

Use feature flags with conditional imports for clean separation:
# roles/presets.py
_PRESETS = {
    "general": GENERAL_PRESET,
    "research": RESEARCH_PRESET,
}

# Conditionally load enterprise roles
if config.get("features", {}).get("ads_research"):
    try:
        from .enterprise.ads_analyst import ADS_ANALYST_PRESET
        _PRESETS["ads_analyst"] = ADS_ANALYST_PRESET
    except ImportError:
        pass  # Shannon works without enterprise module

Common Feature Flags

Flag NameTypeDescriptionDefault
ads_researchEnterpriseAds research workflow with market analysisfalse
parallel_streamingExperimentalMulti-agent parallel SSE streamingtrue
advanced_synthesisEnterpriseCustom synthesis templatesfalse
vendor_tools_enabledIntegrationEnable vendor-specific tool adaptersfalse
enhanced_memoryExperimentalAdvanced vector memory with hybrid searchfalse

Best Practices

1. Default to Disabled

New features should default to false in base config:
# config/shannon.yaml
features:
  new_feature: false  # ✅ Safe default

2. Use Environment Overlays

Create environment-specific overlays for different deployments:
# config/overlays/shannon.production.yaml
features:
  ads_research: true
  parallel_streaming: true
  enhanced_memory: false  # Still testing
Load with:
SHANNON_CONFIG_PATH=config/overlays/shannon.production.yaml

3. Guard with Try/Except

Always use graceful fallback for enterprise/optional features:
if config.features.vendor_tools_enabled:
    try:
        from .vendor import CustomVendorTool
    except ImportError:
        logger.warning("Vendor tools not available, using standard tools")

4. Document Feature Requirements

features:
  # Requires: GA4_SERVICE_ACCOUNT_KEY environment variable
  # Vendor module: llm_service/tools/vendor_adapters/ga4/
  ga4_integration: false

Enterprise Feature Pattern

Shannon separates OSS core from enterprise extensions using feature flags:

File Structure

Shannon/
├── config/
│   ├── shannon.yaml                    # Base config (OSS)
│   └── overlays/
│       └── shannon.enterprise.yaml     # Enterprise flags
├── go/orchestrator/
│   └── internal/workflows/
│       ├── standard_workflow.go        # OSS workflow
│       └── enterprise/                 # Enterprise workflows
│           └── ads_research.go         # Gated by flag
└── python/llm-service/
    └── llm_service/
        ├── roles/
        │   ├── presets.py              # OSS roles + conditional load
        │   └── enterprise/             # Enterprise roles
        │       └── ads_analyst.py      # Gated by flag
        └── tools/
            └── vendor_adapters/        # Vendor tools (gated)

Conditional Workflow Routing

// orchestrator/internal/workflows/router.go
func SelectWorkflow(ctx context.Context, cfg *config.Shannon, req *pb.Request) Workflow {
    // Check for enterprise feature flag
    if cfg.Features.AdsResearch && req.Context["workflow_type"] == "ads_research" {
        return NewAdsResearchWorkflow()
    }

    // Fall back to OSS workflow
    return NewStandardWorkflow()
}

Testing with Feature Flags

Unit Tests

func TestAdsResearchWorkflow(t *testing.T) {
    cfg := &config.Shannon{
        Features: config.FeatureFlagsConfig{
            AdsResearch: true,  // Enable for test
        },
    }

    workflow := SelectWorkflow(context.Background(), cfg, testReq)
    assert.IsType(t, &AdsResearchWorkflow{}, workflow)
}

Integration Tests

# Run tests with feature enabled
SHANNON_FEATURE_ADS_RESEARCH=true go test ./...

# Run tests with feature disabled (OSS mode)
SHANNON_FEATURE_ADS_RESEARCH=false go test ./...

Deployment Strategies

Canary Deployment

Enable features for subset of users:
func isFeatureEnabled(userID string, featureName string) bool {
    // Check user-specific feature flags (e.g., from database)
    if userHasAccess(userID, featureName) {
        return true
    }

    // Fall back to global config
    return cfg.Features.Get(featureName)
}

A/B Testing

Route traffic based on feature flags:
if experimentGroup(userID) == "variant_a" && cfg.Features.EnhancedMemory {
    return useEnhancedMemory(ctx, req)
}
return useStandardMemory(ctx, req)

Monitoring & Observability

Log feature flag usage for debugging:
logger.Info("Feature flag check",
    zap.String("feature", "ads_research"),
    zap.Bool("enabled", cfg.Features.AdsResearch),
    zap.String("user_id", userID),
)
Add metrics:
featureFlagGauge.WithLabelValues("ads_research").Set(
    boolToFloat64(cfg.Features.AdsResearch),
)

Migration Guide

Adding a New Feature Flag

1

Define Flag in Config

Add to config/shannon.yaml:
features:
  my_new_feature: false  # Default disabled
2

Update Go Struct

Add field to go/orchestrator/internal/config/shannon.go:
type FeatureFlagsConfig struct {
    // ... existing flags
    MyNewFeature bool `json:"my_new_feature" yaml:"my_new_feature"`
}
3

Use in Code

Gate functionality:
if cfg.Features.MyNewFeature {
    return newFeatureBehavior()
}
return existingBehavior()
4

Add Tests

Test both enabled/disabled states:
func TestMyNewFeature_Enabled(t *testing.T) { /* ... */ }
func TestMyNewFeature_Disabled(t *testing.T) { /* ... */ }
5

Document

Update this page and environment variables documentation.

Environment Variables

Full list of configuration options

Vendor Adapters

Build vendor-specific integrations

Configuration Guide

Shannon configuration overview

Extending Shannon

Add custom features and workflows