Plug in feature and example we flourish plugin#225
Conversation
Enhance solution metadata and add facility subset matching
This commit addresses the integration gap between OHM and WeFlourish by implementing the OHM Agent side of the commercial lifecycle. Changes: - Created `src/core/models/rfq.py` with `Bid` and `Quote` models. - Implemented `src/core/services/rfq_service.py` to handle outbound bid creation to WeFlourish and inbound webhook processing. - Added `POST /api/rfq/bids` and `POST /api/rfq/webhooks/weflourish` endpoints to `src/core/api/routes/rfq.py`. - Implemented HMAC-SHA256 signature verification for WeFlourish webhooks. - Updated `src/config/settings.py` with WeFlourish API configuration and webhook secrets. - Added integration tests in `tests/core/api/test_rfq_integration.py`. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
This commit introduces a modular plugin architecture to the OHM Agent, enabling specialized integrations without bloating the core platform. Architecture Changes: - Added `src/plugins/base.py` with `BasePlugin` and `PluginSettings` (Pydantic). - Implemented `PluginManager` for gated discovery and lifecycle management. - Integrated plugins into FastAPI lifespan and route registration in `main.py`. WeFlourish/OHM Refactor: - Migrated the RFQ integration into `src/plugins/weflourish_ohm/`. - Implemented secure webhooks (`quote.created`, `quote.accepted`, `bid.status_changed`). - Added outbound bid pushing with automatic `callback_url` injection. - Ensured HMAC-SHA256 signature verification for inbound events. Commercial Primitives: - Added `Bid` and `Quote` models to `src/core/models/rfq.py`. Documentation & Testing: - Added `docs/development/plugins.md` for plugin developers. - Added integration tests for the plugin system and WeFlourish logic. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
This commit introduces a modular plugin architecture to the OHM Agent, enabling specialized integrations without bloating the core platform. The commercial models (Bid, Quote) are designed to be integration-agnostic. Changes: - Added `src/plugins/base.py` with `BasePlugin` and `PluginSettings`. - Implemented `PluginManager` for gated discovery and lifecycle management. - Integrated plugins into FastAPI lifespan and route registration in `main.py`. - Migrated the WeFlourish integration into `src/plugins/weflourish_ohm/`. - Refactored `Bid` model in `src/core/models/rfq.py` to use generic `external_id`. - Implemented secure webhooks and outbound bid logic within the plugin. - Added documentation in `docs/development/plugins.md`. - Added integration tests for the plugin framework and WeFlourish sync. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
…ion-14588912685916048989 WeFlourish RFQ Integration and Webhook Synchronization
This commit introduces a modular plugin architecture to the OHM Agent, enabling specialized integrations (like WeFlourish) while maintaining a clean, agnostic core platform. Architecture Changes: - Added `src/plugins/base.py`: Abstract base classes for plugins and settings. - Added `src/plugins/manager.py`: Singleton manager for gated discovery and lifecycle management. - Updated `src/core/main.py`: Integrated plugin discovery, lifecycle hooks, and route registration. - Added `OHM_ACTIVE_PLUGINS` config to `src/config/settings.py`. Agnostic Commercial Models: - Created `src/core/models/rfq.py`: Defined `Bid`, `Quote`, and `QuoteItem` as universal supply graph primitives. - Ensured models are integration-agnostic by using `external_id` instead of vendor-specific fields. WeFlourish Integration Plugin: - Implemented `src/plugins/weflourish_ohm/`: A self-contained plugin for WeFlourish sync. - Features secure HMAC-SHA256 webhooks for `quote.created`, `quote.accepted`, and `bid.status_changed`. - Handles outbound bid creation with automatic callback URL injection. Documentation & Testing: - Created `docs/development/plugins.md`: Developer guide for the plugin system. - Added `tests/core/api/test_rfq_plugin.py`: Integration tests for the plugin and WeFlourish sync logic. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
This commit introduces a modular plugin architecture to the OHM Agent, enabling specialized integrations without bloating the core platform. The commercial bidding lifecycle for WeFlourish is refactored into a self-contained plugin. Key Changes: - Plugin System: Added `BasePlugin` and `PluginManager` for dynamic, environment-gated loading of integrations (`OHM_ACTIVE_PLUGINS`). - Agnostic Models: Refactored `Bid` and `Quote` in `src/core/models/rfq.py` to use generic `external_id` and standardized statuses. - WeFlourish Plugin: Migrated bid creation and HMAC-signed webhook logic to `src/plugins/weflourish_ohm/`. - Testing: Added unit tests for the plugin manager and service, and integration tests for the full webhook lifecycle. - Documentation: Added `docs/development/plugins.md` to guide authors. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
This commit refactors the plugin architecture to ensure that each plugin is fully self-contained (monolithic), with its own tests, config, and business logic in a single directory. Changes: - Refactored `weflourish_ohm` plugin to include its own `tests/` directory. - Implemented `tests/plugins/runner.py`: A dynamic test scanner that automatically discovers and executes tests located inside `src/plugins/*/tests/`. - Updated `docs/development/plugins.md` to document the monolithic structure and how to run plugin tests. - Verified that all unit and integration tests for the WeFlourish plugin pass using the new scanner. - Maintained agnostic core models and gated plugin discovery. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
…ion-14588912685916048989 Feat/weflourish rfq integration 14588912685916048989
Implement reverse matching for facility design production
touchthesun
left a comment
There was a problem hiding this comment.
Thanks for this, @LokiMetaSmith — this is a substantial, well-organized contribution, and the core instinct is exactly right: keep integrations out of the core and behind a consistent, documented pattern. The BasePlugin/PluginManager design is clean, it's tested, and docs/development/plugins.md is a great touch. We'd like to land the mechanism — with some changes so it lines up with where we're taking the plugin architecture.
For context: we've been putting together our own specification for the plugin system in parallel, so this review is about reconciling your implementation with that direction rather than any problem with the code quality.
What's working well
- Explicit
ACTIVE_PLUGINSallowlist + in-treesrc/plugins/+ in-process loading — this matches our trust model almost exactly (first-party, vetted-by-review, no arbitrary auto-discovery). 👍 - Clean lifecycle (
initialize/on_startup/on_shutdown) and isolated per-plugin config viapydantic-settings. - A real, tested example integration rather than a bare abstraction.
The main reframe: two classes of plugin
We think of plugins in two distinct shapes, and it affects the contract:
- Data-source / interop adapters — bring external data into OHM's model (
fetch → normalize to OKH/OKW). This is our highest-priority extension point: generalizing our existing Maps of Making integration so others (e.g. Appropedia, fablabs.io) can plug in design/facility sources. Your current framework doesn't cover this class — it's oriented around mounting API routes, which is a different axis. - Business-logic / connector plugins — sit on top of OHM, consuming its data or bridging to external tools (RFQ, cost estimation, etc.). Your WeFlourish integration is a great example of this class, and route-mounting is a reasonable mechanism for it.
So: the framework serves class (2) well, but we don't want it to become the only plugin concept and leave class (1) as a separate parallel system. We'd like the registration/lifecycle to be shared, with class (1) adapters carrying a typed → OKH/OKW contract.
Requested changes before re-review
- Split the PR. Please separate the framework (
base.py,manager.py, main.py wiring, docs) from the WeFlourish/RFQ integration. We'd like to evaluate and iterate on the mechanism on its own; the partner integration can follow once the framework is settled. - Keep partner/domain shapes out of core.
src/core/models/rfq.pyputs an RFQ model in the core — that undercuts the "core stays agnostic" goal. RFQ-specific models should live inside the plugin. (Heads-up: RFQ is currently shelved on our side pending a product decision, so please don't make the framework depend on it.) - Reconcile with the data-source axis. Let's make sure there's one plugin concept. Happy to work with you on a small typed contract for data-source adapters that reuses your
BasePluginregistration/lifecycle. - Provenance + untrusted-by-default for any data-importing plugin. Anything that imports records must attach its source/provenance, and imported data should be treated as unverified so downstream (matching/browse) can filter or down-weight it. Not needed for WeFlourish, but it belongs in the base contract for class (1).
- Capability declaration & versioning. Two things to add to the contract: (a) plugins declaring the capabilities they need (network, storage-write, read-only, …) toward least-privilege, and (b) a plugin-API version so we can manage compatibility as the contract evolves.
Smaller notes
- Consider what happens when a listed plugin fails to import mid-list — right now
discover_and_loadlogs and continues, which is reasonable, but we should decide whether a failed active plugin should hard-fail startup in some environments. - A scaffold/template plugin (or a
create-pluginhelper) would make external authorship as easy as we want it to be — the docs are a great start here.
To be clear on scope: unvetted third-party plugins / sandboxing are explicitly out of scope for now — in-tree + allowlisted + reviewed is the model we want at this stage, which your design already fits.
Really appreciate the work here — this is a strong foundation and we'd like to get it in. Happy to pair on the data-source contract so class (1) and class (2) share one clean framework. 🙏
This commit refactors the OHM plugin system to follow a clean, agnostic framework as requested. Key changes include: - Isolated the plugin framework from the WeFlourish/RFQ integration. - Introduced `DataSourcePlugin` with a fetch/normalize contract. - Added `PluginCapability` enum and `plugin_api_version` to `BasePlugin`. - Updated `OKHManifest` and `ManufacturingFacility` models with `provenance` and `is_verified` (default False) fields. - Implemented `OHM_STRICT_PLUGINS` env var for mandatory plugin loading. - Removed all RFQ-related models, routes, and frontend components to keep the core agnostic. - Added a `src/plugins/template/` scaffold for developers. - Updated `docs/development/plugins.md` to reflect the new architecture. All parity and core unit tests pass after cleaning up stale imports. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
This commit refactors the OHM plugin system to follow a clean, agnostic framework as requested by @touchthesun. Key changes include: - Isolated the plugin framework from the WeFlourish/RFQ integration. - Introduced `DataSourcePlugin` with a fetch/normalize contract for Class 1 plugins. - Added `PluginCapability` enum and `plugin_api_version` to `BasePlugin` to support a least-privilege model. - Updated `OKHManifest` and `ManufacturingFacility` models with `provenance` and `is_verified` (default False) fields to support the "untrusted-by-default" ingestion model. - Implemented `OHM_STRICT_PLUGINS` environment variable to allow hard-failing on plugin load errors. - Evicted RFQ-specific models and routes from the core to maintain architectural agnosticism. - Added a `src/plugins/template/` scaffold to facilitate external plugin authorship. - Updated documentation in `docs/development/plugins.md`. All parity and core unit tests pass. RFQ references in the frontend were also removed to ensure consistency. Co-authored-by: LokiMetaSmith <5054116+LokiMetaSmith@users.noreply.github.com>
…3058735781345463942 Refactor Plugin Framework and Agnostic Core
Implementation of Modular Integration Plugin System and WeFlourish Integration
This PR introduces a modular plugin architecture to the OHM platform, enabling external integrations (such as WeFlourish) to operate as self-contained modules without increasing coupling in the core codebase.
Key Changes:
PluginManagerto handle discovery, lifecycle hooks (startup/shutdown), and dynamic route registration.src/plugins/, featuring standardized structures (routes, services, and private configuration viapydantic-settings).src/core/main.pyto trigger plugin lifecycles and register routes during application startup.docs/development/plugins.mdto guide future plugin development and standard best practices.New Dependencies:
pydantic-settingstopyproject.tomlto support isolated plugin configurations.This structure keeps the core agnostic and ensures that integrations follow consistent development patterns.