@spinabot/brigade 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -11
- package/convex/config.d.ts +2 -2
- package/convex/extensions.d.ts +2 -2
- package/convex/logs.d.ts +2 -2
- package/convex/memory.d.ts +7 -7
- package/convex/messages.d.ts +4 -4
- package/convex/schema.d.ts +17 -17
- package/convex/subagents.d.ts +12 -12
- package/dist/agents/agent-loop.d.ts +1 -0
- package/dist/agents/agent-loop.d.ts.map +1 -1
- package/dist/agents/agent-loop.js +1 -1
- package/dist/agents/agent-loop.js.map +1 -1
- package/dist/agents/channels/access-control/format-allow-from.d.ts +50 -0
- package/dist/agents/channels/access-control/format-allow-from.d.ts.map +1 -0
- package/dist/agents/channels/access-control/format-allow-from.js +64 -0
- package/dist/agents/channels/access-control/format-allow-from.js.map +1 -0
- package/dist/agents/channels/access-control/index.d.ts +2 -1
- package/dist/agents/channels/access-control/index.d.ts.map +1 -1
- package/dist/agents/channels/access-control/index.js +2 -1
- package/dist/agents/channels/access-control/index.js.map +1 -1
- package/dist/agents/channels/access-control/store.d.ts +15 -0
- package/dist/agents/channels/access-control/store.d.ts.map +1 -1
- package/dist/agents/channels/access-control/store.js +44 -1
- package/dist/agents/channels/access-control/store.js.map +1 -1
- package/dist/agents/channels/bundled-channel-metas.d.ts +26 -0
- package/dist/agents/channels/bundled-channel-metas.d.ts.map +1 -0
- package/dist/agents/channels/bundled-channel-metas.js +44 -0
- package/dist/agents/channels/bundled-channel-metas.js.map +1 -0
- package/dist/agents/channels/channel-messaging-registry.d.ts +130 -0
- package/dist/agents/channels/channel-messaging-registry.d.ts.map +1 -0
- package/dist/agents/channels/channel-messaging-registry.js +211 -0
- package/dist/agents/channels/channel-messaging-registry.js.map +1 -0
- package/dist/agents/channels/channel-meta-registry.d.ts +60 -0
- package/dist/agents/channels/channel-meta-registry.d.ts.map +1 -0
- package/dist/agents/channels/channel-meta-registry.js +128 -0
- package/dist/agents/channels/channel-meta-registry.js.map +1 -0
- package/dist/agents/channels/channel-security-registry.d.ts +138 -0
- package/dist/agents/channels/channel-security-registry.d.ts.map +1 -0
- package/dist/agents/channels/channel-security-registry.js +265 -0
- package/dist/agents/channels/channel-security-registry.js.map +1 -0
- package/dist/agents/channels/exposure.d.ts +44 -0
- package/dist/agents/channels/exposure.d.ts.map +1 -0
- package/dist/agents/channels/exposure.js +48 -0
- package/dist/agents/channels/exposure.js.map +1 -0
- package/dist/agents/channels/general-callback.d.ts +25 -0
- package/dist/agents/channels/general-callback.d.ts.map +1 -0
- package/dist/agents/channels/general-callback.js +31 -0
- package/dist/agents/channels/general-callback.js.map +1 -0
- package/dist/agents/channels/inbound-pipeline.d.ts +9 -0
- package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -1
- package/dist/agents/channels/inbound-pipeline.js +429 -39
- package/dist/agents/channels/inbound-pipeline.js.map +1 -1
- package/dist/agents/channels/markdown-capability.d.ts +44 -0
- package/dist/agents/channels/markdown-capability.d.ts.map +1 -0
- package/dist/agents/channels/markdown-capability.js +66 -0
- package/dist/agents/channels/markdown-capability.js.map +1 -0
- package/dist/agents/channels/sdk.d.ts +170 -10
- package/dist/agents/channels/sdk.d.ts.map +1 -1
- package/dist/agents/channels/sdk.js +138 -6
- package/dist/agents/channels/sdk.js.map +1 -1
- package/dist/agents/channels/telegram/account-config.d.ts +41 -0
- package/dist/agents/channels/telegram/account-config.d.ts.map +1 -1
- package/dist/agents/channels/telegram/account-config.js +79 -0
- package/dist/agents/channels/telegram/account-config.js.map +1 -1
- package/dist/agents/channels/telegram/adapter.d.ts +6 -0
- package/dist/agents/channels/telegram/adapter.d.ts.map +1 -1
- package/dist/agents/channels/telegram/adapter.js +185 -6
- package/dist/agents/channels/telegram/adapter.js.map +1 -1
- package/dist/agents/channels/telegram/allowed-updates.d.ts +14 -5
- package/dist/agents/channels/telegram/allowed-updates.d.ts.map +1 -1
- package/dist/agents/channels/telegram/allowed-updates.js +8 -4
- package/dist/agents/channels/telegram/allowed-updates.js.map +1 -1
- package/dist/agents/channels/telegram/connection.d.ts +118 -1
- package/dist/agents/channels/telegram/connection.d.ts.map +1 -1
- package/dist/agents/channels/telegram/connection.js +380 -8
- package/dist/agents/channels/telegram/connection.js.map +1 -1
- package/dist/agents/channels/telegram/draft-stream.d.ts +98 -0
- package/dist/agents/channels/telegram/draft-stream.d.ts.map +1 -0
- package/dist/agents/channels/telegram/draft-stream.js +222 -0
- package/dist/agents/channels/telegram/draft-stream.js.map +1 -0
- package/dist/agents/channels/telegram/format.d.ts +17 -0
- package/dist/agents/channels/telegram/format.d.ts.map +1 -1
- package/dist/agents/channels/telegram/format.js +36 -0
- package/dist/agents/channels/telegram/format.js.map +1 -1
- package/dist/agents/channels/telegram/inbound-extras.d.ts +27 -2
- package/dist/agents/channels/telegram/inbound-extras.d.ts.map +1 -1
- package/dist/agents/channels/telegram/inbound-extras.js +134 -7
- package/dist/agents/channels/telegram/inbound-extras.js.map +1 -1
- package/dist/agents/channels/telegram/inline-keyboard.d.ts +36 -0
- package/dist/agents/channels/telegram/inline-keyboard.d.ts.map +1 -0
- package/dist/agents/channels/telegram/inline-keyboard.js +62 -0
- package/dist/agents/channels/telegram/inline-keyboard.js.map +1 -0
- package/dist/agents/channels/telegram/media.d.ts +8 -0
- package/dist/agents/channels/telegram/media.d.ts.map +1 -1
- package/dist/agents/channels/telegram/media.js +30 -2
- package/dist/agents/channels/telegram/media.js.map +1 -1
- package/dist/agents/channels/telegram/plugin.d.ts.map +1 -1
- package/dist/agents/channels/telegram/plugin.js +7 -11
- package/dist/agents/channels/telegram/plugin.js.map +1 -1
- package/dist/agents/channels/telegram/reasoning-lane.d.ts +41 -0
- package/dist/agents/channels/telegram/reasoning-lane.d.ts.map +1 -0
- package/dist/agents/channels/telegram/reasoning-lane.js +67 -0
- package/dist/agents/channels/telegram/reasoning-lane.js.map +1 -0
- package/dist/agents/channels/telegram/socks-dispatcher.d.ts +32 -0
- package/dist/agents/channels/telegram/socks-dispatcher.d.ts.map +1 -0
- package/dist/agents/channels/telegram/socks-dispatcher.js +97 -0
- package/dist/agents/channels/telegram/socks-dispatcher.js.map +1 -0
- package/dist/agents/channels/types.adapters.d.ts +137 -4
- package/dist/agents/channels/types.adapters.d.ts.map +1 -1
- package/dist/agents/channels/types.adapters.js +2 -2
- package/dist/agents/channels/types.core.d.ts +26 -2
- package/dist/agents/channels/types.core.d.ts.map +1 -1
- package/dist/agents/channels/types.plugin.d.ts +25 -7
- package/dist/agents/channels/types.plugin.d.ts.map +1 -1
- package/dist/agents/channels/types.plugin.js +6 -5
- package/dist/agents/channels/types.plugin.js.map +1 -1
- package/dist/agents/channels/whatsapp/adapter.d.ts +8 -0
- package/dist/agents/channels/whatsapp/adapter.d.ts.map +1 -1
- package/dist/agents/channels/whatsapp/adapter.js +7 -4
- package/dist/agents/channels/whatsapp/adapter.js.map +1 -1
- package/dist/agents/channels/whatsapp/connection.d.ts +24 -2
- package/dist/agents/channels/whatsapp/connection.d.ts.map +1 -1
- package/dist/agents/channels/whatsapp/connection.js +26 -5
- package/dist/agents/channels/whatsapp/connection.js.map +1 -1
- package/dist/agents/channels/whatsapp/plugin.d.ts.map +1 -1
- package/dist/agents/channels/whatsapp/plugin.js +6 -10
- package/dist/agents/channels/whatsapp/plugin.js.map +1 -1
- package/dist/agents/extensions/activation-planner.d.ts +125 -0
- package/dist/agents/extensions/activation-planner.d.ts.map +1 -0
- package/dist/agents/extensions/activation-planner.js +221 -0
- package/dist/agents/extensions/activation-planner.js.map +1 -0
- package/dist/agents/extensions/diagnose.d.ts +84 -0
- package/dist/agents/extensions/diagnose.d.ts.map +1 -0
- package/dist/agents/extensions/diagnose.js +123 -0
- package/dist/agents/extensions/diagnose.js.map +1 -0
- package/dist/agents/extensions/discovery.d.ts +85 -7
- package/dist/agents/extensions/discovery.d.ts.map +1 -1
- package/dist/agents/extensions/discovery.js +200 -15
- package/dist/agents/extensions/discovery.js.map +1 -1
- package/dist/agents/extensions/index.d.ts +3 -2
- package/dist/agents/extensions/index.d.ts.map +1 -1
- package/dist/agents/extensions/index.js +3 -2
- package/dist/agents/extensions/index.js.map +1 -1
- package/dist/agents/extensions/install-scan.d.ts +63 -0
- package/dist/agents/extensions/install-scan.d.ts.map +1 -0
- package/dist/agents/extensions/install-scan.js +201 -0
- package/dist/agents/extensions/install-scan.js.map +1 -0
- package/dist/agents/extensions/install.d.ts +135 -0
- package/dist/agents/extensions/install.d.ts.map +1 -0
- package/dist/agents/extensions/install.js +414 -0
- package/dist/agents/extensions/install.js.map +1 -0
- package/dist/agents/extensions/loader.d.ts +13 -2
- package/dist/agents/extensions/loader.d.ts.map +1 -1
- package/dist/agents/extensions/loader.js +126 -13
- package/dist/agents/extensions/loader.js.map +1 -1
- package/dist/agents/extensions/registry.d.ts +109 -0
- package/dist/agents/extensions/registry.d.ts.map +1 -1
- package/dist/agents/extensions/registry.js +172 -0
- package/dist/agents/extensions/registry.js.map +1 -1
- package/dist/agents/extensions/sdk-alias.d.ts +45 -0
- package/dist/agents/extensions/sdk-alias.d.ts.map +1 -0
- package/dist/agents/extensions/sdk-alias.js +94 -0
- package/dist/agents/extensions/sdk-alias.js.map +1 -0
- package/dist/agents/extensions/types.d.ts +166 -1
- package/dist/agents/extensions/types.d.ts.map +1 -1
- package/dist/agents/extensions/types.js.map +1 -1
- package/dist/agents/tools/composio-tool.d.ts +9 -1
- package/dist/agents/tools/composio-tool.d.ts.map +1 -1
- package/dist/agents/tools/composio-tool.js +68 -4
- package/dist/agents/tools/composio-tool.js.map +1 -1
- package/dist/agents/tools/message-action-tool.d.ts +6 -1
- package/dist/agents/tools/message-action-tool.d.ts.map +1 -1
- package/dist/agents/tools/message-action-tool.js +52 -2
- package/dist/agents/tools/message-action-tool.js.map +1 -1
- package/dist/agents/tools/send-message-tool.d.ts +1 -0
- package/dist/agents/tools/send-message-tool.d.ts.map +1 -1
- package/dist/agents/tools/send-message-tool.js +56 -1
- package/dist/agents/tools/send-message-tool.js.map +1 -1
- package/dist/buildstamp.json +1 -1
- package/dist/channel-sdk.d.ts +28 -0
- package/dist/channel-sdk.d.ts.map +1 -0
- package/dist/channel-sdk.js +28 -0
- package/dist/channel-sdk.js.map +1 -0
- package/dist/cli/commands/channels.d.ts.map +1 -1
- package/dist/cli/commands/channels.js +8 -8
- package/dist/cli/commands/channels.js.map +1 -1
- package/dist/cli/commands/connect.d.ts +8 -11
- package/dist/cli/commands/connect.d.ts.map +1 -1
- package/dist/cli/commands/connect.js +157 -17
- package/dist/cli/commands/connect.js.map +1 -1
- package/dist/cli/commands/convex-cmd.d.ts +2 -1
- package/dist/cli/commands/convex-cmd.d.ts.map +1 -1
- package/dist/cli/commands/convex-cmd.js +79 -6
- package/dist/cli/commands/convex-cmd.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +64 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/extensions.d.ts +46 -0
- package/dist/cli/commands/extensions.d.ts.map +1 -0
- package/dist/cli/commands/extensions.js +578 -0
- package/dist/cli/commands/extensions.js.map +1 -0
- package/dist/cli/commands/pairing.d.ts.map +1 -1
- package/dist/cli/commands/pairing.js +16 -2
- package/dist/cli/commands/pairing.js.map +1 -1
- package/dist/cli/commands/update.d.ts +17 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +104 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/program/build-program.d.ts.map +1 -1
- package/dist/cli/program/build-program.js +114 -1
- package/dist/cli/program/build-program.js.map +1 -1
- package/dist/config/paths.d.ts +1 -0
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +9 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +134 -2
- package/dist/core/server.js.map +1 -1
- package/dist/protocol.d.ts +25 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js.map +1 -1
- package/dist/system-prompt/assembler.d.ts.map +1 -1
- package/dist/system-prompt/assembler.js +17 -0
- package/dist/system-prompt/assembler.js.map +1 -1
- package/dist/system-prompt/identity-defaults.d.ts +28 -0
- package/dist/system-prompt/identity-defaults.d.ts.map +1 -1
- package/dist/system-prompt/identity-defaults.js +47 -0
- package/dist/system-prompt/identity-defaults.js.map +1 -1
- package/dist/ui/editor.d.ts.map +1 -1
- package/dist/ui/editor.js +1 -0
- package/dist/ui/editor.js.map +1 -1
- package/dist/version.d.ts +4 -3
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +27 -5
- package/dist/version.js.map +1 -1
- package/package.json +21 -4
- package/scripts/build-done.mjs +11 -2
- package/scripts/convex-dev.mjs +28 -2
|
@@ -12,15 +12,27 @@
|
|
|
12
12
|
* Activation traceability: EVERY module decision (activated / skipped) emits a
|
|
13
13
|
* structured log line under the `extensions/loader` subsystem. The reason is a
|
|
14
14
|
* stable enum (`disabled`/`requiresEnv`/`eligible`/`allowlist`/`configSchema`/
|
|
15
|
-
* `registerFailed`) so an operator running
|
|
16
|
-
* JSONL log can answer "why didn't my plugin
|
|
15
|
+
* `registerFailed`/`activation-not-triggered`) so an operator running
|
|
16
|
+
* `brigade doctor` or scraping the JSONL log can answer "why didn't my plugin
|
|
17
|
+
* load" without source-diving.
|
|
18
|
+
*
|
|
19
|
+
* Step 5 — manifest-driven LAZY activation. User modules are no longer imported
|
|
20
|
+
* eagerly. The loader lists candidates WITHOUT importing, reads each one's
|
|
21
|
+
* sidecar `brigade.extension.json` manifest, and consults the activation planner
|
|
22
|
+
* (`activation-planner.ts`) against an active-config snapshot. A module whose
|
|
23
|
+
* declared `activation` triggers don't fire is NEVER imported (its top-level
|
|
24
|
+
* never runs) — O(manifest) boot. A module with no sidecar manifest is imported
|
|
25
|
+
* to recover its `manifest` field, then re-planned from the body, so back-compat
|
|
26
|
+
* holds (no manifest / no triggers ⇒ always activate). Skips here log
|
|
27
|
+
* `reason=activation-not-triggered`.
|
|
17
28
|
*/
|
|
18
29
|
import { Check, Errors } from "typebox/value";
|
|
19
30
|
import { resolveExtensionsDir } from "../../config/paths.js";
|
|
20
31
|
import { withTimeout } from "../../core/extension-lifecycle.js";
|
|
21
32
|
import { createSubsystemLogger } from "../../logging/subsystem-logger.js";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
33
|
+
import { buildActivationSnapshot, planActivation, } from "./activation-planner.js";
|
|
34
|
+
import { importDiscoveredModules, listDiscoveryCandidates, } from "./discovery.js";
|
|
35
|
+
import { BrigadeExtensionRegistry, diffCapabilityIds } from "./registry.js";
|
|
24
36
|
const log = createSubsystemLogger("extensions/loader");
|
|
25
37
|
// A module's register() should just record capabilities and return; cap it so a
|
|
26
38
|
// buggy/hung one can't wedge boot or a turn.
|
|
@@ -58,19 +70,69 @@ export async function loadModules(args) {
|
|
|
58
70
|
const allow = ext?.allow ?? [];
|
|
59
71
|
const entries = ext?.entries ?? {};
|
|
60
72
|
// Bundled first; then user modules (deduped — a bundled id wins).
|
|
73
|
+
//
|
|
74
|
+
// Step 5 — manifest-driven LAZY activation. Instead of importing every user
|
|
75
|
+
// candidate up front (eager, O(modules)), we list candidates WITHOUT
|
|
76
|
+
// importing, read each one's sidecar `brigade.extension.json` manifest, and
|
|
77
|
+
// consult the activation planner against the active-config snapshot. A
|
|
78
|
+
// candidate whose declared activation triggers don't fire is NEVER imported
|
|
79
|
+
// (its top-level never runs) — that's the cold-boot win. A candidate with no
|
|
80
|
+
// sidecar manifest is imported to recover its `manifest` field, then planned
|
|
81
|
+
// again from the body so back-compat is preserved (no manifest / no triggers
|
|
82
|
+
// ⇒ always activate).
|
|
61
83
|
const bundledIds = new Set(args.modules.map((m) => m.id));
|
|
62
84
|
const userModules = [];
|
|
63
85
|
if (!args.noDiscovery) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
86
|
+
// Fold the command names the bundled modules declare in their manifest
|
|
87
|
+
// into the activation snapshot, so a user module gated only on
|
|
88
|
+
// `onCommands:["foo"]` can match when a bundled module contributes `foo`
|
|
89
|
+
// (the built-in channel commands are added by the snapshot itself when a
|
|
90
|
+
// channel is configured).
|
|
91
|
+
const declaredCommands = collectDeclaredCommandNames(args.modules);
|
|
92
|
+
const snapshot = buildActivationSnapshot(config, declaredCommands);
|
|
93
|
+
const candidates = listDiscoveryCandidates(args.extensionsDir ?? resolveExtensionsDir());
|
|
94
|
+
for (const cand of candidates) {
|
|
95
|
+
if (cand.safetyReason) {
|
|
96
|
+
log.warn("rejected user extension — POSIX safety check failed", {
|
|
97
|
+
source: cand.source,
|
|
98
|
+
reason: cand.safetyReason,
|
|
70
99
|
});
|
|
71
100
|
continue;
|
|
72
101
|
}
|
|
73
|
-
|
|
102
|
+
// (a) Sidecar present → plan BEFORE importing. A non-triggered module is
|
|
103
|
+
// skipped here and its body never runs (the lazy-activation win).
|
|
104
|
+
if (cand.manifest) {
|
|
105
|
+
const decision = planActivation(cand.manifest, snapshot);
|
|
106
|
+
if (!decision.activate) {
|
|
107
|
+
logSkip(cand.manifest.id, "user", cand.source, "activation-not-triggered", decision.reason ?? "activation triggers did not match active config");
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// (b) Import the body (sidecar said activate, or there was no sidecar so
|
|
112
|
+
// we must read the module's own `manifest` field). The sidecar manifest,
|
|
113
|
+
// when present, is authoritative over a body-carried one.
|
|
114
|
+
const discovered = await importDiscoveredModules(cand.source, cand.manifest);
|
|
115
|
+
for (const d of discovered) {
|
|
116
|
+
// (c) No sidecar → re-plan from the body manifest (could carry its own
|
|
117
|
+
// activation triggers). If it doesn't trigger, skip registration —
|
|
118
|
+
// the body did run (no sidecar to gate on), but we still don't
|
|
119
|
+
// register a module the active config doesn't want.
|
|
120
|
+
if (!cand.manifest) {
|
|
121
|
+
const decision = planActivation(d.manifest, snapshot);
|
|
122
|
+
if (!decision.activate) {
|
|
123
|
+
logSkip(d.module.id, "user", d.source, "activation-not-triggered", decision.reason ?? "activation triggers did not match active config");
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (bundledIds.has(d.module.id)) {
|
|
128
|
+
log.warn("user extension shadows a bundled module id — ignoring the user one", {
|
|
129
|
+
id: d.module.id,
|
|
130
|
+
source: d.source,
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
userModules.push(d);
|
|
135
|
+
}
|
|
74
136
|
}
|
|
75
137
|
}
|
|
76
138
|
const all = [
|
|
@@ -87,6 +149,19 @@ export async function loadModules(args) {
|
|
|
87
149
|
logSkip(m.id, origin, source, "allowlist", "extensions.allow does not include this id");
|
|
88
150
|
continue;
|
|
89
151
|
}
|
|
152
|
+
// `enabledByDefault: false` opt-out — a module (typically a bundled one)
|
|
153
|
+
// can declare it does NOT auto-activate. It stays dormant unless the
|
|
154
|
+
// operator explicitly turns it back on via `extensions.entries[id].enabled
|
|
155
|
+
// = true` or by naming it in a non-empty `extensions.allow`. (An explicit
|
|
156
|
+
// `disabled` already short-circuited above; the allowlist gate above means
|
|
157
|
+
// that if we got here with a non-empty allow list, the id IS listed.)
|
|
158
|
+
if (m.manifest?.enabledByDefault === false) {
|
|
159
|
+
const forcedOn = entries[m.id]?.enabled === true || (allow.length > 0 && allow.includes(m.id));
|
|
160
|
+
if (!forcedOn) {
|
|
161
|
+
logSkip(m.id, origin, source, "enabledByDefault", "manifest enabledByDefault=false and not explicitly enabled (set extensions.entries[id].enabled=true to opt in)");
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
90
165
|
if (m.requiresEnv) {
|
|
91
166
|
const missing = m.requiresEnv.find((v) => !env[v] || env[v]?.trim() === "");
|
|
92
167
|
if (missing) {
|
|
@@ -106,20 +181,56 @@ export async function loadModules(args) {
|
|
|
106
181
|
logSkip(m.id, origin, source, "configSchema", `config invalid at ${first?.path ?? "<root>"}: ${first?.message ?? "validation error"}`);
|
|
107
182
|
continue;
|
|
108
183
|
}
|
|
184
|
+
// FIX 4 — mark the module discovered (it passed gating) and snapshot the
|
|
185
|
+
// registry's capability ids so we can attribute what THIS module registers.
|
|
186
|
+
registry.markModuleDiscovered(m.id);
|
|
187
|
+
const capsBefore = registry.capabilitySnapshot();
|
|
109
188
|
try {
|
|
110
189
|
// Time-box register so a hung module (e.g. a stray network await) can't
|
|
111
190
|
// wedge boot or the per-turn path. A well-behaved register just records
|
|
112
191
|
// and resolves instantly.
|
|
113
192
|
await withTimeout(Promise.resolve(m.register(registry.context({ ...args.meta, moduleConfig }))), REGISTER_TIMEOUT_MS, `module ${m.id} register`);
|
|
114
193
|
registry.loadedModules.push(m);
|
|
115
|
-
|
|
194
|
+
// FIX 4 — register() succeeded: attribute the newly-registered ids to
|
|
195
|
+
// this module and flip its record to `activated`.
|
|
196
|
+
registry.markModuleActivated(m.id, diffCapabilityIds(capsBefore, registry.capabilitySnapshot()));
|
|
197
|
+
// Per-module activation trace — one line per bundled module. At `info`
|
|
198
|
+
// this floods every short-lived CLI command (channels/pairing/agents all
|
|
199
|
+
// activate the full bundle just to enumerate adapters) and gateway boot.
|
|
200
|
+
// It's diagnostic detail, so it lives at `debug` (surface with --verbose
|
|
201
|
+
// / BRIGADE_LOG_LEVEL=debug). Failures + shadows still log at warn above.
|
|
202
|
+
log.debug("extension activated", { id: m.id, origin, source });
|
|
116
203
|
}
|
|
117
204
|
catch (err) {
|
|
205
|
+
// FIX 4 — record the register-phase failure so the CLI can show it live.
|
|
206
|
+
registry.markModuleFailed(m.id, "register");
|
|
118
207
|
logSkip(m.id, origin, source, "registerFailed", err instanceof Error ? err.message : String(err));
|
|
119
208
|
}
|
|
120
209
|
}
|
|
121
210
|
return registry;
|
|
122
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Collect the command names the given (bundled) modules declare in their
|
|
214
|
+
* manifest's `provides.commands` slot. Used to seed the activation snapshot's
|
|
215
|
+
* `commands` set so an `onCommands` trigger on a USER module can match a command
|
|
216
|
+
* a BUNDLED module provides. Deduped + trimmed; empties dropped.
|
|
217
|
+
*
|
|
218
|
+
* Note: a module's runtime `command()` / `channelCommand()` registrations aren't
|
|
219
|
+
* known until it's imported + registered, so we use the declarative manifest
|
|
220
|
+
* rather than running anything — keeping lazy activation lazy.
|
|
221
|
+
*/
|
|
222
|
+
function collectDeclaredCommandNames(modules) {
|
|
223
|
+
const out = new Set();
|
|
224
|
+
for (const m of modules) {
|
|
225
|
+
const provided = m.manifest?.provides?.commands ?? [];
|
|
226
|
+
for (const name of provided) {
|
|
227
|
+
const norm = typeof name === "string" ? name.trim() : "";
|
|
228
|
+
if (norm)
|
|
229
|
+
out.add(norm);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return [...out];
|
|
233
|
+
}
|
|
123
234
|
/**
|
|
124
235
|
* Emit a stable, structured `extension skipped` log line. The shape is
|
|
125
236
|
* deliberately fixed (`id`/`origin`/`source`/`reason`/`cause`) so a future
|
|
@@ -136,7 +247,9 @@ function logSkip(id, origin, source, reason, cause) {
|
|
|
136
247
|
log.warn("extension register failed", fields);
|
|
137
248
|
}
|
|
138
249
|
else {
|
|
139
|
-
|
|
250
|
+
// Per-module skip trace — same flood concern as "extension activated".
|
|
251
|
+
// Diagnostic detail → debug (surface with --verbose).
|
|
252
|
+
log.debug("extension skipped", fields);
|
|
140
253
|
}
|
|
141
254
|
}
|
|
142
255
|
//# sourceMappingURL=loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/agents/extensions/loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/agents/extensions/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
|
|
|
16
16
|
import type { BrigadeConfig } from "../../config/io.js";
|
|
17
17
|
import type { AnyBrigadeTool } from "../tools/types.js";
|
|
18
18
|
import { type BrigadeHookName, type HookFireResult } from "./hook-runner.js";
|
|
19
|
+
import type { ChannelMessagingAdapter, ChannelSecurityAdapter } from "../channels/types.adapters.js";
|
|
19
20
|
import type { BrigadeExtensionContext, ChannelAdapter, ChannelCommand, GatewayMethodHandler, HttpRoute, Integration, MediaGenProvider, ProviderAuthMethodRegistration, Service, SpeechProvider, TranscriptionProvider } from "./types.js";
|
|
20
21
|
/** Per-load context Brigade supplies to each module's `register(b)`. */
|
|
21
22
|
export interface RegistryContextMeta {
|
|
@@ -26,6 +27,56 @@ export interface RegistryContextMeta {
|
|
|
26
27
|
/** This module's validated config block (see `BrigadeExtensionContext.moduleConfig`). */
|
|
27
28
|
moduleConfig?: unknown;
|
|
28
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Lifecycle state of one module on the live registry (FIX 4 — the durable
|
|
32
|
+
* `PluginRecord` state machine the CLI can read live).
|
|
33
|
+
*
|
|
34
|
+
* - `discovered` — the loader decided to run this module (it passed gating) but
|
|
35
|
+
* `register()` has not completed yet.
|
|
36
|
+
* - `activated` — `register()` completed successfully; `capabilities` lists the
|
|
37
|
+
* capability ids this module contributed (attributed by diffing the registry
|
|
38
|
+
* before/after its `register()`).
|
|
39
|
+
* - `failed` — `register()` threw (or another register-phase step failed);
|
|
40
|
+
* `failurePhase` names where.
|
|
41
|
+
*
|
|
42
|
+
* Unlike the discovery-only `brigade extensions list`, this reflects the
|
|
43
|
+
* REGISTER phase — so an operator can see a module that imported fine but threw
|
|
44
|
+
* while registering, which discovery alone never surfaces.
|
|
45
|
+
*/
|
|
46
|
+
export type PluginRecordStatus = "discovered" | "activated" | "failed";
|
|
47
|
+
/** Capability ids a module contributed, grouped by kind (empty arrays omitted-as-[]). */
|
|
48
|
+
export interface PluginCapabilityIds {
|
|
49
|
+
tools: string[];
|
|
50
|
+
hooks: string[];
|
|
51
|
+
commands: string[];
|
|
52
|
+
modelProviders: string[];
|
|
53
|
+
channels: string[];
|
|
54
|
+
channelCommands: string[];
|
|
55
|
+
channelMessagingAdapters: string[];
|
|
56
|
+
channelSecurityAdapters: string[];
|
|
57
|
+
speechProviders: string[];
|
|
58
|
+
transcriptionProviders: string[];
|
|
59
|
+
mediaGenProviders: string[];
|
|
60
|
+
memoryCapabilities: string[];
|
|
61
|
+
contextEngines: string[];
|
|
62
|
+
compactionProviders: string[];
|
|
63
|
+
agentHarnesses: string[];
|
|
64
|
+
webSearchProviders: string[];
|
|
65
|
+
webFetchProviders: string[];
|
|
66
|
+
integrations: string[];
|
|
67
|
+
services: string[];
|
|
68
|
+
httpRoutes: string[];
|
|
69
|
+
gatewayMethods: string[];
|
|
70
|
+
}
|
|
71
|
+
/** A per-module runtime record on the live registry. */
|
|
72
|
+
export interface PluginRecord {
|
|
73
|
+
id: string;
|
|
74
|
+
status: PluginRecordStatus;
|
|
75
|
+
/** When `status === "failed"`, the phase that failed (e.g. `"register"`). */
|
|
76
|
+
failurePhase?: string;
|
|
77
|
+
/** Capability ids this module registered (populated on `activated`). */
|
|
78
|
+
capabilities: PluginCapabilityIds;
|
|
79
|
+
}
|
|
29
80
|
export declare class BrigadeExtensionRegistry {
|
|
30
81
|
private readonly toolRegs;
|
|
31
82
|
private readonly hookRegs;
|
|
@@ -34,6 +85,10 @@ export declare class BrigadeExtensionRegistry {
|
|
|
34
85
|
private readonly providerAuthMethodRegs;
|
|
35
86
|
private readonly channelMap;
|
|
36
87
|
private readonly channelCommandMap;
|
|
88
|
+
/** OUTBOUND messaging adapters declared on a channel slot, keyed by lowercased channel id. */
|
|
89
|
+
private readonly channelMessagingMap;
|
|
90
|
+
/** SUPPLEMENTARY security adapters declared on a channel slot, keyed by lowercased channel id. */
|
|
91
|
+
private readonly channelSecurityMap;
|
|
37
92
|
private readonly speechMap;
|
|
38
93
|
private readonly transcriptionMap;
|
|
39
94
|
private readonly mediaGenMap;
|
|
@@ -50,10 +105,56 @@ export declare class BrigadeExtensionRegistry {
|
|
|
50
105
|
private readonly gatewayMethodMap;
|
|
51
106
|
/** Modules that successfully registered — the loader fills this (used for reload). */
|
|
52
107
|
readonly loadedModules: import("./types.js").BrigadeModule[];
|
|
108
|
+
/**
|
|
109
|
+
* Per-module runtime lifecycle records (FIX 4). The loader populates these as
|
|
110
|
+
* it registers each module: `discovered` before `register()`, then `activated`
|
|
111
|
+
* (with attributed capabilities) or `failed`. Insertion-ordered (Map) so the
|
|
112
|
+
* CLI renders them in load order. Read via `pluginRecord(id)` / `pluginRecords()`.
|
|
113
|
+
*/
|
|
114
|
+
private readonly pluginRecordMap;
|
|
53
115
|
/** Build the recording context a module's `register(b)` writes into. */
|
|
54
116
|
context(meta: RegistryContextMeta): BrigadeExtensionContext;
|
|
117
|
+
/**
|
|
118
|
+
* Snapshot the FULL set of currently-registered capability ids, grouped by
|
|
119
|
+
* kind. The loader takes one of these BEFORE a module's `register()` and one
|
|
120
|
+
* AFTER, then diffs them to attribute the newly-registered ids to that module
|
|
121
|
+
* (see `diffCapabilityIds`). Pure read.
|
|
122
|
+
*/
|
|
123
|
+
capabilitySnapshot(): PluginCapabilityIds;
|
|
124
|
+
/** Record that a module was selected to load (pre-`register()`). */
|
|
125
|
+
markModuleDiscovered(id: string): void;
|
|
126
|
+
/**
|
|
127
|
+
* Record that a module's `register()` succeeded. `capabilities` is the diff of
|
|
128
|
+
* the registry's capability ids across the module's `register()` (what THIS
|
|
129
|
+
* module added), produced by `diffCapabilityIds(before, after)` in the loader.
|
|
130
|
+
*/
|
|
131
|
+
markModuleActivated(id: string, capabilities: PluginCapabilityIds): void;
|
|
132
|
+
/** Record that a module failed during a register-phase `phase`. */
|
|
133
|
+
markModuleFailed(id: string, phase: string): void;
|
|
134
|
+
/** Live lifecycle record for one module id, or `undefined` if never seen. */
|
|
135
|
+
pluginRecord(id: string): PluginRecord | undefined;
|
|
136
|
+
/** All live lifecycle records, in load order. */
|
|
137
|
+
pluginRecords(): PluginRecord[];
|
|
55
138
|
get channels(): ChannelAdapter[];
|
|
56
139
|
get channelCommands(): ChannelCommand[];
|
|
140
|
+
/**
|
|
141
|
+
* OUTBOUND messaging adapters declared via `b.channelMessaging(id, adapter)`,
|
|
142
|
+
* shaped `{ id, messaging }` so the boot can hand them straight to
|
|
143
|
+
* `syncChannelMessagingAdaptersFromPlugins(...)`. Parallel to `channels`.
|
|
144
|
+
*/
|
|
145
|
+
get channelMessagingAdapters(): {
|
|
146
|
+
id: string;
|
|
147
|
+
messaging: ChannelMessagingAdapter;
|
|
148
|
+
}[];
|
|
149
|
+
/**
|
|
150
|
+
* SUPPLEMENTARY security adapters declared via `b.channelSecurity(id, adapter)`,
|
|
151
|
+
* shaped `{ id, security }` so the boot can hand them straight to
|
|
152
|
+
* `syncChannelSecurityAdaptersFromPlugins(...)`. Parallel to `channels`.
|
|
153
|
+
*/
|
|
154
|
+
get channelSecurityAdapters(): {
|
|
155
|
+
id: string;
|
|
156
|
+
security: ChannelSecurityAdapter;
|
|
157
|
+
}[];
|
|
57
158
|
get speechProviders(): SpeechProvider[];
|
|
58
159
|
get transcriptionProviders(): TranscriptionProvider[];
|
|
59
160
|
get mediaGenProviders(): MediaGenProvider[];
|
|
@@ -181,4 +282,12 @@ export declare class BrigadeExtensionRegistry {
|
|
|
181
282
|
sessionKey?: string;
|
|
182
283
|
}): ExtensionFactory;
|
|
183
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Diff two capability-id snapshots (`before`/`after` a single module's
|
|
287
|
+
* `register()`), returning ONLY the ids the module added. Multiset-aware per
|
|
288
|
+
* kind: if `before` had one `web_search` tool and `after` has two, the new one
|
|
289
|
+
* is attributed. Used by the loader to attribute capabilities to the module that
|
|
290
|
+
* registered them for its `PluginRecord`.
|
|
291
|
+
*/
|
|
292
|
+
export declare function diffCapabilityIds(before: PluginCapabilityIds, after: PluginCapabilityIds): PluginCapabilityIds;
|
|
184
293
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/agents/extensions/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,eAAe,EAAoB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EACX,uBAAuB,EACvB,cAAc,EACd,cAAc,EAEd,oBAAoB,EAEpB,SAAS,EACT,WAAW,EACX,gBAAgB,EAEhB,8BAA8B,EAC9B,OAAO,EACP,cAAc,EAEd,qBAAqB,EACrB,MAAM,YAAY,CAAC;AAEpB,wEAAwE;AACxE,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,aAAa,CAAC;IACtB,yFAAyF;IACzF,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,qBAAa,wBAAwB;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmC;IACrE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAwC;IAC/E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqC;IAChE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAqC;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqC;IAC/D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4C;IAC7E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuC;IACnE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4D;IACtF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAmE;IACtG,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmE;IACpG,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA8D;IACpG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwD;IACxF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6D;IAC1F,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4D;IACxF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;IACjE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAC7D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA2C;IAE5E,sFAAsF;IACtF,QAAQ,CAAC,aAAa,EAAE,OAAO,YAAY,EAAE,aAAa,EAAE,CAAM;IAElE,wEAAwE;IACxE,OAAO,CAAC,IAAI,EAAE,mBAAmB,GAAG,uBAAuB;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/agents/extensions/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,31 @@
|
|
|
13
13
|
* Product registrations dedupe by id (last wins) so re-running modules is safe.
|
|
14
14
|
*/
|
|
15
15
|
import { createHookRunner } from "./hook-runner.js";
|
|
16
|
+
function emptyCapabilityIds() {
|
|
17
|
+
return {
|
|
18
|
+
tools: [],
|
|
19
|
+
hooks: [],
|
|
20
|
+
commands: [],
|
|
21
|
+
modelProviders: [],
|
|
22
|
+
channels: [],
|
|
23
|
+
channelCommands: [],
|
|
24
|
+
channelMessagingAdapters: [],
|
|
25
|
+
channelSecurityAdapters: [],
|
|
26
|
+
speechProviders: [],
|
|
27
|
+
transcriptionProviders: [],
|
|
28
|
+
mediaGenProviders: [],
|
|
29
|
+
memoryCapabilities: [],
|
|
30
|
+
contextEngines: [],
|
|
31
|
+
compactionProviders: [],
|
|
32
|
+
agentHarnesses: [],
|
|
33
|
+
webSearchProviders: [],
|
|
34
|
+
webFetchProviders: [],
|
|
35
|
+
integrations: [],
|
|
36
|
+
services: [],
|
|
37
|
+
httpRoutes: [],
|
|
38
|
+
gatewayMethods: [],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
16
41
|
export class BrigadeExtensionRegistry {
|
|
17
42
|
toolRegs = [];
|
|
18
43
|
hookRegs = [];
|
|
@@ -21,6 +46,10 @@ export class BrigadeExtensionRegistry {
|
|
|
21
46
|
providerAuthMethodRegs = [];
|
|
22
47
|
channelMap = new Map();
|
|
23
48
|
channelCommandMap = new Map();
|
|
49
|
+
/** OUTBOUND messaging adapters declared on a channel slot, keyed by lowercased channel id. */
|
|
50
|
+
channelMessagingMap = new Map();
|
|
51
|
+
/** SUPPLEMENTARY security adapters declared on a channel slot, keyed by lowercased channel id. */
|
|
52
|
+
channelSecurityMap = new Map();
|
|
24
53
|
speechMap = new Map();
|
|
25
54
|
transcriptionMap = new Map();
|
|
26
55
|
mediaGenMap = new Map();
|
|
@@ -37,6 +66,13 @@ export class BrigadeExtensionRegistry {
|
|
|
37
66
|
gatewayMethodMap = new Map();
|
|
38
67
|
/** Modules that successfully registered — the loader fills this (used for reload). */
|
|
39
68
|
loadedModules = [];
|
|
69
|
+
/**
|
|
70
|
+
* Per-module runtime lifecycle records (FIX 4). The loader populates these as
|
|
71
|
+
* it registers each module: `discovered` before `register()`, then `activated`
|
|
72
|
+
* (with attributed capabilities) or `failed`. Insertion-ordered (Map) so the
|
|
73
|
+
* CLI renders them in load order. Read via `pluginRecord(id)` / `pluginRecords()`.
|
|
74
|
+
*/
|
|
75
|
+
pluginRecordMap = new Map();
|
|
40
76
|
/** Build the recording context a module's `register(b)` writes into. */
|
|
41
77
|
context(meta) {
|
|
42
78
|
return {
|
|
@@ -87,6 +123,21 @@ export class BrigadeExtensionRegistry {
|
|
|
87
123
|
// case-insensitive dispatch (both sides use lowercase).
|
|
88
124
|
this.channelCommandMap.set(command.name.toLowerCase(), command);
|
|
89
125
|
},
|
|
126
|
+
channelMessaging: (channelId, adapter) => {
|
|
127
|
+
// Lowercase the key so it agrees with the channel-messaging registry's
|
|
128
|
+
// case-insensitive lookup (which normalizes the same way). A blank id
|
|
129
|
+
// is dropped — the registry would reject it anyway.
|
|
130
|
+
const id = channelId.trim().toLowerCase();
|
|
131
|
+
if (id)
|
|
132
|
+
this.channelMessagingMap.set(id, adapter);
|
|
133
|
+
},
|
|
134
|
+
channelSecurity: (channelId, adapter) => {
|
|
135
|
+
// Lowercase the key so it agrees with the channel-security registry's
|
|
136
|
+
// case-insensitive lookup. A blank id is dropped.
|
|
137
|
+
const id = channelId.trim().toLowerCase();
|
|
138
|
+
if (id)
|
|
139
|
+
this.channelSecurityMap.set(id, adapter);
|
|
140
|
+
},
|
|
90
141
|
tts: (provider) => {
|
|
91
142
|
this.speechMap.set(provider.id, provider);
|
|
92
143
|
},
|
|
@@ -133,6 +184,71 @@ export class BrigadeExtensionRegistry {
|
|
|
133
184
|
},
|
|
134
185
|
};
|
|
135
186
|
}
|
|
187
|
+
/* ── plugin lifecycle records (FIX 4) ── */
|
|
188
|
+
/**
|
|
189
|
+
* Snapshot the FULL set of currently-registered capability ids, grouped by
|
|
190
|
+
* kind. The loader takes one of these BEFORE a module's `register()` and one
|
|
191
|
+
* AFTER, then diffs them to attribute the newly-registered ids to that module
|
|
192
|
+
* (see `diffCapabilityIds`). Pure read.
|
|
193
|
+
*/
|
|
194
|
+
capabilitySnapshot() {
|
|
195
|
+
return {
|
|
196
|
+
tools: this.toolRegs
|
|
197
|
+
.map((t) => (t.tool ? t.tool.name : t.factory?.create({ agentId: "", sessionKey: "" }).name))
|
|
198
|
+
.filter((n) => typeof n === "string"),
|
|
199
|
+
hooks: this.hookRegs.map((h) => h.event),
|
|
200
|
+
commands: this.commandRegs.map((c) => c.name),
|
|
201
|
+
modelProviders: this.modelProviderRegs.map((p) => p.name),
|
|
202
|
+
channels: [...this.channelMap.keys()],
|
|
203
|
+
channelCommands: [...this.channelCommandMap.keys()],
|
|
204
|
+
channelMessagingAdapters: [...this.channelMessagingMap.keys()],
|
|
205
|
+
channelSecurityAdapters: [...this.channelSecurityMap.keys()],
|
|
206
|
+
speechProviders: [...this.speechMap.keys()],
|
|
207
|
+
transcriptionProviders: [...this.transcriptionMap.keys()],
|
|
208
|
+
mediaGenProviders: [...this.mediaGenMap.keys()],
|
|
209
|
+
memoryCapabilities: [...this.memoryMap.keys()],
|
|
210
|
+
contextEngines: [...this.contextEngineMap.keys()],
|
|
211
|
+
compactionProviders: [...this.compactionProviderMap.keys()],
|
|
212
|
+
agentHarnesses: [...this.agentHarnessMap.keys()],
|
|
213
|
+
webSearchProviders: [...this.webSearchMap.keys()],
|
|
214
|
+
webFetchProviders: [...this.webFetchMap.keys()],
|
|
215
|
+
integrations: [...this.integrationMap.keys()],
|
|
216
|
+
services: [...this.serviceMap.keys()],
|
|
217
|
+
httpRoutes: [...this.httpRouteMap.keys()],
|
|
218
|
+
gatewayMethods: [...this.gatewayMethodMap.keys()],
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/** Record that a module was selected to load (pre-`register()`). */
|
|
222
|
+
markModuleDiscovered(id) {
|
|
223
|
+
this.pluginRecordMap.set(id, { id, status: "discovered", capabilities: emptyCapabilityIds() });
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Record that a module's `register()` succeeded. `capabilities` is the diff of
|
|
227
|
+
* the registry's capability ids across the module's `register()` (what THIS
|
|
228
|
+
* module added), produced by `diffCapabilityIds(before, after)` in the loader.
|
|
229
|
+
*/
|
|
230
|
+
markModuleActivated(id, capabilities) {
|
|
231
|
+
this.pluginRecordMap.set(id, { id, status: "activated", capabilities });
|
|
232
|
+
}
|
|
233
|
+
/** Record that a module failed during a register-phase `phase`. */
|
|
234
|
+
markModuleFailed(id, phase) {
|
|
235
|
+
const prev = this.pluginRecordMap.get(id);
|
|
236
|
+
this.pluginRecordMap.set(id, {
|
|
237
|
+
id,
|
|
238
|
+
status: "failed",
|
|
239
|
+
failurePhase: phase,
|
|
240
|
+
capabilities: prev?.capabilities ?? emptyCapabilityIds(),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
/** Live lifecycle record for one module id, or `undefined` if never seen. */
|
|
244
|
+
pluginRecord(id) {
|
|
245
|
+
const r = this.pluginRecordMap.get(id);
|
|
246
|
+
return r ? clonePluginRecord(r) : undefined;
|
|
247
|
+
}
|
|
248
|
+
/** All live lifecycle records, in load order. */
|
|
249
|
+
pluginRecords() {
|
|
250
|
+
return [...this.pluginRecordMap.values()].map(clonePluginRecord);
|
|
251
|
+
}
|
|
136
252
|
/* ── product-level getters (the gateway consumes these) ── */
|
|
137
253
|
get channels() {
|
|
138
254
|
return [...this.channelMap.values()];
|
|
@@ -140,6 +256,22 @@ export class BrigadeExtensionRegistry {
|
|
|
140
256
|
get channelCommands() {
|
|
141
257
|
return [...this.channelCommandMap.values()];
|
|
142
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* OUTBOUND messaging adapters declared via `b.channelMessaging(id, adapter)`,
|
|
261
|
+
* shaped `{ id, messaging }` so the boot can hand them straight to
|
|
262
|
+
* `syncChannelMessagingAdaptersFromPlugins(...)`. Parallel to `channels`.
|
|
263
|
+
*/
|
|
264
|
+
get channelMessagingAdapters() {
|
|
265
|
+
return [...this.channelMessagingMap.entries()].map(([id, messaging]) => ({ id, messaging }));
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* SUPPLEMENTARY security adapters declared via `b.channelSecurity(id, adapter)`,
|
|
269
|
+
* shaped `{ id, security }` so the boot can hand them straight to
|
|
270
|
+
* `syncChannelSecurityAdaptersFromPlugins(...)`. Parallel to `channels`.
|
|
271
|
+
*/
|
|
272
|
+
get channelSecurityAdapters() {
|
|
273
|
+
return [...this.channelSecurityMap.entries()].map(([id, security]) => ({ id, security }));
|
|
274
|
+
}
|
|
143
275
|
get speechProviders() {
|
|
144
276
|
return [...this.speechMap.values()];
|
|
145
277
|
}
|
|
@@ -509,4 +641,44 @@ function filterByAllowDeny(candidates, allow, deny) {
|
|
|
509
641
|
return true;
|
|
510
642
|
});
|
|
511
643
|
}
|
|
644
|
+
/** Deep-ish clone of a PluginRecord so callers can't mutate the registry's copy. */
|
|
645
|
+
function clonePluginRecord(r) {
|
|
646
|
+
const caps = {};
|
|
647
|
+
for (const key of Object.keys(r.capabilities)) {
|
|
648
|
+
caps[key] = [...r.capabilities[key]];
|
|
649
|
+
}
|
|
650
|
+
return {
|
|
651
|
+
id: r.id,
|
|
652
|
+
status: r.status,
|
|
653
|
+
...(r.failurePhase !== undefined ? { failurePhase: r.failurePhase } : {}),
|
|
654
|
+
capabilities: caps,
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Diff two capability-id snapshots (`before`/`after` a single module's
|
|
659
|
+
* `register()`), returning ONLY the ids the module added. Multiset-aware per
|
|
660
|
+
* kind: if `before` had one `web_search` tool and `after` has two, the new one
|
|
661
|
+
* is attributed. Used by the loader to attribute capabilities to the module that
|
|
662
|
+
* registered them for its `PluginRecord`.
|
|
663
|
+
*/
|
|
664
|
+
export function diffCapabilityIds(before, after) {
|
|
665
|
+
const out = {};
|
|
666
|
+
for (const key of Object.keys(after)) {
|
|
667
|
+
const beforeCounts = new Map();
|
|
668
|
+
for (const id of before[key])
|
|
669
|
+
beforeCounts.set(id, (beforeCounts.get(id) ?? 0) + 1);
|
|
670
|
+
const added = [];
|
|
671
|
+
for (const id of after[key]) {
|
|
672
|
+
const remaining = beforeCounts.get(id) ?? 0;
|
|
673
|
+
if (remaining > 0) {
|
|
674
|
+
beforeCounts.set(id, remaining - 1); // consumed a pre-existing one
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
added.push(id);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
out[key] = added;
|
|
681
|
+
}
|
|
682
|
+
return out;
|
|
683
|
+
}
|
|
512
684
|
//# sourceMappingURL=registry.js.map
|