Skip to content

feat(DATAGO-126647): Migrate existing feature flags to OpenFeature SDK#1178

Closed
bwiebe-solace wants to merge 17 commits intomainfrom
bwiebe/DATAGO-126647/flag-migration
Closed

feat(DATAGO-126647): Migrate existing feature flags to OpenFeature SDK#1178
bwiebe-solace wants to merge 17 commits intomainfrom
bwiebe/DATAGO-126647/flag-migration

Conversation

@bwiebe-solace
Copy link
Contributor

@bwiebe-solace bwiebe-solace commented Mar 13, 2026

What is the purpose of this change?

Migrates all existing feature flag checks from the legacy ConfigContext / component.get_config() pattern to the OpenFeature SDK. This is the final step of the feature flags initiative (after the core framework in #1122, the admin API in #1123, and the frontend provider in #1129), moving every flag consumer to the unified evaluation chain.

Related PRs (environment configuration updates)

How was this change implemented?

Backend (routers/, services/, dependencies.py):

  • Replaced manual component.get_config("feature_name", {}).get("enabled", False) lookups with component.feature_checker.is_enabled("key") calls across config.py, projects.py, tasks.py, and session_service.py
  • Added two reusable FastAPI dependency factories in dependencies.py: require_feature(key) (hard-gates an endpoint with HTTP 404) and get_feature_value(key) (injects boolean value without raising)
  • Replaced the bespoke check_project_indexing_enabled dependency in projects.py with get_feature_value("project_indexing")

Frontend (components/, hooks/, providers/):

  • Replaced configFeatureEnablement.mentions, autoTitleGenerationEnabled, projectIndexing, and projectSharingEnabled reads from ConfigContext with useBooleanFlagValue() calls from @openfeature/react-sdk
  • Removed autoTitleGenerationEnabled from ConfigContext and ConfigProvider (no longer derived from /api/v1/config)
  • Updated MockConfigProvider to initialise an OpenFeatureProvider backed by SamFeatureProvider so that Storybook tests using useBooleanFlagValue() resolve correctly

Flag definitions (features.yaml):

  • Registered mentions, auto_title_generation, project_sharing, and project_indexing with their release phase, JIRA epic, and description
  • Replaced the placeholder background_tasks example flag

Tests:

  • Updated integration tests to assert against the newly registered flags instead of the old placeholder
  • Updated Storybook test data to use snake_case flag keys matching the YAML definitions

How was this change tested?

  • Unit tests: test_feature_dependencies.py — 4 tests covering require_feature (returns 404 when disabled, passes when enabled) and get_feature_value (returns correct boolean)
  • Unit tests: test_config_auto_title.py — 3 tests updated to mock feature_checker.is_enabled instead of old get_config pattern
  • Integration tests: Updated test_feature_flags_router.py assertions to validate the newly registered flags (mentions, etc.) instead of the old background_tasks placeholder
  • Storybook tests: Updated MockConfigProvider to wire SamFeatureProvider into OpenFeatureProvider so component tests resolve flags correctly
  • Manual testing: Verify each flag resolves correctly via GET /api/v1/config/features; verify frontend toggles work for mentions, auto-title, project sharing, and project indexing; verify SAM_FEATURE_<KEY> env var overrides take effect

Is there anything the reviewers should focus on/be aware of?

  • The mentions flag on the frontend additionally gates on identityServiceType !== null (same prerequisite as the backend), while the backend gates on component.identity_service is None. This preserves the existing behaviour where mentions require an identity service.
  • The auto_title_generation flag on the frontend additionally gates on persistenceEnabled — again preserving existing behaviour.
  • The old background_tasks placeholder flag in features.yaml has been replaced. Background tasks are currently GA and not gated by a feature flag in practice.
  • Flag key casing changed from camelCase (projectIndexing, projectSharingEnabled) to snake_case (project_indexing, project_sharing) to match the YAML definitions — Storybook test data updated accordingly.
  • Environment configuration PRs for each deployment repo are linked above and should be merged after this PR.

Generated by Claude Code

bwiebe-solace and others added 7 commits March 13, 2026 13:59
log.exception already captures the active exception; passing e as a
format arg duplicates information in the log output.

FeatureFlagResponse has no field aliases so populate_by_name has no
effect. Remove it along with the now-unused ConfigDict import.
Replace demo background_tasks entry in features.yaml with the four
release toggle flags being migrated: mentions, auto_title_generation,
project_sharing, and project_indexing.

Update MockConfigProvider to wrap with OpenFeatureProvider so that
components using useBooleanFlagValue() resolve correctly in tests
and Storybook stories.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace configFeatureEnablement?.mentions with
useBooleanFlagValue("mentions", false) in MessageHoverButtons
and ChatInputArea.

On the backend, rewrite _determine_mentions_enabled in config.py to
evaluate via feature_checker.is_enabled("mentions") instead of reading
mentions.enabled / frontend_feature_enablement from YAML config.

Operators now control this flag via SAM_FEATURE_MENTIONS=true
instead of frontend_feature_enablement.mentions or mentions.enabled
in YAML config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace autoTitleGenerationEnabled from ConfigContext with
useBooleanFlagValue("auto_title_generation", false) in ChatProvider,
ChatPage, and SessionList. Remove the property from ConfigContext
and ConfigProvider.

On the backend, rewrite _determine_auto_title_generation_enabled in
config.py to evaluate via feature_checker.is_enabled("auto_title_generation")
instead of reading auto_title_generation.enabled / frontend_feature_enablement
from YAML config. Persistence check is preserved as a technical prerequisite.

Operators now control this flag via SAM_FEATURE_AUTO_TITLE_GENERATION=true
instead of frontend_feature_enablement.auto_title_generation or
auto_title_generation.enabled in YAML config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace configFeatureEnablement?.projectSharingEnabled with
useBooleanFlagValue("project_sharing", false) in
useIsProjectSharingEnabled hook. Update story test presets to
use the new snake_case flag key.

Community defaults to false; enterprise features.yaml overrides
to true. Operators control via SAM_FEATURE_PROJECT_SHARING.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace configFeatureEnablement?.projectIndexing with
useBooleanFlagValue("project_indexing", false) in
useIsProjectIndexingEnabled hook. Update ChatSidePanel tests
to use the new snake_case flag key.

On the backend, add require_feature() and get_feature_value()
FastAPI dependency factories to dependencies.py. Replace the
check_project_indexing_enabled function in projects.py with
get_feature_value("project_indexing"). Update tasks.py and
session_service.py to use feature_checker.is_enabled() instead
of get_config("project_indexing").

Operators now control this flag via SAM_FEATURE_PROJECT_INDEXING
instead of frontend_feature_enablement.projectIndexing in YAML.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The integration tests were pinned to the background_tasks example flag
which was replaced by the 4 release toggle flags (mentions,
auto_title_generation, project_sharing, project_indexing).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 13, 2026

✅ FOSSA Guard: Licensing (SolaceLabs_solace-agent-mesh) • PASSED

Compared against main (7372821dd6962c243ec1cf93ee57a986a48e982d) • 0 new, 7 total (7 in base)

Scan Report | View Details in FOSSA

@github-actions
Copy link

github-actions bot commented Mar 13, 2026

✅ FOSSA Guard: Vulnerability (SolaceLabs_solace-agent-mesh) • PASSED

Compared against main (7372821dd6962c243ec1cf93ee57a986a48e982d) • 0 new, 0 total (0 in base)

Scan Report | View Details in FOSSA

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates legacy feature-flag reads (backend config lookups + frontend ConfigContext booleans) to the OpenFeature evaluation path, and replaces the community features.yaml placeholder with real flag definitions.

Changes:

  • Backend: replace get_config(...).get("enabled") flag checks with component.feature_checker.is_enabled(...), and add reusable FastAPI dependencies for gating/injecting flags.
  • Frontend: switch feature consumers to useBooleanFlagValue() (snake_case keys), remove autoTitleGenerationEnabled from ConfigContext, and update Storybook mocks/tests to initialize OpenFeature.
  • Registry/tests: replace background_tasks placeholder with real flags in features.yaml, and update integration tests to assert against mentions.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/integration/apis/test_feature_flags_router.py Updates integration assertions to validate mentions flag behavior and env overrides.
src/solace_agent_mesh/gateway/http_sse/services/session_service.py Uses OpenFeature-backed checker for project_indexing instead of config dict parsing.
src/solace_agent_mesh/gateway/http_sse/routers/tasks.py Uses OpenFeature-backed checker for project_indexing in task context injection and submission logic.
src/solace_agent_mesh/gateway/http_sse/routers/projects.py Replaces bespoke indexing dependency with get_feature_value("project_indexing").
src/solace_agent_mesh/gateway/http_sse/routers/feature_flags.py Minor logging change in error path.
src/solace_agent_mesh/gateway/http_sse/routers/config.py Migrates mentions/auto-title enablement to OpenFeature checks while preserving prerequisites.
src/solace_agent_mesh/gateway/http_sse/dependencies.py Adds require_feature() and get_feature_value() dependency factories.
src/solace_agent_mesh/common/features/features.yaml Replaces placeholder flag with registered community flags (mentions, auto title, project sharing/indexing).
client/webui/frontend/src/stories/mocks/MockConfigProvider.tsx Initializes OpenFeature provider for Storybook/test rendering.
client/webui/frontend/src/stories/data/parameters.ts Updates Storybook test data to snake_case flag keys.
client/webui/frontend/src/stories/chat/ChatSidePanel.test.tsx Updates test fixtures to snake_case project_indexing key.
client/webui/frontend/src/lib/providers/ConfigProvider.tsx Stops deriving autoTitleGenerationEnabled from /config; OpenFeature is initialized from /config/features.
client/webui/frontend/src/lib/providers/ChatProvider.tsx Computes auto-title enablement via useBooleanFlagValue("auto_title_generation") + persistence prerequisite.
client/webui/frontend/src/lib/hooks/useIsProjectSharingEnabled.ts Migrates to useBooleanFlagValue("project_sharing").
client/webui/frontend/src/lib/hooks/useIsProjectIndexingEnabled.ts Migrates to useBooleanFlagValue("project_indexing").
client/webui/frontend/src/lib/contexts/ConfigContext.ts Removes autoTitleGenerationEnabled from the context contract.
client/webui/frontend/src/lib/components/pages/ChatPage.tsx Migrates auto-title gating to OpenFeature flag + persistence prerequisite.
client/webui/frontend/src/lib/components/chat/SessionList.tsx Migrates auto-title gating to OpenFeature flag + persistence prerequisite.
client/webui/frontend/src/lib/components/chat/MessageHoverButtons.tsx Migrates mentions gating to OpenFeature flag.
client/webui/frontend/src/lib/components/chat/ChatInputArea.tsx Migrates mentions gating to OpenFeature flag + identity-service prerequisite.
Comments suppressed due to low confidence (1)

client/webui/frontend/src/lib/contexts/ConfigContext.ts:69

  • autoTitleGenerationEnabled was removed from ConfigContextValue, but there is still at least one consumer destructuring it (e.g. client/webui/frontend/src/lib/components/chat/RecentChatsList.tsx). This will break the frontend TypeScript build; migrate that component to derive the value from useBooleanFlagValue("auto_title_generation", false) (and persistence gating) like the other updated call sites.
    platformConfigured: boolean;

    /**
     * Whether Identity Service is configured.
     * When null, Identity Service is not configured.
     */
    identityServiceType: string | null;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Migrate RecentChatsList.tsx to useBooleanFlagValue (missed in
  initial migration, causing TS2339 build error)
- Clear all SAM_FEATURE_<KEY> env vars in test_no_env_override_by_default
  to prevent false failures when other flag env vars are set

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 13, 2026

WhiteSource Policy Violation Summary

✅︎ No Blocking Whitesource Policy Violations found in solaceai/solace-agent-mesh-ui-pr-1178!

bwiebe-solace and others added 2 commits March 13, 2026 14:34
Avoid redundant setProvider calls on every render by using a useRef
guard in MockConfigProvider. Provider is only re-registered when the
flags object reference changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove auto_title_generation, projectIndexing, and project_indexing
from frontend_feature_enablement and component config. These are now
controlled via SAM_FEATURE_* environment variables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bwiebe-solace bwiebe-solace marked this pull request as ready for review March 16, 2026 18:54
@bwiebe-solace bwiebe-solace requested a review from Copilot March 16, 2026 18:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates feature-flag consumption across the SAM backend and WebUI frontend from legacy config-based checks to the OpenFeature-backed FeatureChecker evaluation chain, updates the community features.yaml catalog accordingly, and refreshes related integration/Storybook tests and examples.

Changes:

  • Backend: replace frontend_feature_enablement / config lookups with component.feature_checker.is_enabled(...) and add reusable FastAPI dependencies for flag gating/injection.
  • Frontend: replace ConfigContext-derived flag reads with useBooleanFlagValue(...) and update Storybook mocks/test data for snake_case keys.
  • Registry/tests/docs: register migrated flags in features.yaml and update integration tests and example configuration comments.

Reviewed changes

Copilot reviewed 48 out of 48 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
tmp3/src/init.py Adds placeholder package init for tmp3.
tmp3/proxy_single_connection.yaml.disabled Adds single-connection proxy profiling config.
tmp3/proxy_dual_connection.yaml Adds dual-connection proxy profiling config.
tmp3/configs/shared_config.yaml Adds shared broker/model/service config for tmp3 examples.
tmp3/configs/services/platform.yaml Adds platform service template config (tmp3).
tmp3/configs/proxies/a2a_proxy_with_batching_example.yaml Adds batching-focused proxy config example (tmp3).
tmp3/configs/logging_config.yaml Adds logging config template (tmp3).
tmp3/configs/gateways/webui.yaml Adds WebUI gateway config template (tmp3).
tmp3/configs/agents/sam-geo-information.yaml Adds example agent plugin config (tmp3).
tmp3/configs/agents/markitdown_agent.yaml Adds example agent config (tmp3).
tmp3/configs/agents/main_orchestrator.yaml Adds orchestrator agent config (tmp3).
tmp3/a2a_test_server_proxy.yaml Adds A2A test server proxy config (tmp3).
tmp3/README.md Adds profiling README (tmp3).
tmp2/src/init.py Adds placeholder package init for tmp2.
tmp2/proxy_single_connection.yaml.disabled Adds single-connection proxy profiling config.
tmp2/proxy_dual_connection.yaml Adds dual-connection proxy profiling config.
tmp2/configs/shared_config.yaml Adds shared broker/model/service config for tmp2 examples.
tmp2/configs/services/platform.yaml Adds platform service template config (tmp2).
tmp2/configs/proxies/a2a_proxy_with_batching_example.yaml Adds batching-focused proxy config example (tmp2).
tmp2/configs/logging_config.yaml Adds logging config template (tmp2).
tmp2/configs/gateways/webui.yaml Adds WebUI gateway config template (tmp2).
tmp2/configs/agents/markitdown_agent.yaml Adds example agent config (tmp2).
tmp2/configs/agents/main_orchestrator.yaml Adds orchestrator agent config (tmp2).
tmp2/a2a_test_server_proxy.yaml Adds A2A test server proxy config (tmp2).
tmp2/README.md Adds profiling README (tmp2).
tests/integration/apis/test_feature_flags_router.py Updates integration assertions to newly-registered flags (e.g., mentions).
src/solace_agent_mesh/gateway/http_sse/services/session_service.py Switches project-indexing gating to feature_checker.is_enabled("project_indexing").
src/solace_agent_mesh/gateway/http_sse/routers/tasks.py Switches project-indexing gating and updates related comments.
src/solace_agent_mesh/gateway/http_sse/routers/projects.py Replaces bespoke indexing dependency with get_feature_value("project_indexing").
src/solace_agent_mesh/gateway/http_sse/routers/feature_flags.py Adjusts exception logging for feature flag endpoint.
src/solace_agent_mesh/gateway/http_sse/routers/config.py Migrates mentions/auto-title config evaluation to OpenFeature flags.
src/solace_agent_mesh/gateway/http_sse/dependencies.py Adds require_feature(...) and get_feature_value(...) dependency factories.
src/solace_agent_mesh/common/features/features.yaml Registers migrated flags (mentions, auto_title_generation, project_sharing, project_indexing).
examples/gateways/webui_gateway_example.yaml Updates example comments to reflect SAM_FEATURE_* control for migrated flags.
client/webui/frontend/src/stories/workflowVisualization/WorkflowNodeDetailPanel.stories.tsx Adds Storybook stories/tests for workflow node detail panel.
client/webui/frontend/src/stories/mocks/MockConfigProvider.tsx Updates Storybook mock provider to initialize OpenFeature for flag hooks.
client/webui/frontend/src/stories/data/parameters.ts Updates Storybook parameter data to snake_case flag keys.
client/webui/frontend/src/stories/chat/ChatSidePanel.test.tsx Updates Storybook test data for project_indexing snake_case key.
client/webui/frontend/src/lib/providers/ConfigProvider.tsx Removes autoTitleGenerationEnabled from config context mapping (now OpenFeature-driven).
client/webui/frontend/src/lib/providers/ChatProvider.tsx Uses OpenFeature flag for auto-title generation enablement.
client/webui/frontend/src/lib/hooks/useIsProjectSharingEnabled.ts Migrates to useBooleanFlagValue("project_sharing").
client/webui/frontend/src/lib/hooks/useIsProjectIndexingEnabled.ts Migrates to useBooleanFlagValue("project_indexing").
client/webui/frontend/src/lib/contexts/ConfigContext.ts Removes autoTitleGenerationEnabled from the config context interface.
client/webui/frontend/src/lib/components/pages/ChatPage.tsx Computes auto-title enablement from OpenFeature + persistence.
client/webui/frontend/src/lib/components/chat/SessionList.tsx Computes auto-title enablement from OpenFeature + persistence.
client/webui/frontend/src/lib/components/chat/RecentChatsList.tsx Computes auto-title enablement from OpenFeature + persistence.
client/webui/frontend/src/lib/components/chat/MessageHoverButtons.tsx Migrates mentions check to OpenFeature.
client/webui/frontend/src/lib/components/chat/ChatInputArea.tsx Migrates mentions check to OpenFeature (with identity-service gating).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…flag-migration

# Conflicts:
#	client/webui/frontend/src/lib/components/chat/SessionList.tsx
#	client/webui/frontend/src/lib/components/pages/ChatPage.tsx
#	examples/gateways/webui_gateway_example.yaml
#	src/solace_agent_mesh/gateway/http_sse/routers/projects.py
#	src/solace_agent_mesh/gateway/http_sse/routers/tasks.py
#	src/solace_agent_mesh/gateway/http_sse/services/session_service.py
@bwiebe-solace bwiebe-solace force-pushed the bwiebe/DATAGO-126647/flag-migration branch from dfb0f18 to 9aea682 Compare March 16, 2026 19:38
bwiebe-solace and others added 4 commits March 16, 2026 16:17
- Update test_config_auto_title.py to use feature_checker.is_enabled
  mock instead of old get_config mock (fixes CI failure)
- Add test_feature_dependencies.py with tests for require_feature
  and get_feature_value dependency factories (coverage)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cover all three branches of the mentions feature flag helper:
disabled when no identity_service, disabled when flag is off,
and enabled when both conditions are met.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nal invocation

useBooleanFlagValue() calls combined with && short-circuit evaluation
are fragile — reordering operands could violate React's rules-of-hooks.
Extract each hook call into its own const, then combine with the
non-hook condition on a separate line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…g names

The feature flags router integration test was asserting against real
production flag keys (mentions, etc.), making it fragile to flag
renames or metadata changes. Introduce a test-only features.yaml with
fake flags and a features_yaml_path param on WebUIBackendFactory so
framework tests are isolated from production definitions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bwiebe-solace and others added 2 commits March 18, 2026 10:55
autoTitleGenerationEnabled is not part of ConfigContextValue — it is
computed locally in ChatProvider. The field was incorrectly added to
the mock config in a test introduced via the main branch merge,
causing a TypeScript compile error that broke the CI build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqube-solacecloud
Copy link

@bwiebe-solace
Copy link
Contributor Author

closing, will re-open a new PR which is based on #1221 to align with the modified approach and keep the history cleaner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants