1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Location: ./crates/cpex-core/src/factory.rs
// Copyright 2025
// SPDX-License-Identifier: Apache-2.0
// Authors: Teryl Taylor
//
// Plugin factory registry.
//
// Provides a factory pattern for creating plugin instances from
// config. The host registers factories by `kind` name before
// loading config. When the manager processes a config file, it
// looks up the factory for each plugin's `kind` and calls create().
//
// This decouples plugin instantiation from the manager — the
// manager doesn't know how to create a "builtin" vs "wasm" vs
// "python" plugin. The factory does.
//
// Mirrors the Python framework's PluginLoader in
// cpex/framework/loader/plugin.py.
use HashMap;
use Arc;
use cratePluginError;
use crate;
use crateAnyHookHandler;
// ---------------------------------------------------------------------------
// Plugin Factory Trait
// ---------------------------------------------------------------------------
/// Factory for creating plugin instances from config.
///
/// The host registers factories by `kind` name before loading
/// config. When the manager processes a config file, it looks up
/// the factory for each plugin's `kind` and calls `create()`.
///
/// The factory returns both the plugin and its handler because it
/// knows the concrete types — which handler traits the plugin
/// implements and which hooks it handles.
///
/// # Examples
///
/// ```rust,ignore
/// struct RateLimiterFactory;
///
/// impl PluginFactory for RateLimiterFactory {
/// fn create(&self, config: &PluginConfig)
/// -> Result<PluginInstance, Box<PluginError>>
/// {
/// let plugin = Arc::new(RateLimiter::from_config(config)?);
/// let handler = Arc::new(TypedHandlerAdapter::<RequestHeadersReceived, _>::new(
/// Arc::clone(&plugin),
/// ));
/// Ok(PluginInstance { plugin, handler })
/// }
/// }
///
/// let mut factories = PluginFactoryRegistry::new();
/// factories.register("security/rate_limit", Box::new(RateLimiterFactory));
/// ```
/// A created plugin instance — the plugin and its type-erased handlers.
///
/// Each handler is paired with the hook name it handles. A plugin
/// that implements multiple hook types (e.g., `ToolPreInvoke` and
/// `ToolPostInvoke`) returns one entry per hook.
// ---------------------------------------------------------------------------
// Plugin Factory Registry
// ---------------------------------------------------------------------------
/// Registry of plugin factories keyed by `kind` name.
///
/// The host populates this before calling `PluginManager::from_config()`.
/// Each factory knows how to create plugins of a specific kind.
///
/// # Examples
///
/// ```rust,ignore
/// let mut factories = PluginFactoryRegistry::new();
/// factories.register("builtin/rate_limit", Box::new(RateLimiterFactory));
/// factories.register("builtin/identity", Box::new(IdentityFactory));
///
/// let manager = PluginManager::from_config(path, &factories)?;
/// ```