@herjarsa/omo-meta-governor 0.1.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.
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Cross-system memory aggregator for MetaGovernor.
3
+ *
4
+ * PR 2 of 8. Reads from all three memory systems (agentmemory, magic-context,
5
+ * boulder-state) in parallel and returns a `MemoryRead` that conforms to the
6
+ * PR 1 contract (types.ts).
7
+ *
8
+ * Design choices:
9
+ * - Parallel reads with per-source timeouts. No sequential I/O.
10
+ * - Graceful degrade: a failing source does NOT fail the whole read.
11
+ * It populates `degradedSources[]` (string tags per the contract) and
12
+ * the caller (`score()`) can decide the policy.
13
+ * - Lessons are sorted by confidence DESC. Slots by label. Tasks by priority
14
+ * ASC then recency DESC.
15
+ * - Result is bounded: respects `limits`.
16
+ * - Per-source error messages are stored separately (`errorMessages`) for
17
+ * debugging but NOT in the contract type (the contract only has the string tags).
18
+ *
19
+ * Future PRs that wire this:
20
+ * - PR 3 (closed-loop): calls `aggregateRead()` from `observeErrorAndLearn`
21
+ * and `preflightCheck`.
22
+ * - PR 5 (score): calls `aggregateRead()` to build `lessonsRelevant` slice
23
+ * of `DecisionContext`.
24
+ * - PR 6 (post-repair): calls `aggregateRead()` after a fix to verify.
25
+ *
26
+ * Internal raw types (Lesson, Crystal, Slot, BoulderTask) are defined here
27
+ * as private interfaces representing what each backend actually returns.
28
+ * The aggregator maps them to the contract types from types.ts.
29
+ */
30
+ import type { MemoryRead, MemorySource } from "./types";
31
+ interface RawLesson {
32
+ readonly id: string;
33
+ readonly title: string;
34
+ readonly content: string;
35
+ readonly type: string;
36
+ readonly concepts: readonly string[];
37
+ readonly confidence: number;
38
+ readonly files: readonly string[];
39
+ }
40
+ interface RawCrystal {
41
+ readonly id: string;
42
+ readonly title: string;
43
+ readonly content: string;
44
+ readonly type: string;
45
+ readonly concepts: readonly string[];
46
+ readonly confidence: number;
47
+ readonly files: readonly string[];
48
+ }
49
+ interface RawSlot {
50
+ readonly label: string;
51
+ readonly content: string;
52
+ readonly pinned?: boolean;
53
+ readonly scope?: string;
54
+ readonly sizeLimit?: number;
55
+ readonly updatedAt?: number;
56
+ }
57
+ interface RawBoulderTask {
58
+ readonly id: string;
59
+ readonly title: string;
60
+ readonly priority: number;
61
+ readonly status: string;
62
+ readonly description: string;
63
+ readonly createdAtMs: number;
64
+ readonly updatedAtMs: number;
65
+ }
66
+ export interface AgentmemoryBackend {
67
+ smartSearch(input: {
68
+ query: string;
69
+ limit?: number;
70
+ }): Promise<{
71
+ lessons: RawLesson[];
72
+ crystals: RawCrystal[];
73
+ }>;
74
+ }
75
+ export interface MagicContextBackend {
76
+ slotList(input: {
77
+ directory?: string;
78
+ labelPrefix?: string;
79
+ }): Promise<RawSlot[]>;
80
+ }
81
+ export interface BoulderStateBackend {
82
+ boulderRead(input: {
83
+ directory: string;
84
+ sessionID: string;
85
+ query?: string;
86
+ }): Promise<RawBoulderTask[]>;
87
+ }
88
+ export interface AggregateReadInput {
89
+ /** Working directory. Scopes the read. */
90
+ readonly directory: string;
91
+ /** Session ID. Used for boulder-state keying. */
92
+ readonly sessionID: string;
93
+ /** Natural-language query. Passed to agentmemory (semantic) and boulder. */
94
+ readonly query: string;
95
+ /** Result-size bounds. */
96
+ readonly limits?: {
97
+ readonly maxLessons?: number;
98
+ readonly maxSlots?: number;
99
+ readonly maxTasks?: number;
100
+ };
101
+ /** Per-source timeout in ms. Default 2000 for agentmemory (network), 1000 for local. */
102
+ readonly timeouts?: {
103
+ readonly agentmemoryMs?: number;
104
+ readonly magicContextMs?: number;
105
+ readonly boulderStateMs?: number;
106
+ };
107
+ }
108
+ export interface AggregateReadResult extends MemoryRead {
109
+ /** Wall-clock duration of the whole read, in ms. */
110
+ readonly durationMs: number;
111
+ /** Per-source error messages (for debugging; not in the contract type). */
112
+ readonly errorMessages: Partial<Record<MemorySource, string>>;
113
+ }
114
+ export interface Backends {
115
+ agentmemory: AgentmemoryBackend;
116
+ magicContext: MagicContextBackend;
117
+ boulderState: BoulderStateBackend;
118
+ }
119
+ /**
120
+ * Read from all three memory systems in parallel. Never throws — a failing
121
+ * source populates `degradedSources` and the read still returns a valid result.
122
+ */
123
+ export declare function aggregateRead(input: AggregateReadInput, backends: Backends): Promise<AggregateReadResult>;
124
+ export {};
@@ -0,0 +1,33 @@
1
+ /**
2
+ * MetaGovernor Orchestrator — PR 7 of 8.
3
+ *
4
+ * Unified pipeline integrating all 6 prior modules:
5
+ * - Memory Aggregator (PR 2): parallel reads from 3 memory systems
6
+ * - Token Predictor (PR 4): burn rate + context pressure estimation
7
+ * - Scoring Engine (PR 5): weighted evidence scoring → action decision
8
+ * - Decision Handler (PR 6): dispatch + history tracking + force-continue
9
+ * - Closed-Loop Learning (PR 3): lesson persistence for future sessions
10
+ *
11
+ * Architecture:
12
+ * - Pure pipeline: input → memory → predict → score → decide → learn → output
13
+ * - Each stage is independently testable and DI-friendly
14
+ * - Graceful degradation: if any module throws, returns partial output with skipped=true
15
+ */
16
+ import type { DecisionContext, MemoryRead, MetaGovernorInput, MetaGovernorOutput, OrchestratorConfig } from "./types";
17
+ export declare const defaultOrchestratorConfig: () => OrchestratorConfig;
18
+ /**
19
+ * Build a DecisionContext from orchestrator input + memory read.
20
+ * Exported for direct testing.
21
+ */
22
+ export declare function buildDecisionContext(input: MetaGovernorInput, memoryRead?: MemoryRead): DecisionContext;
23
+ /**
24
+ * Run the full MetaGovernor pipeline.
25
+ *
26
+ * 1. Read memory via aggregator
27
+ * 2. Predict token pressure (skipped if no usage data)
28
+ * 3. Build DecisionContext + score
29
+ * 4. Dispatch decision
30
+ * 5. Learn from outcome
31
+ * 6. Return unified output
32
+ */
33
+ export declare function runMetaGovernor(input: MetaGovernorInput, config?: Partial<OrchestratorConfig>): Promise<MetaGovernorOutput>;
@@ -0,0 +1,23 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ import type { AgentmemoryWriteBackend, MemoryBackends } from "./types";
3
+ /**
4
+ * Dependencies required by the MetaGovernor plugin.
5
+ * All are optional — features degrade gracefully when backends are unavailable.
6
+ */
7
+ export interface MetaGovernorPluginDeps {
8
+ /** Backends for reading memory (agentmemory, magic-context, boulder-state). Optional — degrades gracefully. */
9
+ backends?: MemoryBackends;
10
+ /** Backend for writing lessons/decisions back to agentmemory. Optional — degrades gracefully. */
11
+ writeBackend?: AgentmemoryWriteBackend;
12
+ /** Provider ID for the current session (for token predictor). */
13
+ providerID?: () => string | undefined;
14
+ /** Model ID for the current session (for token predictor). */
15
+ modelID?: () => string | undefined;
16
+ }
17
+ /**
18
+ * Create a MetaGovernor plugin that registers a `tool.execute.after` hook.
19
+ *
20
+ * The plugin observes every tool call, runs the MetaGovernor pipeline,
21
+ * and dispatches decisions (continue/warn/escalate/stop).
22
+ */
23
+ export declare function createMetaGovernorPlugin(deps?: MetaGovernorPluginDeps): Plugin;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Post-Repair Recorder for MetaGovernor — PR 9 of 9.
3
+ *
4
+ * After each recovery hook repairs an error, this module records the
5
+ * outcome into agentmemory. This ensures the MetaGovernor learns from
6
+ * recovery attempts across sessions.
7
+ *
8
+ * Architecture invariants:
9
+ * - DI: AgentmemoryWriteBackend injected via function parameter.
10
+ * - No-op when backend is null (graceful degradation).
11
+ * - Bypasses observeAndLearn() to preserve custom severity/category.
12
+ * - Success → leve deviation (low severity, lesson saved for pattern).
13
+ * - Failure → grave deviation (high severity, lesson saved as bug).
14
+ */
15
+ import type { AgentmemoryWriteBackend, ClosedLoopConfig, LearnFromOutcomeOutput } from "./types";
16
+ import { defaultClosedLoopConfig } from "./closed-loop-learning";
17
+ /**
18
+ * Outcome of a recovery hook repair attempt.
19
+ */
20
+ export interface RecoveryOutcome {
21
+ /** Error code or category (e.g. "TOOL_TIMEOUT", "JSON_PARSE_ERROR"). */
22
+ readonly errorCode: string;
23
+ /** Recovery strategy used (e.g. "retry", "fallback", "compact"). */
24
+ readonly fixStrategy: string;
25
+ /** Whether the repair succeeded. */
26
+ readonly success: boolean;
27
+ /** Session ID where the repair happened. */
28
+ readonly sessionID: string;
29
+ /** Directory context. */
30
+ readonly directory: string;
31
+ /** Files changed during the repair, if any. */
32
+ readonly filesChanged?: readonly string[];
33
+ /** Additional context about the error. */
34
+ readonly context?: string;
35
+ }
36
+ /**
37
+ * Record a recovery outcome to agentmemory.
38
+ *
39
+ * This bypasses observeAndLearn() to preserve custom severity and category
40
+ * from the recovery outcome (observeAndLearn hardcodes severity: "media").
41
+ *
42
+ * When `writeBackend` is null, this is a silent no-op.
43
+ */
44
+ export declare function recordRecovery(outcome: RecoveryOutcome, writeBackend: AgentmemoryWriteBackend | null, options?: {
45
+ config?: ClosedLoopConfig;
46
+ }): Promise<LearnFromOutcomeOutput | null>;
47
+ export { defaultClosedLoopConfig };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * MetaGovernor Scoring Engine — PR 5 of 8.
3
+ *
4
+ * The core decision engine. Takes a DecisionContext (built from signals
5
+ * gathered by the memory-aggregator, token-predictor, and hooks) and
6
+ * produces a Decision via weighted evidence scoring.
7
+ *
8
+ * Architecture invariants:
9
+ * - Pure function: no side effects, no I/O, no MCP calls
10
+ * - Deterministic: same input → same output (no randomness)
11
+ * - All thresholds configurable via ScoringConfig
12
+ * - Paralysis prevention: N consecutive stops → force continue with warning
13
+ * - Cite-or-abstain: evidence required when action !== "continue" silently
14
+ *
15
+ * Score ranges (default thresholds):
16
+ * >= +0.3 → continue silently
17
+ * [-0.3, +0.3] → continue with log
18
+ * [-0.6, -0.3] → warn
19
+ * [-0.8, -0.6] → escalate
20
+ * < -0.8 → stop
21
+ */
22
+ import type { DecisionContext, ScoringConfig, ScoringResult } from "./types";
23
+ export declare const defaultScoringConfig: () => ScoringConfig;
24
+ /**
25
+ * Core scoring function. Pure, deterministic, no side effects.
26
+ *
27
+ * @param ctx - DecisionContext assembled from all signal sources
28
+ * @param config - Scoring thresholds (defaults if omitted)
29
+ * @returns ScoringResult with Decision, evidence breakdown, and metadata
30
+ */
31
+ export declare function score(ctx: DecisionContext, config?: Partial<ScoringConfig>): ScoringResult;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Token Predictor for MetaGovernor.
3
+ *
4
+ * PR 4 of 8. Computes token burn rate from recent turn metrics and recommends
5
+ * preemptive actions (compact, switch model, delegate) before context window
6
+ * exhaustion.
7
+ *
8
+ * Design:
9
+ * - Pure function with no I/O — takes input, returns prediction.
10
+ * - Configurable thresholds via TokenPredictorConfig.
11
+ * - Burn rate = avg tokens/turn over sliding window.
12
+ * - Overflow prediction: budgetLeft / burnRate = turns left.
13
+ * - Recommendations layered: compact-now > switch-model > delegate > no-action.
14
+ */
15
+ import type { TokenPredictorConfig, TokenPredictorInput, TokenPredictorOutput } from "./types";
16
+ /**
17
+ * Default configuration for the token predictor.
18
+ */
19
+ export declare function defaultTokenPredictorConfig(): TokenPredictorConfig;
20
+ /**
21
+ * Calculate burn rate (avg tokens/turn) from recent turn tokens.
22
+ * Returns 0 if no turns provided.
23
+ */
24
+ export declare function calculateBurnRate(recentTurnTokens: readonly number[]): number;
25
+ /**
26
+ * Core prediction function. Analyzes recent turn tokens and recommends
27
+ * an action to prevent context window exhaustion.
28
+ */
29
+ export declare function predict(input: TokenPredictorInput): TokenPredictorOutput;