@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.
- package/README.md +43 -0
- package/dist/closed-loop-learning.d.ts +32 -0
- package/dist/config.d.ts +50 -0
- package/dist/decision-handler.d.ts +35 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +1049 -0
- package/dist/memory-aggregator.d.ts +124 -0
- package/dist/orchestrator.d.ts +33 -0
- package/dist/plugin.d.ts +23 -0
- package/dist/post-repair-recorder.d.ts +47 -0
- package/dist/scoring-engine.d.ts +31 -0
- package/dist/token-predictor.d.ts +29 -0
- package/dist/types.d.ts +476 -0
- package/package.json +38 -0
|
@@ -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>;
|
package/dist/plugin.d.ts
ADDED
|
@@ -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;
|