@herjarsa/omo-meta-governor 0.9.3 → 0.9.8
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/package.json +1 -1
- package/dist/closed-loop-learning.d.ts +0 -32
- package/dist/config-file.d.ts +0 -71
- package/dist/config.d.ts +0 -79
- package/dist/decision-handler.d.ts +0 -35
- package/dist/decision-store.d.ts +0 -36
- package/dist/file-logger.d.ts +0 -1
- package/dist/generate-schema.d.ts +0 -45
- package/dist/graph-sync.d.ts +0 -90
- package/dist/index.d.ts +0 -40
- package/dist/index.js +0 -23
- package/dist/index.js.map +0 -25
- package/dist/memory-aggregator.d.ts +0 -124
- package/dist/orchestrator.d.ts +0 -33
- package/dist/plugin.d.ts +0 -14
- package/dist/post-repair-recorder.d.ts +0 -47
- package/dist/protocol-enforcer.d.ts +0 -33
- package/dist/scoring-engine.d.ts +0 -31
- package/dist/token-predictor.d.ts +0 -29
- package/dist/types.d.ts +0 -552
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Closed-loop learning for MetaGovernor.
|
|
3
|
-
*
|
|
4
|
-
* PR 3 of 8. After every repair/action cycle, observeAndLearn() decides
|
|
5
|
-
* whether to persist a lesson or decision record to agentmemory. Future
|
|
6
|
-
* sessions retrieve these via aggregateRead() (PR 2) and factor them into
|
|
7
|
-
* scoring (PR 5).
|
|
8
|
-
*
|
|
9
|
-
* Design:
|
|
10
|
-
* - Pure function with DI backend (no side effects without backend).
|
|
11
|
-
* - config.enabled=false → returns no-op with reason.
|
|
12
|
-
* - Severity threshold: minSeverityToLearn filters what gets saved.
|
|
13
|
-
* - Session cap: maxLessonsPerSession prevents flooding.
|
|
14
|
-
* - Lessons go to agentmemory_memory_save (type: "pattern").
|
|
15
|
-
* - Decisions go to agentmemory_memory_save (type: "fact").
|
|
16
|
-
* - No file I/O, no MCP calls — just decision logic + DI write.
|
|
17
|
-
*/
|
|
18
|
-
import type { AgentmemoryWriteBackend, ClosedLoopConfig, LearnFromOutcomeInput, LearnFromOutcomeOutput } from "./types";
|
|
19
|
-
/** Severity ordering for threshold comparison. */
|
|
20
|
-
declare const SEVERITY_ORDER: Record<string, number>;
|
|
21
|
-
/**
|
|
22
|
-
* Core learning function. Decides whether to save a lesson and/or decision
|
|
23
|
-
* to agentmemory based on the outcome of a repair/action cycle.
|
|
24
|
-
*
|
|
25
|
-
* Returns LearnFromOutcomeOutput describing what was saved (or why nothing was saved).
|
|
26
|
-
*/
|
|
27
|
-
export declare function observeAndLearn(input: LearnFromOutcomeInput, backend: AgentmemoryWriteBackend): Promise<LearnFromOutcomeOutput>;
|
|
28
|
-
/**
|
|
29
|
-
* Helper: create a default ClosedLoopConfig.
|
|
30
|
-
*/
|
|
31
|
-
export declare function defaultClosedLoopConfig(): ClosedLoopConfig;
|
|
32
|
-
export { SEVERITY_ORDER };
|
package/dist/config-file.d.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSONC config file loader for omo-meta-governor.
|
|
3
|
-
*
|
|
4
|
-
* Loads `omo-meta-governor.jsonc` from three layers (closer wins):
|
|
5
|
-
* 1. CLI inline options (opts object) — highest priority
|
|
6
|
-
* 2. Project config: `.opencode/omo-meta-governor.jsonc`
|
|
7
|
-
* 3. User config: `~/.config/opencode/omo-meta-governor.jsonc`
|
|
8
|
-
* 4. Defaults — lowest priority
|
|
9
|
-
*
|
|
10
|
-
* JSONC support: comments (//, /* * /) and trailing commas are stripped
|
|
11
|
-
* before parsing. The raw JSON object is then projected into
|
|
12
|
-
* `MetaGovernorPluginConfig` via `loadOrchestratorConfig()`.
|
|
13
|
-
*/
|
|
14
|
-
import type { MetaGovernorPluginConfig } from "./config";
|
|
15
|
-
/**
|
|
16
|
-
* Strip JSONC comments (single-line // style and multi-line bracket style)
|
|
17
|
-
* and trailing commas from a JSONC string so it can be parsed by JSON.parse.
|
|
18
|
-
*
|
|
19
|
-
* Handles:
|
|
20
|
-
* - // single-line comments
|
|
21
|
-
* - /asterisk ... asterisk/ multi-line comments
|
|
22
|
-
* - Trailing commas before ] or }
|
|
23
|
-
* - Strings containing comments (preserved)
|
|
24
|
-
*/
|
|
25
|
-
export declare function stripJsoncComments(jsonc: string): string;
|
|
26
|
-
/**
|
|
27
|
-
* Parse a JSONC string into a JavaScript object.
|
|
28
|
-
* Returns undefined on parse failure.
|
|
29
|
-
*/
|
|
30
|
-
export declare function parseJsonc<T = Record<string, unknown>>(jsonc: string): T | undefined;
|
|
31
|
-
/**
|
|
32
|
-
* Get the user-level config file path.
|
|
33
|
-
*/
|
|
34
|
-
export declare function getUserConfigPath(): string;
|
|
35
|
-
/**
|
|
36
|
-
* Get the project-level config file path for a given project directory.
|
|
37
|
-
*/
|
|
38
|
-
export declare function getProjectConfigPath(projectDir?: string): string;
|
|
39
|
-
/**
|
|
40
|
-
* Read and parse a single JSONC config file.
|
|
41
|
-
* Returns undefined if the file does not exist or is unparseable.
|
|
42
|
-
*/
|
|
43
|
-
export declare function loadJsoncFile<T = Record<string, unknown>>(filePath: string): Promise<T | undefined>;
|
|
44
|
-
/**
|
|
45
|
-
* Deep-merge two config objects. Arrays are replaced (not concatenated).
|
|
46
|
-
* The `source` values win when both exist.
|
|
47
|
-
* Mutually recursive with mergeArrays=false for sub-objects.
|
|
48
|
-
*/
|
|
49
|
-
export declare function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T;
|
|
50
|
-
export interface ConfigFileSources {
|
|
51
|
-
/** CLI inline options (highest priority) */
|
|
52
|
-
cliOptions?: Partial<MetaGovernorPluginConfig>;
|
|
53
|
-
/** Project directory for project-level config lookup */
|
|
54
|
-
projectDir?: string;
|
|
55
|
-
}
|
|
56
|
-
export interface ConfigFileResult {
|
|
57
|
-
/** The merged MetaGovernorPluginConfig */
|
|
58
|
-
config: Partial<MetaGovernorPluginConfig>;
|
|
59
|
-
/** Which source files were loaded */
|
|
60
|
-
sources: string[];
|
|
61
|
-
/** Which source was the effective highest-priority non-empty source */
|
|
62
|
-
effectiveSource: "cli" | "project" | "user" | "defaults";
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Load the MetaGovernor config from all available sources with priority:
|
|
66
|
-
* CLI inline > project `.opencode/omo-meta-governor.jsonc` >
|
|
67
|
-
* user `~/.config/opencode/omo-meta-governor.jsonc` > defaults
|
|
68
|
-
*
|
|
69
|
-
* Higher-priority sources override lower-priority ones.
|
|
70
|
-
*/
|
|
71
|
-
export declare function loadMetaGovernorConfig(sources?: ConfigFileSources): Promise<ConfigFileResult>;
|
package/dist/config.d.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { ModelOverrideConfig, OrchestratorConfig } from "./types";
|
|
2
|
-
import type { ConfigFileSources } from "./config-file";
|
|
3
|
-
/**
|
|
4
|
-
* MetaGovernor config schema exposed to users.
|
|
5
|
-
* This is a Zod-free config interface since Zod parsing is optional
|
|
6
|
-
* in the standalone plugin — the user provides JSON, we coerce with defaults.
|
|
7
|
-
*/
|
|
8
|
-
export interface MetaGovernorPluginConfig {
|
|
9
|
-
/** Master feature flag — must be true to run the orchestrator. */
|
|
10
|
-
enabled?: boolean;
|
|
11
|
-
/** Decision handler (PR 6) */
|
|
12
|
-
decision?: {
|
|
13
|
-
maxHistoryPerSession?: number;
|
|
14
|
-
forceContinueAfterStops?: number;
|
|
15
|
-
};
|
|
16
|
-
/** Memory aggregator (PR 2) */
|
|
17
|
-
memory?: {
|
|
18
|
-
agentmemoryTimeoutMs?: number;
|
|
19
|
-
magicContextTimeoutMs?: number;
|
|
20
|
-
boulderStateTimeoutMs?: number;
|
|
21
|
-
query?: string;
|
|
22
|
-
};
|
|
23
|
-
/** Token predictor (PR 4) */
|
|
24
|
-
tokenPredictor?: {
|
|
25
|
-
compactBurnRateThreshold?: number;
|
|
26
|
-
compactUsageThreshold?: number;
|
|
27
|
-
switchModelUsageThreshold?: number;
|
|
28
|
-
delegateConsecutiveHighBurn?: number;
|
|
29
|
-
};
|
|
30
|
-
/** Scoring engine (PR 5) */
|
|
31
|
-
scoring?: {
|
|
32
|
-
continueThreshold?: number;
|
|
33
|
-
warnThreshold?: number;
|
|
34
|
-
escalateThreshold?: number;
|
|
35
|
-
stopThreshold?: number;
|
|
36
|
-
};
|
|
37
|
-
/** Closed-loop learning (PR 3) */
|
|
38
|
-
closedLoop?: {
|
|
39
|
-
saveDecisions?: boolean;
|
|
40
|
-
saveLessons?: boolean;
|
|
41
|
-
};
|
|
42
|
-
/** Model override for MetaGovernor internal LLM usage. */
|
|
43
|
-
modelOverride?: ModelOverrideConfig;
|
|
44
|
-
/** Intervention config for visible decision injection. */
|
|
45
|
-
intervention?: {
|
|
46
|
-
mode?: "silent" | "message" | "system";
|
|
47
|
-
includeDecisionHistory?: boolean;
|
|
48
|
-
maxHistoryMessages?: number;
|
|
49
|
-
minActionForMessage?: "warn" | "escalate" | "stop";
|
|
50
|
-
};
|
|
51
|
-
/** Sisyphus protocol enforcement config. */
|
|
52
|
-
protocolEnforcement?: {
|
|
53
|
-
enabled?: boolean;
|
|
54
|
-
path?: string;
|
|
55
|
-
injectIntoSystem?: boolean;
|
|
56
|
-
auditToolCalls?: boolean;
|
|
57
|
-
};
|
|
58
|
-
/** Graph sync config for auto-initializing codegraph/graphify. */
|
|
59
|
-
graphSync?: {
|
|
60
|
-
enabled?: boolean;
|
|
61
|
-
watch?: boolean;
|
|
62
|
-
autoInstall?: boolean;
|
|
63
|
-
installTimeoutMs?: number;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Project the full MetaGovernorPluginConfig into OrchestratorConfig.
|
|
68
|
-
* Missing sub-configs fall back to module defaults.
|
|
69
|
-
*/
|
|
70
|
-
export declare function loadOrchestratorConfig(pluginConfig: Partial<MetaGovernorPluginConfig> | undefined): OrchestratorConfig;
|
|
71
|
-
/**
|
|
72
|
-
* Check whether the MetaGovernor is enabled. Returns false if config is undefined.
|
|
73
|
-
*/
|
|
74
|
-
export declare function isMetaGovernorEnabled(config: MetaGovernorPluginConfig | undefined): boolean;
|
|
75
|
-
/**
|
|
76
|
-
* Load orchestrator config from all available sources: config file (JSONC)
|
|
77
|
-
* with priority: CLI inline > project config > user config > defaults.
|
|
78
|
-
*/
|
|
79
|
-
export declare function loadOrchestratorConfigFromSources(sources?: ConfigFileSources): Promise<OrchestratorConfig>;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MetaGovernor Decision Handler — PR 6 of 8.
|
|
3
|
-
*
|
|
4
|
-
* Takes a ScoringResult from the scoring engine and dispatches to the
|
|
5
|
-
* appropriate action: continue, warn, escalate, or stop. This is the
|
|
6
|
-
* "executor" that translates scoring decisions into concrete outcomes.
|
|
7
|
-
*
|
|
8
|
-
* Architecture invariants:
|
|
9
|
-
* - Pure dispatch: no I/O, no MCP calls, no side effects
|
|
10
|
-
* - DI pattern: backends injected via DecisionHandlerConfig
|
|
11
|
-
* - Audit trail: every decision + outcome recorded in DecisionHistory
|
|
12
|
-
* - Configurable: all thresholds and behaviors overridable
|
|
13
|
-
*/
|
|
14
|
-
import type { DecisionHandlerConfig, DecisionHandlerInput, DecisionHandlerOutput } from "./types";
|
|
15
|
-
export declare const defaultDecisionHandlerConfig: () => DecisionHandlerConfig;
|
|
16
|
-
/**
|
|
17
|
-
* Core decision handler. Takes a ScoringResult and dispatches to the
|
|
18
|
-
* appropriate action. Pure function — no side effects.
|
|
19
|
-
*
|
|
20
|
-
* @param input - ScoringResult + session context
|
|
21
|
-
* @param config - Handler configuration
|
|
22
|
-
* @returns DecisionHandlerOutput with action taken + message + history entry
|
|
23
|
-
*/
|
|
24
|
-
export declare function handleDecision(input: DecisionHandlerInput, config?: Partial<DecisionHandlerConfig>): DecisionHandlerOutput;
|
|
25
|
-
/**
|
|
26
|
-
* Trim history to max size. Returns trimmed array + entries dropped count.
|
|
27
|
-
*/
|
|
28
|
-
export declare function trimHistory(history: readonly DecisionHandlerOutput["historyEntry"][], maxSize: number): {
|
|
29
|
-
trimmed: DecisionHandlerOutput["historyEntry"][];
|
|
30
|
-
dropped: number;
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* Count consecutive stops in history (most recent first).
|
|
34
|
-
*/
|
|
35
|
-
export declare function countConsecutiveStops(history: readonly DecisionHandlerOutput["historyEntry"][]): number;
|
package/dist/decision-store.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MetaGovernor decision store — in-memory Map for intervention feature.
|
|
3
|
-
*
|
|
4
|
-
* Stores decisions produced by tool.execute.after so they can be
|
|
5
|
-
* consumed by experimental.chat.messages.transform and
|
|
6
|
-
* experimental.chat.system.transform hooks.
|
|
7
|
-
*
|
|
8
|
-
* The store is keyed by sessionID. For hooks that receive a sessionID
|
|
9
|
-
* (system.transform), use takeDecision(sessionID). For hooks that
|
|
10
|
-
* receive no sessionID (messages.transform), use takeAnyDecision().
|
|
11
|
-
*/
|
|
12
|
-
import type { DecisionHandlerOutput } from "./types";
|
|
13
|
-
/**
|
|
14
|
-
* Store a decision for a session.
|
|
15
|
-
* Overwrites any previous pending decision for the same session.
|
|
16
|
-
*/
|
|
17
|
-
export declare function storeDecision(sessionID: string, decision: DecisionHandlerOutput): void;
|
|
18
|
-
/**
|
|
19
|
-
* Take (retrieve and remove) the pending decision for a session.
|
|
20
|
-
* Returns undefined if no decision is pending.
|
|
21
|
-
*/
|
|
22
|
-
export declare function takeDecision(sessionID: string): DecisionHandlerOutput | undefined;
|
|
23
|
-
/**
|
|
24
|
-
* Check whether a session has a pending decision without consuming it.
|
|
25
|
-
*/
|
|
26
|
-
export declare function hasDecision(sessionID: string): boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Take any pending decision across all sessions.
|
|
29
|
-
* Useful for hooks that do not receive a sessionID.
|
|
30
|
-
* Returns the first pending decision found, or undefined if none.
|
|
31
|
-
*/
|
|
32
|
-
export declare function takeAnyDecision(): DecisionHandlerOutput | undefined;
|
|
33
|
-
/**
|
|
34
|
-
* Clear all stored decisions. Useful in tests or when a session ends.
|
|
35
|
-
*/
|
|
36
|
-
export declare function clearAll(): void;
|
package/dist/file-logger.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function logToFile(level: "info" | "warn" | "error", message: string, data?: unknown): void;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON Schema generator for omo-meta-governor.jsonc.
|
|
3
|
-
*
|
|
4
|
-
* Generates a JSON Schema (draft-07) from the MetaGovernorPluginConfig
|
|
5
|
-
* interface definition. The schema is used for IDE autocompletion and
|
|
6
|
-
* validation when editing the .jsonc config file.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* import { generateSchema } from "./generate-schema"
|
|
10
|
-
* const schema = generateSchema()
|
|
11
|
-
* await Bun.write("assets/omo-meta-governor.schema.json", JSON.stringify(schema, null, 2))
|
|
12
|
-
*/
|
|
13
|
-
export interface JsonSchema {
|
|
14
|
-
$schema: string;
|
|
15
|
-
$id: string;
|
|
16
|
-
title: string;
|
|
17
|
-
description: string;
|
|
18
|
-
type: "object";
|
|
19
|
-
properties: Record<string, JsonSchemaProperty>;
|
|
20
|
-
additionalProperties: boolean;
|
|
21
|
-
definitions?: Record<string, JsonSchemaProperty>;
|
|
22
|
-
}
|
|
23
|
-
export interface JsonSchemaProperty {
|
|
24
|
-
type?: string | string[];
|
|
25
|
-
description?: string;
|
|
26
|
-
default?: unknown;
|
|
27
|
-
properties?: Record<string, JsonSchemaProperty>;
|
|
28
|
-
items?: JsonSchemaProperty;
|
|
29
|
-
additionalProperties?: boolean;
|
|
30
|
-
required?: string[];
|
|
31
|
-
enum?: string[];
|
|
32
|
-
oneOf?: JsonSchemaProperty[];
|
|
33
|
-
anyOf?: JsonSchemaProperty[];
|
|
34
|
-
$ref?: string;
|
|
35
|
-
minimum?: number;
|
|
36
|
-
maximum?: number;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Generate the full JSON Schema for the omo-meta-governor.jsonc config file.
|
|
40
|
-
*/
|
|
41
|
-
export declare function generateSchema(): JsonSchema;
|
|
42
|
-
/**
|
|
43
|
-
* Write the schema to a file.
|
|
44
|
-
*/
|
|
45
|
-
export declare function writeSchemaFile(outputPath: string): Promise<void>;
|
package/dist/graph-sync.d.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* graphSync — Auto-initialize codegraph and graphify for a project.
|
|
3
|
-
*
|
|
4
|
-
* On first session in a project, checks whether:
|
|
5
|
-
* - `npx codegraph` is available on PATH (or node_modules)
|
|
6
|
-
* - `graphify` / `graphifyy` is available as a Python package
|
|
7
|
-
*
|
|
8
|
-
* If a tool is available but the project has no index yet, runs the
|
|
9
|
-
* initialization automatically. With `--watch` mode, spawns a background
|
|
10
|
-
* process that re-indexes on file changes.
|
|
11
|
-
*
|
|
12
|
-
* Architecture invariants:
|
|
13
|
-
* - Never blocks the session — init runs async, best-effort
|
|
14
|
-
* - Never throws — all errors are silently caught and logged
|
|
15
|
-
* - Tracks session init once per project via an in-memory Set
|
|
16
|
-
*/
|
|
17
|
-
export interface GraphSyncConfig {
|
|
18
|
-
/** Enable auto-initialization. Default: true */
|
|
19
|
-
enabled: boolean;
|
|
20
|
-
/** Enable watch mode (re-index on file changes). Default: false */
|
|
21
|
-
watch: boolean;
|
|
22
|
-
/** Project directory to initialize in. Default: cwd */
|
|
23
|
-
projectDir?: string;
|
|
24
|
-
/**
|
|
25
|
-
* Auto-install missing backends. Default: true.
|
|
26
|
-
* - codegraph: installed via `npm i -D @colbymchenry/codegraph` in the project
|
|
27
|
-
* - graphify: installed via `pip install graphifyy --break-system-packages` (or `uv tool install graphifyy`)
|
|
28
|
-
*/
|
|
29
|
-
autoInstall: boolean;
|
|
30
|
-
/** Max ms to wait for each install. Default: 60_000 */
|
|
31
|
-
installTimeoutMs: number;
|
|
32
|
-
}
|
|
33
|
-
export type InstallCode = "codegraph-installed" | "codegraph-install-failed" | "codegraph-install-skipped" | "graphify-installed" | "graphify-install-failed" | "graphify-install-skipped";
|
|
34
|
-
/**
|
|
35
|
-
* Install codegraph via `npm i -D @colbymchenry/codegraph`.
|
|
36
|
-
* Best-effort, never throws.
|
|
37
|
-
*/
|
|
38
|
-
export declare function installCodegraph(projectDir: string, timeoutMs?: number): Promise<InstallCode>;
|
|
39
|
-
/**
|
|
40
|
-
* Install graphify via `pip install graphifyy --break-system-packages`.
|
|
41
|
-
* Falls back to `uv tool install graphifyy`.
|
|
42
|
-
* Best-effort, never throws.
|
|
43
|
-
*/
|
|
44
|
-
export declare function installGraphify(timeoutMs?: number): Promise<InstallCode>;
|
|
45
|
-
export declare function resetInitializedProjects(): void;
|
|
46
|
-
/**
|
|
47
|
-
* Track a new session for a project. Increments reference count.
|
|
48
|
-
* Returns the new count.
|
|
49
|
-
*/
|
|
50
|
-
export declare function trackSession(projectDir: string): number;
|
|
51
|
-
/**
|
|
52
|
-
* Untrack a session for a project. Decrements reference count.
|
|
53
|
-
* When count drops to 0, all watch processes for that project
|
|
54
|
-
* are automatically stopped.
|
|
55
|
-
* Returns the remaining count.
|
|
56
|
-
*/
|
|
57
|
-
export declare function untrackSession(projectDir: string): number;
|
|
58
|
-
/** Get active session count for a project. */
|
|
59
|
-
export declare function getSessionCount(projectDir: string): number;
|
|
60
|
-
export interface ToolAvailability {
|
|
61
|
-
/** Whether codegraph is available (via npx or node_modules) */
|
|
62
|
-
codegraph: boolean;
|
|
63
|
-
/** Whether graphify/graphifyy is available (via pip) */
|
|
64
|
-
graphify: boolean;
|
|
65
|
-
/** Whether .codegraph/ directory already exists in the project */
|
|
66
|
-
codegraphIndexExists: boolean;
|
|
67
|
-
/** Whether graphify-out/ directory already exists in the project */
|
|
68
|
-
graphifyIndexExists: boolean;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Stop all active watch processes for a project.
|
|
72
|
-
*/
|
|
73
|
-
export declare function stopWatches(projectDir?: string): void;
|
|
74
|
-
/** Check if watches are active for a project. */
|
|
75
|
-
export declare function hasActiveWatcher(projectDir: string, tool?: "codegraph" | "graphify"): boolean;
|
|
76
|
-
export interface GraphSyncResult {
|
|
77
|
-
/** Whether synchronization was attempted */
|
|
78
|
-
attempted: boolean;
|
|
79
|
-
/** Codes that describe the outcome */
|
|
80
|
-
codes: GraphSyncCode[];
|
|
81
|
-
/** Tool availability before init */
|
|
82
|
-
availability: ToolAvailability;
|
|
83
|
-
/** Whether this project was already initialized this session */
|
|
84
|
-
alreadyInitialized: boolean;
|
|
85
|
-
}
|
|
86
|
-
export type GraphSyncCode = "codegraph-initialized" | "codegraph-already-exists" | "codegraph-unavailable" | "codegraph-install-failed" | "codegraph-install-skipped" | "graphify-initialized" | "graphify-already-exists" | "graphify-unavailable" | "graphify-install-failed" | "graphify-install-skipped" | "watch-started-codegraph" | "watch-started-graphify" | "disabled" | "error";
|
|
87
|
-
/**
|
|
88
|
-
* Run the graphSync pipeline. Best-effort, never throws.
|
|
89
|
-
*/
|
|
90
|
-
export declare function runGraphSync(config?: GraphSyncConfig): Promise<GraphSyncResult>;
|
package/dist/index.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { PluginModule } from "@opencode-ai/plugin";
|
|
2
|
-
/**
|
|
3
|
-
* @sisyphuslabs/omo-meta-governor — Self-judging agent orchestration layer.
|
|
4
|
-
*
|
|
5
|
-
* Default export is an OpenCode PluginModule that registers a
|
|
6
|
-
* `tool.execute.after` hook. The MetaGovernor reads session signals,
|
|
7
|
-
* scores them against weighted evidence, and dispatches decisions.
|
|
8
|
-
*
|
|
9
|
-
* Install:
|
|
10
|
-
* npm install @sisyphuslabs/omo-meta-governor
|
|
11
|
-
*
|
|
12
|
-
* Configure:
|
|
13
|
-
* ```jsonc
|
|
14
|
-
* {
|
|
15
|
-
* "meta_governor": {
|
|
16
|
-
* "enabled": true
|
|
17
|
-
* }
|
|
18
|
-
* }
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
declare const pluginModule: PluginModule;
|
|
22
|
-
export default pluginModule;
|
|
23
|
-
export { createMetaGovernorPlugin, type MetaGovernorPluginDeps } from "./plugin";
|
|
24
|
-
export { logToFile } from "./file-logger";
|
|
25
|
-
export { runMetaGovernor, buildDecisionContext, defaultOrchestratorConfig, } from "./orchestrator";
|
|
26
|
-
export { loadOrchestratorConfig, isMetaGovernorEnabled, type MetaGovernorPluginConfig, } from "./config";
|
|
27
|
-
export { score, defaultScoringConfig } from "./scoring-engine";
|
|
28
|
-
export { predict, defaultTokenPredictorConfig, calculateBurnRate } from "./token-predictor";
|
|
29
|
-
export { handleDecision, defaultDecisionHandlerConfig, trimHistory, countConsecutiveStops } from "./decision-handler";
|
|
30
|
-
export { observeAndLearn, defaultClosedLoopConfig } from "./closed-loop-learning";
|
|
31
|
-
export { aggregateRead } from "./memory-aggregator";
|
|
32
|
-
export { recordRecovery, type RecoveryOutcome } from "./post-repair-recorder";
|
|
33
|
-
export { storeDecision, takeDecision, hasDecision, takeAnyDecision, clearAll, } from "./decision-store";
|
|
34
|
-
export type { Decision, DecisionContext, DecisionHandlerConfig, DecisionHandlerInput, DecisionHandlerOutput, Deviation, Evidence, EvidenceContribution, InterventionConfig, InterventionMode, LearnFromOutcomeInput, LearnFromOutcomeOutput, MemoryRead, MemoryBackends, AgentmemoryWriteBackend, MetaGovernorInput, MetaGovernorOutput, OrchestratorConfig, ScoringConfig, ScoringResult, SlotMemory, TokenPredictorConfig, TokenPredictorInput, TokenPredictorOutput, ClosedLoopConfig, } from "./types";
|
|
35
|
-
export { loadProtocol, buildSystemInjection, auditToolCall, DEFAULT_PROTOCOL_PATH, } from "./protocol-enforcer";
|
|
36
|
-
export { stripJsoncComments, parseJsonc, loadJsoncFile, deepMerge, loadMetaGovernorConfig, getUserConfigPath, getProjectConfigPath, type ConfigFileSources, type ConfigFileResult, } from "./config-file";
|
|
37
|
-
export { runGraphSync, stopWatches, resetInitializedProjects, type GraphSyncConfig, type GraphSyncResult, type GraphSyncCode, type ToolAvailability, } from "./graph-sync";
|
|
38
|
-
export { generateSchema, writeSchemaFile, type JsonSchema, type JsonSchemaProperty } from "./generate-schema";
|
|
39
|
-
export { loadOrchestratorConfigFromSources } from "./config";
|
|
40
|
-
export type { ProtocolViolation, ProtocolEnforcementSessionState } from "./types";
|
package/dist/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import{createRequire as rK}from"node:module";var dK=Object.defineProperty;var uK=(K)=>K;function lK(K,Q){this[K]=uK.bind(null,Q)}var aK=(K,Q)=>{for(var X in Q)dK(K,X,{get:Q[X],enumerable:!0,configurable:!0,set:lK.bind(Q,X)})};var cK=(K,Q)=>()=>(K&&(Q=K(K=0)),Q);var GK=rK(import.meta.url);var DK={};aK(DK,{stripJsoncComments:()=>QK,parseJsonc:()=>XK,loadMetaGovernorConfig:()=>IK,loadJsoncFile:()=>f,getUserConfigPath:()=>ZK,getProjectConfigPath:()=>$K,deepMerge:()=>b});import{readFile as TQ,access as bQ}from"node:fs/promises";import{resolve as yK}from"node:path";import{homedir as jQ}from"node:os";function QK(K){let Q=[],X=0;while(X<K.length){let $=K[X];if($==='"'||$==="'"){let J=$;Q.push(J),X++;while(X<K.length){let q=K[X];if(Q.push(q),q==="\\"){if(X++,X<K.length)Q.push(K[X])}else if(q===J){X++;break}X++}continue}if($==="/"&&X+1<K.length&&K[X+1]==="/"){X+=2;while(X<K.length&&K[X]!==`
|
|
2
|
-
`)X++;continue}if($==="/"&&X+1<K.length&&K[X+1]==="*"){X+=2;while(X<K.length){if(K[X]==="*"&&X+1<K.length&&K[X+1]==="/"){X+=2;break}X++}continue}Q.push($),X++}let Z=Q.join("");for(let $=0;$<10;$++){let J=Z;if(Z=Z.replace(/,(\s*[\]}])/g,"$1"),Z===J)break}return Z}function XK(K){try{let Q=QK(K);return JSON.parse(Q)}catch{return}}function ZK(){return yK(jQ(),".config","opencode",xK)}function $K(K){let Q=K??process.cwd();return yK(Q,".opencode",xK)}async function CQ(K){try{return await bQ(K),!0}catch{return!1}}async function f(K){if(!await CQ(K))return;try{let Q=await TQ(K,"utf-8");return XK(Q)}catch{return}}function b(K,Q){let X={...K};for(let Z of Object.keys(Q)){let $=Q[Z],J=X[Z];if($===void 0)continue;if(CK($)&&CK(J))X[Z]=b(J,$);else X[Z]=$}return X}function CK(K){return typeof K==="object"&&K!==null&&!Array.isArray(K)}async function IK(K={}){let Q=[],X="defaults",Z={},$=ZK(),J=await f($);if(J)Z=b(Z,J),Q.push(`user:${$}`),X="user";let q=$K(K.projectDir),B=await f(q);if(B)Z=b(Z,B),Q.push(`project:${q}`),X="project";if(K.cliOptions&&Object.keys(K.cliOptions).length>0)Z=b(Z,K.cliOptions),Q.push("cli:inline"),X="cli";return{config:Z,sources:Q,effectiveSource:X}}var xK="omo-meta-governor.jsonc";var JK=()=>{};import{execSync as M,spawn as FK}from"node:child_process";import{access as nK,stat as sK}from"node:fs/promises";import{resolve as D}from"node:path";import{constants as iK}from"node:fs";async function tK(K,Q=60000){try{return M("npm i -D @colbymchenry/codegraph",{cwd:K,stdio:"ignore",timeout:Q}),"codegraph-installed"}catch{return"codegraph-install-failed"}}async function oK(K=60000){try{return M("pip install graphifyy --break-system-packages --quiet",{stdio:"ignore",timeout:K}),"graphify-installed"}catch{try{return M("uv tool install graphifyy --quiet",{stdio:"ignore",timeout:K}),"graphify-installed"}catch{return"graphify-install-failed"}}}var d=new Set;function eK(){d.clear()}var _K=new Map;function PK(K){let X=(_K.get(K)??0)+1;return _K.set(K,X),X}async function wK(K){let Q=!1,X=!1,Z=await LK(D(K,".codegraph")),$=await LK(D(K,"graphify-out"));try{M("npx --yes codegraph --version",{stdio:"ignore",timeout:1e4}),Q=!0}catch{try{M("node node_modules/.bin/codegraph --version",{cwd:K,stdio:"ignore",timeout:5000}),Q=!0}catch{}}try{M("python3 -c 'import graphify; print(graphify.__version__)'",{stdio:"ignore",timeout:5000}),X=!0}catch{try{M("python3 -c 'import graphifyy; print(graphifyy.__version__)'",{stdio:"ignore",timeout:5000}),X=!0}catch{}}return{codegraph:Q,graphify:X,codegraphIndexExists:Z,graphifyIndexExists:$}}async function KQ(K){let Q=D(K,".codegraph");await MK(Q);try{M("npx --yes codegraph init",{cwd:K,stdio:"ignore",timeout:60000})}catch{}}async function QQ(K){let Q=D(K,"graphify-out");await MK(Q);try{M("python3 -m graphify . --no-viz",{cwd:K,stdio:"ignore",timeout:120000})}catch{try{M("graphifyy . --no-viz",{cwd:K,stdio:"ignore",timeout:120000})}catch{}}}var y=new Map;function AK(K,Q){let X=`${K}:${Q}`;if(y.has(X))return;try{let Z;if(Q==="codegraph")Z=FK("node",["-e",`
|
|
3
|
-
const {execSync} = require("child_process");
|
|
4
|
-
const run = () => {
|
|
5
|
-
try { execSync("npx codegraph update 2>/dev/null", {cwd: ${JSON.stringify(K)}, stdio: "ignore"}); }
|
|
6
|
-
catch(e) { /* best effort */ }
|
|
7
|
-
};
|
|
8
|
-
run();
|
|
9
|
-
setInterval(run, 30_000);
|
|
10
|
-
`],{stdio:"ignore",detached:!0});else Z=FK("python3",["-m","graphify",".","--no-viz","--watch"],{cwd:K,stdio:"ignore",detached:!0});Z.unref(),y.set(X,{process:Z,tool:Q}),Z.on("exit",()=>{y.delete(X)})}catch{}}function XQ(K){for(let[Q,X]of y)if(!K||Q.startsWith(K)){try{X.process.kill("SIGTERM")}catch{}setTimeout(()=>{try{X.process.kill("SIGKILL")}catch{}},2000).unref(),y.delete(Q)}}async function u(K={enabled:!0,watch:!1,autoInstall:!0,installTimeoutMs:60000}){let Q=[],X=K.projectDir??process.cwd();if(!K.enabled)return{attempted:!1,codes:["disabled"],availability:{codegraph:!1,graphify:!1,codegraphIndexExists:!1,graphifyIndexExists:!1},alreadyInitialized:!1};if(d.has(X)){let $=await wK(X);return{attempted:!1,codes:$.codegraphIndexExists?["codegraph-already-exists"]:[],availability:$,alreadyInitialized:!0}}d.add(X);let Z;try{Z=await wK(X)}catch{return{attempted:!1,codes:["error"],availability:{codegraph:!1,graphify:!1,codegraphIndexExists:!1,graphifyIndexExists:!1},alreadyInitialized:!1}}if(K.autoInstall!==!1){if(!Z.codegraph){let $=await tK(X,K.installTimeoutMs??60000);if(Q.push($),$==="codegraph-installed")Z.codegraph=!0}if(!Z.graphify){let $=await oK(K.installTimeoutMs??60000);if(Q.push($),$==="graphify-installed")Z.graphify=!0}}else{if(!Z.codegraph)Q.push("codegraph-install-skipped");if(!Z.graphify)Q.push("graphify-install-skipped")}if(Z.codegraph)if(!Z.codegraphIndexExists)try{await KQ(X),Q.push("codegraph-initialized")}catch{Q.push("error")}else Q.push("codegraph-already-exists");else Q.push("codegraph-unavailable");if(Z.graphify)if(!Z.graphifyIndexExists)try{await QQ(X),Q.push("graphify-initialized")}catch{Q.push("error")}else Q.push("graphify-already-exists");else Q.push("graphify-unavailable");if(K.watch){if(Z.codegraph)AK(X,"codegraph"),Q.push("watch-started-codegraph");if(Z.graphify)AK(X,"graphify"),Q.push("watch-started-graphify")}return{attempted:!0,codes:Q,availability:Z,alreadyInitialized:!1}}async function LK(K){try{return(await sK(K)).isDirectory()}catch{return!1}}async function MK(K){try{await nK(K,iK.F_OK)}catch{let{mkdir:Q}=await import("node:fs/promises");await Q(K,{recursive:!0})}}var OK={limits:{maxLessons:10,maxSlots:20,maxTasks:10},timeouts:{agentmemoryMs:2000,magicContextMs:1000,boulderStateMs:1000}};async function r(K,Q){let X=performance.now(),Z={...OK.limits,...K.limits},$={...OK.timeouts,...K.timeouts},[J,q,B]=await Promise.allSettled([ZQ(K,Q.agentmemory,Z,$.agentmemoryMs),$Q(K,Q.magicContext,Z,$.magicContextMs),JQ(K,Q.boulderState,Z,$.boulderStateMs)]),V=[],W={},z=J.status==="fulfilled"?J.value:(a(V,W,"agentmemory",l(J.reason)),c.agentmemory),U=q.status==="fulfilled"?q.value:(a(V,W,"magicContext",l(q.reason)),c.magicContext),H=B.status==="fulfilled"?B.value:(a(V,W,"boulderState",l(B.reason)),c.boulderState);return{query:K.query,timestampISO:new Date().toISOString(),agentmemory:z,magicContext:U,boulderState:H,degradedSources:V,durationMs:performance.now()-X,errorMessages:W}}async function ZQ(K,Q,X,Z){let $=await n(Q.smartSearch({query:K.query,limit:X.maxLessons}),Z,"agentmemory");return{available:!0,lessons:qQ($.lessons).slice(0,X.maxLessons).map((q)=>({id:q.id,title:q.title,advice:"info",confidence:q.confidence,concepts:q.concepts}))}}async function $Q(K,Q,X,Z){return{available:!0,slots:(await n(Q.slotList({directory:K.directory}),Z,"magicContext")).filter((J)=>J.label.startsWith("meta_governor:")||zQ(J,K.query)).sort((J,q)=>J.label.localeCompare(q.label)).slice(0,X.maxSlots).map((J)=>({label:J.label,content:J.content}))}}async function JQ(K,Q,X,Z){let $=await n(Q.boulderRead({directory:K.directory,sessionID:K.sessionID,query:K.query}),Z,"boulderState");return{available:!0,tasks:$.sort((q,B)=>q.priority-B.priority||B.updatedAtMs-q.updatedAtMs).slice(0,X.maxTasks).map((q)=>({id:q.id,status:q.status,title:q.title})),planProgress:BQ($)}}function qQ(K){return[...K].sort((Q,X)=>X.confidence-Q.confidence)}function zQ(K,Q){let X=Q.toLowerCase();return K.label.toLowerCase().includes(X)||K.content.toLowerCase().includes(X)}function BQ(K){if(K.length===0)return 0;return K.filter((X)=>X.status==="done").length/K.length}function l(K){if(K instanceof Error)return K.message;if(typeof K==="string")return K;return"unknown error"}function a(K,Q,X,Z){K.push(X),Q[X]=Z}var c={agentmemory:{available:!1,lessons:[]},magicContext:{available:!1,slots:[]},boulderState:{available:!1,tasks:[],planProgress:0}};async function n(K,Q,X){return new Promise((Z,$)=>{let J=setTimeout(()=>$(Error(`${X} timeout after ${Q}ms`)),Q);K.then((q)=>{clearTimeout(J),Z(q)},(q)=>{clearTimeout(J),$(q)})})}function YQ(){return{compactBurnRateThreshold:500,compactUsageThreshold:0.85,switchModelUsageThreshold:0.95,delegateConsecutiveHighBurn:5,windowSize:10}}function RK(K){if(K.length===0)return 0;return K.reduce((X,Z)=>X+Z,0)/K.length}function VQ(K,Q){let X=0;for(let Z=K.length-1;Z>=0;Z--)if(K[Z]>=Q)X++;else break;return X}function WQ(K,Q,X,Z){let $=Q-K;if($<=0)return Z;if(X<=0)return null;let J=Math.floor($/X);if(J<=0)return Z;let q=J*2;return new Date(new Date(Z).getTime()+q*1000).toISOString()}function s(K){let{currentUsage:Q,modelLimit:X,recentTurnTokens:Z,timestampISO:$,config:J}=K,q=Z.slice(-J.windowSize),B=RK(q),V=X-Q,W=X>0?Q/X:1,z=Math.min(0.95,0.3+q.length/J.windowSize*0.65),U="no-action",H="within normal parameters";if(W>=J.switchModelUsageThreshold)U="switch-model",H=`context usage ${(W*100).toFixed(1)}% exceeds switch threshold ${(J.switchModelUsageThreshold*100).toFixed(1)}%`;if(W>=J.compactUsageThreshold||B>=J.compactBurnRateThreshold){if(U==="no-action")U="compact-now",H=W>=J.compactUsageThreshold?`context usage ${(W*100).toFixed(1)}% exceeds compact threshold ${(J.compactUsageThreshold*100).toFixed(1)}%`:`burn rate ${B.toFixed(0)} tokens/turn exceeds threshold ${J.compactBurnRateThreshold}`}let w=VQ(q,J.compactBurnRateThreshold);if(w>=J.delegateConsecutiveHighBurn&&U==="no-action")U="delegate-to-subagent",H=`${w} consecutive high-burn turns (threshold: ${J.delegateConsecutiveHighBurn})`;let _=WQ(Q,X,B,$);return{currentUsage:Q,burnRate:B,budgetLeft:V,willOverflowAt:_,recommendation:U,confidence:z,modelLimit:X,windowRemaining:Math.max(0,Math.floor(V/Math.max(B,1))),input:{...K},computedAtISO:$,turnsAnalyzed:q.length}}var O={"oracle-verified":0.25,"no-progress-detector":0.2,"deviation-detector":0.2,"iteration-budget":0.15,"lesson-recall":0.1,"token-predictor":0.1},S=()=>({continueThreshold:0.3,warnThreshold:0.3,escalateThreshold:0.6,stopThreshold:0.8,paralysisThreshold:3,defaultEscalationTarget:"oracle"});function UQ(K){let Q=[];Q.push({source:"oracle-verified",rawScore:K.oracleVerified?0.6:0,weight:O["oracle-verified"],weightedScore:K.oracleVerified?0.6*O["oracle-verified"]:0,description:K.oracleVerified?"Oracle verification passed":"No Oracle verification"}),Q.push({source:"no-progress-detector",rawScore:K.noProgress?-0.8:0,weight:O["no-progress-detector"],weightedScore:K.noProgress?-0.8*O["no-progress-detector"]:0,description:K.noProgress?"No progress detected in last turn":"Progress detected"});let X=HQ(K.deviations);Q.push({source:"deviation-detector",rawScore:X,weight:O["deviation-detector"],weightedScore:X*O["deviation-detector"],description:K.deviations.length>0?`${K.deviations.length} deviation(s) detected (worst: ${K.deviations[0].severity})`:"No deviations detected"});let Z=GQ(K.iterationRatio);Q.push({source:"iteration-budget",rawScore:Z,weight:O["iteration-budget"],weightedScore:Z*O["iteration-budget"],description:`Iteration ratio: ${K.iterationRatio.toFixed(2)} (${K.ambient.iteration}/${K.ambient.maxIterations})`});let $=FQ(K.lessonsRelevant);return Q.push({source:"lesson-recall",rawScore:$,weight:O["lesson-recall"],weightedScore:$*O["lesson-recall"],description:K.lessonsRelevant.length>0?`${K.lessonsRelevant.length} relevant lesson(s) (avg confidence: ${_Q(K.lessonsRelevant).toFixed(2)})`:"No relevant lessons"}),Q}function HQ(K){if(K.length===0)return 0;let Q={grave:-0.9,media:-0.5,leve:-0.2},X=0;for(let $ of K){let J=Q[$.severity]??-0.3;if(J<X)X=J}let Z=Math.min(K.length*0.05,0.2);return Math.max(X-Z,-1)}function GQ(K){if(K<=0.5)return-K*0.6;return-0.3-(K-0.5)*1}function FQ(K){if(K.length===0)return 0;let Q=0;for(let X of K)Q+=({continue:0.3,info:0,warn:-0.3,stop:-0.7}[X.advice]??0)*X.confidence;return Math.max(Math.min(Q/K.length,1),-1)}function _Q(K){if(K.length===0)return 0;return K.reduce((Q,X)=>Q+X.confidence,0)/K.length}function wQ(K,Q){if(K>=Q.continueThreshold)return"continue";if(K<=-Q.stopThreshold)return"stop";if(K<=-Q.escalateThreshold)return"escalate";if(K<=-Q.warnThreshold)return"warn";return"continue"}function AQ(K,Q){if(!K.oracleVerified)return"oracle";if(K.deviations.some((X)=>X.severity==="grave"))return"user";return Q.defaultEscalationTarget}function kK(K,Q,X,Z){if(Z)return`Paralysis detected: forced continue despite score ${K.toFixed(3)} (too many consecutive stops)`;let $=[...X].sort((W,z)=>W.weightedScore-z.weightedScore),J=$[0],q=$[$.length-1],B=[];if(J.weightedScore<0)B.push(`primary concern: ${J.description}`);if(q.weightedScore>0)B.push(`positive signal: ${q.description}`);return`${{continue:"Continue",warn:"Warn",escalate:"Escalate",stop:"Stop"}[Q]} (score: ${K.toFixed(3)}): ${B.join("; ")||"balanced signals"}`}function i(K,Q){let X={...S(),...Q},Z=UQ(K),$=Z.reduce((U,H)=>U+H.weightedScore,0),J=Math.max(Math.min($,1),-1),q=K.slotMemory.consecutiveStops>=X.paralysisThreshold&&J<=-X.warnThreshold,B=q?"continue":wQ(J,X),V=[];if(B!=="continue"||Math.abs(J)<X.continueThreshold){for(let U of Z)if(Math.abs(U.weightedScore)>0.01)V.push({source:U.source,value:U.description,confidence:Math.abs(U.rawScore),weight:U.weight});if(V.length===0&&B!=="continue")V.push({source:"ambient",value:kK(J,B,Z,q),confidence:0.5,weight:0.1})}let W=B==="escalate"?AQ(K,X):null;return{decision:{action:B,score:J,reasoning:kK(J,B,Z,q),evidence:V,shouldEscalateTo:W},contributions:Z,rawScore:J,paralysisOverride:q,computedAtISO:new Date().toISOString()}}var v=()=>({enabled:!0,maxHistoryPerSession:50,forceContinueAfterStops:3,warnMessageTemplate:"[MetaGovernor] Score {score}: {reasoning}. Evidence: {evidenceCount} signal(s).",escalateMessageTemplate:"[MetaGovernor] Escalating to {target}: {reasoning}",stopMessageTemplate:"[MetaGovernor] STOP — {reasoning}. Evidence: {evidenceCount} signal(s)."});function h(K,Q){let X=K;for(let[Z,$]of Object.entries(Q))X=X.replaceAll(`{${Z}}`,$);return X}function LQ(K){return K.length}function t(K,Q){let X={...v(),...Q};if(!X.enabled)return{action:"continue",message:null,historyEntry:{decision:K.scoringResult.decision,action:"continue",timestampISO:new Date().toISOString(),sessionID:K.sessionID,reasoning:"Decision handler disabled — pass-through continue"}};let Z=K.scoringResult.decision,$=Z.score,J=Z.reasoning,q=LQ(Z.evidence),B=Z.shouldEscalateTo??X.defaultEscalationTarget??"oracle";if(K.scoringResult.paralysisOverride)return{action:"continue",message:h(X.warnMessageTemplate,{score:$.toFixed(3),reasoning:`Paralysis detected — forced continue. ${J}`,evidenceCount:String(q)}),historyEntry:{decision:Z,action:"continue",timestampISO:new Date().toISOString(),sessionID:K.sessionID,reasoning:`Paralysis override: ${J}`}};switch(Z.action){case"continue":return{action:"continue",message:null,historyEntry:{decision:Z,action:"continue",timestampISO:new Date().toISOString(),sessionID:K.sessionID,reasoning:J}};case"warn":return{action:"warn",message:h(X.warnMessageTemplate,{score:$.toFixed(3),reasoning:J,evidenceCount:String(q)}),historyEntry:{decision:Z,action:"warn",timestampISO:new Date().toISOString(),sessionID:K.sessionID,reasoning:J}};case"escalate":return{action:"escalate",message:h(X.escalateMessageTemplate,{target:B,reasoning:J}),historyEntry:{decision:Z,action:"escalate",timestampISO:new Date().toISOString(),sessionID:K.sessionID,reasoning:`Escalate to ${B}: ${J}`}};case"stop":return{action:"stop",message:h(X.stopMessageTemplate,{reasoning:J,evidenceCount:String(q)}),historyEntry:{decision:Z,action:"stop",timestampISO:new Date().toISOString(),sessionID:K.sessionID,reasoning:J}}}}function PQ(K,Q){if(K.length<=Q)return{trimmed:[...K],dropped:0};let X=K.length-Q;return{trimmed:K.slice(-Q),dropped:X}}function MQ(K){let Q=0;for(let X=K.length-1;X>=0;X--)if(K[X].action==="stop")Q++;else break;return Q}var NK={leve:0,media:1,grave:2};function OQ(K,Q,X){let Z=`${K}-${Q}-${X}`.split("").reduce(($,J)=>($<<5)-$+J.charCodeAt(0)|0,0);return`D-${Math.abs(Z).toString(36)}`}function EK(K,Q){let X=NK[Q]??0;return K.some((Z)=>(NK[Z.severity]??0)>=X)}function RQ(K){let Q=new Set;for(let X of K)Q.add(X.category),Q.add(X.severity);return[...Q]}function kQ(K,Q){let X=Q.map((Z)=>`[${Z.severity}] ${Z.category}: ${Z.detail}`).join("; ");return`Action "${K.action}" (score ${K.score.toFixed(2)}) after deviations: ${X}. Reasoning: ${K.reasoning}`}async function o(K,Q){let{decision:X,config:Z,sessionID:$,directory:J,filesChanged:q}=K,B=new Date().toISOString();if(!Z.enabled)return{lessonSaved:null,decisionSaved:null,reason:"closed-loop learning disabled"};if(X.evidence.length===0&&X.action==="continue")return{lessonSaved:null,decisionSaved:null,reason:"no deviations to learn from"};let V=null,W=null;if(Z.saveDecisions){let H={id:OQ($,X.action,B),timestampISO:B,action:X.action,score:X.score,reasoning:X.reasoning,sessionID:$,directory:J,deviations:X.evidence.filter((w)=>w.source==="deviation-detector").map((w)=>({severity:"media",category:w.source,detail:w.value}))};try{await Q.saveMemory({content:`Decision: ${X.action} (score ${X.score.toFixed(2)}). ${X.reasoning}`,concepts:["meta-governor","decision",X.action],type:"fact",files:[...q]}),W=H}catch{}}let z=X.evidence.filter((H)=>H.source==="deviation-detector").map((H)=>({severity:"media",category:H.source,detail:H.value}));if(EK(z,Z.minSeverityToLearn)){let H=RQ(z),w=kQ(X,z);try{V={id:(await Q.saveLesson({content:w,context:`session:${$} dir:${J}`,confidence:Math.max(0.3,Math.min(0.8,Math.abs(X.score))),tags:H})).id,title:`${X.action} after ${z[0]?.category??"deviation"}`,content:w,type:"pattern",concepts:H,confidence:Math.max(0.3,Math.min(0.8,Math.abs(X.score))),files:[...q],sessionID:$}}catch{}}let U=[];if(W)U.push("decision saved");if(V)U.push("lesson saved");if(!W&&!V)if(!EK(z,Z.minSeverityToLearn))U.push("severity below threshold");else U.push("no saveable content");return{lessonSaved:V,decisionSaved:W,reason:U.join("; ")||"no action taken"}}function N(){return{enabled:!0,minSeverityToLearn:"media",maxLessonsPerSession:20,saveDecisions:!0}}var bK=()=>({enabled:!0,memory:{enabled:!0,query:"",timeoutMs:3000},tokenPredictor:{},scoring:{},decision:{},closedLoop:{},intervention:{mode:"silent",includeDecisionHistory:!0,maxHistoryMessages:5,minActionForMessage:"warn"},protocolEnforcement:{enabled:!1,path:void 0,injectIntoSystem:!1,auditToolCalls:!1}}),e={query:"",timestampISO:new Date().toISOString(),agentmemory:{available:!1,lessons:[]},magicContext:{available:!1,slots:[]},boulderState:{available:!1,tasks:[],planProgress:0},degradedSources:["agentmemory","magicContext","boulderState"]},NQ={consecutiveStops:0,consecutiveContinues:0,lastUpdatedISO:new Date().toISOString()},EQ={action:"continue",message:null,historyEntry:{decision:{action:"continue",score:0,reasoning:"no decision made",evidence:[],shouldEscalateTo:null},action:"continue",timestampISO:new Date().toISOString(),sessionID:"",reasoning:"no decision made"}};function jK(K,Q=e){let X=K.maxIterations>0?K.iteration/K.maxIterations:0,Z={...NQ,consecutiveStops:K.consecutiveStops??0};return{oracleVerified:K.oracleVerified,noProgress:K.noProgress,deviations:K.deviations,iterationRatio:X,lessonsRelevant:Q.agentmemory.lessons,slotMemory:Z,ambient:{sessionID:K.sessionID,directory:".",mode:"simple",agentName:K.agentName??"unknown",iteration:K.iteration,maxIterations:K.maxIterations}}}async function KK(K,Q={}){let X={...bK(),...Q};if(!X.enabled)return{memoryRead:e,tokenPrediction:TK(K),scoringResult:{decision:{action:"continue",score:0,reasoning:"MetaGovernor disabled",evidence:[],shouldEscalateTo:null},contributions:[],rawScore:0,paralysisOverride:!1,computedAtISO:new Date().toISOString()},decision:EQ,lessonSaved:null,decisionHistory:[],skipped:!0,skipReason:"disabled"};let Z=e;if(X.memory.enabled)try{let W={agentmemory:K.backends.agentmemory,magicContext:K.backends.magicContext,boulderState:K.backends.boulderState};Z=await r({directory:".",sessionID:K.sessionID,query:X.memory.query||K.toolName},W)}catch{}let $;try{$=s({currentUsage:K.recentTurnTokens.reduce((W,z)=>W+z,0),modelLimit:K.modelLimit??Q.modelOverride?.modelLimit??200000,recentTurnTokens:K.recentTurnTokens,timestampISO:new Date().toISOString(),providerID:K.providerID??"",modelID:K.modelID??"",config:X.tokenPredictor})}catch{$=TK(K)}let J=i(jK(K,Z),X.scoring),q={sessionID:K.sessionID,scoringResult:J},B=t(q,X.decision),V=null;try{if(X.closedLoop.enabled!==!1)V=await o({decision:B.historyEntry.decision,memoryRead:Z,config:{...N(),...X.closedLoop},sessionID:K.sessionID,directory:".",filesChanged:[]},K.writeBackend)}catch{}return{memoryRead:Z,tokenPrediction:$,scoringResult:J,decision:B,lessonSaved:V,decisionHistory:[B.historyEntry],skipped:!1}}function TK(K){let Q=K.recentTurnTokens.reduce((X,Z)=>X+Z,0);return{burnRate:0,budgetLeft:200000,currentUsage:Q,modelLimit:200000,willOverflowAt:null,recommendation:"no-action",confidence:1,windowRemaining:200000,input:{currentUsage:Q,modelLimit:200000,recentTurnTokens:K.recentTurnTokens,timestampISO:new Date().toISOString(),providerID:K.providerID??"",modelID:K.modelID??"",config:{compactBurnRateThreshold:500,compactUsageThreshold:0.85,switchModelUsageThreshold:0.95,delegateConsecutiveHighBurn:5,windowSize:10}},computedAtISO:new Date().toISOString(),turnsAnalyzed:K.recentTurnTokens.length}}function m(K){let Q={enabled:!1,...K},X=S(),Z=v(),$=N();return{enabled:Q.enabled===!0,memory:{enabled:!0,query:Q.memory?.query??"meta_governor_context",timeoutMs:Q.memory?.agentmemoryTimeoutMs??2000},tokenPredictor:{compactBurnRateThreshold:Q.tokenPredictor?.compactBurnRateThreshold??500,compactUsageThreshold:Q.tokenPredictor?.compactUsageThreshold??0.85,switchModelUsageThreshold:Q.tokenPredictor?.switchModelUsageThreshold??0.95,delegateConsecutiveHighBurn:Q.tokenPredictor?.delegateConsecutiveHighBurn??5},scoring:{...X,...Q.scoring?.continueThreshold!==void 0?{continueThreshold:Q.scoring.continueThreshold}:{},...Q.scoring?.warnThreshold!==void 0?{warnThreshold:Q.scoring.warnThreshold}:{},...Q.scoring?.escalateThreshold!==void 0?{escalateThreshold:Q.scoring.escalateThreshold}:{},...Q.scoring?.stopThreshold!==void 0?{stopThreshold:Q.scoring.stopThreshold}:{}},closedLoop:{...$,...Q.closedLoop?.saveDecisions!==void 0?{saveDecisions:Q.closedLoop.saveDecisions}:{}},decision:{...Z,...Q.decision?.maxHistoryPerSession!==void 0?{maxHistoryPerSession:Q.decision.maxHistoryPerSession}:{},...Q.decision?.forceContinueAfterStops!==void 0?{forceContinueAfterStops:Q.decision.forceContinueAfterStops}:{}},modelOverride:Q.modelOverride?{providerID:Q.modelOverride.providerID,modelID:Q.modelOverride.modelID,modelLimit:Q.modelOverride.modelLimit,temperature:Q.modelOverride.temperature??0.2,topP:Q.modelOverride.topP??1,maxTokens:Q.modelOverride.maxTokens??2048,reasoning:Q.modelOverride.reasoning??!1,verbosity:Q.modelOverride.verbosity??"minimal"}:void 0,intervention:{mode:Q.intervention?.mode??"silent",includeDecisionHistory:Q.intervention?.includeDecisionHistory??!0,maxHistoryMessages:Q.intervention?.maxHistoryMessages??5,minActionForMessage:Q.intervention?.minActionForMessage??"warn"},protocolEnforcement:{enabled:Q.protocolEnforcement?.enabled??!1,path:Q.protocolEnforcement?.path,injectIntoSystem:Q.protocolEnforcement?.injectIntoSystem??!1,auditToolCalls:Q.protocolEnforcement?.auditToolCalls??!1}}}function yQ(K){return K?.enabled===!0}async function xQ(K={}){let{loadMetaGovernorConfig:Q}=await Promise.resolve().then(() => (JK(),DK)),X=await Q(K);return m(X.config)}var E=new Map;function qK(K,Q){E.set(K,Q)}function zK(K){let Q=E.get(K);if(Q!==void 0)E.delete(K);return Q}function IQ(K){return E.has(K)}function BK(){for(let[K,Q]of E)return E.delete(K),Q;return}function DQ(){E.clear()}import{appendFileSync as SQ,mkdirSync as hQ}from"node:fs";import{resolve as vQ,dirname as fQ}from"node:path";import{homedir as mQ}from"node:os";var SK=vQ(mQ(),".config","opencode","meta-governor.log");function gQ(){try{hQ(fQ(SK),{recursive:!0})}catch{}}function j(K,Q,X){gQ();let Z=new Date().toISOString(),$=X!==void 0?` | ${JSON.stringify(X)}`:"",J=`[${Z}] [${K.toUpperCase()}] ${Q}${$}
|
|
11
|
-
`;try{SQ(SK,J)}catch{}if(K==="error")console.error(`[meta-governor] ${Q}`);else if(K==="warn")console.warn(`[meta-governor] ${Q}`);else console.log(`[meta-governor] ${Q}`)}import{statSync as hK}from"node:fs";import{readFile as pQ}from"node:fs/promises";import{resolve as dQ}from"node:path";import{homedir as uQ}from"node:os";var g=dQ(uQ(),".config","opencode","sisyphus-mandatory","sisyphus-mandatory.md");async function YK(K){return await pQ(K??g,"utf-8")}function VK(K){let Q=["","## Sisyphus Protocol Enforcement","","You MUST follow these Sisyphus protocol rules:","","1. **Pre-response Memory Check**: Before any action, read `<project-memory>` and `<session-history-since>` blocks in context. Cite `<memory id>` for any fact used from memory. Do not ask questions whose answers are in those blocks.","","2. **Codebase Graph First**: Before using grep/glob/read for architecture or symbol queries, check whether `.codegraph/` or `graphify-out/` exists. If so, use codegraph/graphify tools first. Fall back to AFT (aft_zoom, aft_outline), then grep/read only as last resort.","","3. **Tool Routing Table**: Match common intents to the correct tool:",' - "we did this before" / "you should know" → `agentmemory_memory_recall`',' - "the usual" / "as configured" → `ctx_memory(action="list")`'," - Starting a task that resembles a previous one → `agentmemory_memory_smart_search`",' - "what changed" / "history" → `ctx_search`'," - Before asking the user a clarifying question → `agentmemory_memory_recall` first"," - Working note for THIS session only → `ctx_note`"," - Save durable insight/decision/rule → `ctx_memory`",""];if(/\boracle\b/i.test(K))Q.push("4. **Post-task Oracle Verification**: If files touched >= 3 OR any INVOKE trigger matches, invoke Oracle with the exact format:",' `task(subagent_type="oracle", run_in_background=false, prompt="Verify: ...")`'," - INVOKE triggers: created 1+ new file, modified abstraction, touched security/auth paths, modified DB/persistence, modified CI/CD, added/removed dependency, modified perf-critical path, todo had 2+ completed items."," - SKIP only when: files touched <= 2, no new file, no dependency change, single-step task, change is typo/comment/rename only."," - Verdict: PASS → done. FAIL/CONDITIONAL → fix and re-invoke. Max 3 invocations."," - Cost: Max 3 oracle invocations per task. Skip rate: Must NOT skip Oracle on 2+ file change.","");return Q.push("5. **Parallel Query Rule**: Fire independent tool queries in the same turn. Do NOT serialize independent memory/context queries.","","6. **Empty-Result Escalation**: On empty `agentmemory_memory_recall`, fire `agentmemory_memory_smart_search` + `ctx_search` + `agentmemory_memory_export` before asking the user.","","7. **Hard Rules (No Exceptions)**:"," - Do NOT ask 'where is X?' if memory or session record already contains it."," - Do NOT claim 'I don't know' before firing at least 2 different recall tools."," - Do NOT re-issue clarifying questions whose answer is in `<project-memory>` or `<session-history-since>`."," - Do NOT use grep/find when aft_outline would answer the structure question."," - Do NOT duplicate a memory in both `agentmemory_memory_save` and `ctx_memory` — pick ONE."," - Do NOT suppress type errors with `as any`, `@ts-ignore`, or `@ts-expect-error`."," - Do NOT leave empty catch blocks `catch(e) {}`.",' - Do NOT start a fresh agent via `task()` when `task(task_id="ses_...")` (continuation) exists — use continuation IDs.'," - Do NOT batch-complete todos — mark each one `completed` immediately after finishing."," - Do NOT skip creating todos for multi-step tasks.","","8. **Self-Check Before Responding**:"," - Verify you read `<project-memory>` and `<session-history-since>` blocks."," - Verify you cited `<memory id>` for any fact used from memory."," - Verify you did not ask a question whose answer is in those blocks."," - For multi-file changes, verify Oracle was invoked."," - For codebase exploration, verify codegraph/graphify was tried before grep/read."," - After discovering something non-obvious, save it with `ctx_memory` so future sessions benefit.",""),Q.join(`
|
|
12
|
-
`)}function WK(K,Q,X){let Z=[],$=X.recentToolCalls??[],J=X.aftAvailable??!1,q=X.aftUsed??!1,B=X.recentWriteContents??[],V=X.memorySaved??!1,W=X.batchCompletions??0;if((K==="grep"||K==="glob")&&(X.hasCodegraphDir||X.hasGraphifyDir)){let _=X.hasCodegraphDir?".codegraph":"graphify-out";Z.push({rule:"codebase-graph-first",tool:K,severity:"media",detail:`Used ${K} when ${_} exists — should use codegraph/graphify first for architecture and symbol queries.`})}if((K==="read"||K==="grep")&&J&&!q)Z.push({rule:"aft-first",tool:K,severity:"media",detail:`AFT tools (aft_outline, aft_zoom) are available but were not tried before using ${K}. Use aft_outline for structure discovery, aft_zoom for symbol source, before falling back to grep/read.`});if(K==="grep"&&J&&!q&&!X.hasCodegraphDir&&!X.hasGraphifyDir)Z.push({rule:"grep-without-aft",tool:K,severity:"leve",detail:"Used grep before checking if aft_outline would answer the structure question. grep is a last resort after graph tools and AFT."});if(K==="task"&&Q&&typeof Q==="object"){let _=Q;if(!_.task_id&&typeof _.prompt==="string"&&$.length>3)Z.push({rule:"continuation-discipline",tool:K,severity:"leve",detail:`Started a new task() without task(task_id="ses_...") continuation ID. Use task_id to preserve the subagent's full context and save tokens.`})}let z=["write","edit","edit_block","desktop-commander_edit_block","desktop-commander_write_file"];if(z.includes(K)){let _=typeof Q==="object"&&Q!==null?JSON.stringify(Q):String(Q??""),L=/@ts-ignore|@ts-expect-error/.test(_),P=/\bas any\b/.test(_);if(L&&P)Z.push({rule:"no-type-suppression",tool:K,severity:"grave",detail:"File write contains both @ts-ignore/@ts-expect-error AND 'as any' — double type suppression. "+"Both are forbidden by the Sisyphus protocol."});else if(L)Z.push({rule:"no-type-suppression",tool:K,severity:"media",detail:"File write contains @ts-ignore or @ts-expect-error — both are forbidden. "+"Fix the underlying type error instead."});else if(P)Z.push({rule:"no-type-suppression",tool:K,severity:"media",detail:"File write contains 'as any' — type suppression forbidden. "+"Use proper type narrowing instead."})}if(z.includes(K)){let _=typeof Q==="object"&&Q!==null?JSON.stringify(Q):String(Q??"");if(/catch\s*\(\s*\w+\s*\)\s*\{\s*\}/.test(_))Z.push({rule:"no-empty-catch",tool:K,severity:"media",detail:"Empty catch block detected — `catch(e) {}` is forbidden. "+"Log the error or handle it gracefully."})}if(["grep","glob","read","aft_zoom","aft_outline","codegraph_explore","graphify query"].includes(K)&&$.length>=2){if(!$.slice(0,5).some((L)=>L.startsWith("ctx_memory"))&&!V)Z.push({rule:"save-discovery-to-memory",tool:K,severity:"leve",detail:`Used ${K} to discover code but ctx_memory was not used afterwards. Save non-obvious findings with ctx_memory so future sessions benefit.`})}if(W>0&&K!=="todowrite")Z.push({rule:"no-batch-todo-completion",tool:K,severity:"leve",detail:"Batch todo completion detected. Each todo must be marked `completed` immediately "+"after finishing — do not batch-complete multiple items."});if(K==="ctx_reduce"&&Q&&typeof Q==="object"){let _=Q.drop;if(typeof _==="string"&&/^\d+-\d+$/i.test(_.trim())){let[L,P]=_.trim().split("-").map(Number);if(!isNaN(L)&&!isNaN(P)&&P-L>10)Z.push({rule:"ctx-reduce-discipline",tool:K,severity:"leve",detail:`Dropped a large range (${_}) with ctx_reduce. The protocol requires reviewing each tag before dropping. Use smaller targeted drops instead of blanket ranges.`})}}if(X.emptyRecall&&!X.escalationAttempted){if(K.startsWith("question")||K==="ask")Z.push({rule:"empty-result-escalation",tool:K,severity:"grave",detail:"Memory recall returned empty but agent did not fire smart_search + ctx_search + export before asking the user. Steps 1-3 of empty-result escalation protocol are mandatory."})}let H=["agentmemory_memory_recall","agentmemory_memory_smart_search","agentmemory_memory_save","ctx_memory","ctx_search","ctx_note"];if(!X.memoryToolsUsed.some((_)=>H.some((L)=>_.startsWith(L)))&&(K.startsWith("question")||K==="ask"))Z.push({rule:"memory-first",tool:K,severity:"grave",detail:"Asked a question without first querying memory (agentmemory or ctx_memory). Must fire agentmemory_memory_recall or ctx_memory before asking the user."});if(X.filesChanged>=3&&!X.oracleInvoked){if(K!=="task"||!Q||typeof Q!=="object"||!("subagent_type"in Q))Z.push({rule:"oracle-verification",tool:K,severity:"media",detail:`Files changed (${X.filesChanged}) >= 3 but Oracle was not invoked. The POST-TASK ORACLE VERIFICATION protocol requires Oracle invocation on multi-file changes.`})}return Z}var vK={continue:0,warn:1,escalate:2,stop:3};function UK(K,Q){return vK[K]>=vK[Q]}function HK(K={},Q={}){let X=process.cwd(),Z=(()=>{try{return hK(`${X}/.codegraph`).isDirectory()}catch{return!1}})(),$=(()=>{try{return hK(`${X}/graphify-out`).isDirectory()}catch{return!1}})();if(K.graphSync?.enabled!==!1)u({enabled:!0,watch:K.graphSync?.watch??!1,autoInstall:K.graphSync?.autoInstall??!0,installTimeoutMs:K.graphSync?.installTimeoutMs??60000,projectDir:X}).catch(()=>{}),PK(X);return j("info","MetaGovernor plugin loaded",{version:"0.9.3",cwd:X,projectHasCodegraph:Z,projectHasGraphify:$}),async(B,V)=>{let W={...K,...V?.meta_governor??{}},z=m(W);if(!z.enabled)return{};let U=()=>z.modelOverride?.providerID??Q.providerID?.(),H=()=>z.modelOverride?.modelID??Q.modelID?.(),w=()=>z.modelOverride?.modelLimit??200000,_=U()??"unknown",L=H()??"unknown",P;if(z.protocolEnforcement.enabled||z.protocolEnforcement.injectIntoSystem){let G=z.protocolEnforcement.path??g;YK(G).then((Y)=>{P=VK(Y)}).catch((Y)=>{if(typeof console<"u"&&z.modelOverride?.verbosity!=="silent")console.warn("[meta-governor] could not load protocol:",Y instanceof Error?Y.message:Y)})}let p=new Map,C=new Map;return{"tool.execute.before":async(G)=>{if(!z.enabled)return;if(!z.protocolEnforcement.auditToolCalls)return;if(!G.sessionID)return;let Y=p.get(G.sessionID);if(!Y)Y={memoryToolsUsed:[],hasCodegraphDir:Z,hasGraphifyDir:$,oracleInvoked:!1,filesChanged:0,emptyRecall:!1,escalationAttempted:!1,aftAvailable:!1,aftUsed:!1,recentToolCalls:[],recentWriteContents:[],memorySaved:!1,batchCompletions:0},p.set(G.sessionID,Y);if(P)console.log("[meta-governor] protocol loaded, system injection ready");let F=WK(G.tool,{},{memoryToolsUsed:Y.memoryToolsUsed,hasCodegraphDir:Y.hasCodegraphDir,hasGraphifyDir:Y.hasGraphifyDir,oracleInvoked:Y.oracleInvoked,filesChanged:Y.filesChanged,emptyRecall:Y.emptyRecall,escalationAttempted:Y.escalationAttempted,aftAvailable:Y.aftAvailable,aftUsed:Y.aftUsed,recentToolCalls:Y.recentToolCalls,recentWriteContents:Y.recentWriteContents,memorySaved:Y.memorySaved,batchCompletions:Y.batchCompletions});if(F.length>0){j("warn",`protocol violations on tool ${G.tool}`,F);let R=C.get(G.sessionID)??[];for(let A of F)R.push(`[${A.severity.toUpperCase()}] ${A.rule}: ${A.detail}`);C.set(G.sessionID,R)}else j("info",`audit OK on tool ${G.tool}`)},"tool.execute.after":async(G,Y)=>{if(!z.enabled)return;let F=p.get(G.sessionID);if(F){if(F.recentToolCalls=[G.tool].concat(F.recentToolCalls).slice(0,20),["write","edit","edit_block","desktop-commander_write_file","desktop-commander_edit_block"].includes(G.tool)){F.filesChanged++;let k=(Y.output??"").slice(0,500);F.recentWriteContents=[k].concat(F.recentWriteContents).slice(0,3)}if(["agentmemory_memory_recall","agentmemory_memory_smart_search","agentmemory_memory_save","ctx_memory","ctx_search","ctx_note"].some((k)=>G.tool.startsWith(k))&&!F.memoryToolsUsed.includes(G.tool))F.memoryToolsUsed.push(G.tool);if(G.tool.startsWith("ctx_memory")){let k=Y.output??"";if(k.includes("saved")||k.includes("written"))F.memorySaved=!0}if(G.tool.startsWith("aft_zoom")||G.tool.startsWith("aft_outline"))F.aftUsed=!0;if(G.tool==="task"&&(Y.output??"").includes("subagent_type=oracle"))F.oracleInvoked=!0;let I=(Y.output??"").toLowerCase();if(G.tool.includes("recall")&&(I.includes("returned empty")||I.includes("no results")))F.emptyRecall=!0;if(G.tool==="todowrite"&&(Y.output??"").includes("completed")){if(((Y.output??"").match(/"status":"completed"/g)??[]).length>=3)F.batchCompletions++}}let R={sessionID:G.sessionID,toolName:G.tool,toolOutput:Y.output,iteration:0,maxIterations:10,oracleVerified:!1,noProgress:!1,filesChanged:0,recentTurnTokens:[],deviations:[],backends:Q.backends??{agentmemory:{smartSearch:async()=>({lessons:[],crystals:[]})},magicContext:{slotList:async()=>[]},boulderState:{boulderRead:async()=>[]}},writeBackend:Q.writeBackend??{saveMemory:async()=>({id:""}),saveLesson:async()=>({id:""})},config:z,...U()?{providerID:U()}:{},...H()?{modelID:H()}:{},modelLimit:w()};try{let A=await KK(R);if(z.intervention.mode!=="silent"){let T=A.decision;if(T.action!=="continue"&&UK(T.action,z.intervention.minActionForMessage))qK(G.sessionID,T)}}catch{}},"experimental.chat.messages.transform":async(G,Y)=>{if(!z.enabled)return;if(z.intervention.mode!=="message")return;let R=Y.messages[Y.messages.length-1]?.info?.sessionID;if(R&&C.has(R)){let x=C.get(R);if(x.length>0){let I=`[META-GOVERNOR PROTOCOL VIOLATIONS - YOU MUST COMPLY]
|
|
13
|
-
|
|
14
|
-
${x.map((k,pK)=>`${pK+1}. ${k}`).join(`
|
|
15
|
-
`)}
|
|
16
|
-
|
|
17
|
-
Remember: use codegraph/graphify for architecture queries, do not grep without trying AFT/codegraph first, no @ts-ignore/as-any, no empty catch, check memory before asking.`;Y.messages.push({info:{role:"user",agent:"meta-governor",synthetic:!0},parts:[{type:"text",text:I,synthetic:!0}]}),C.delete(R),j("info",`injected ${x.length} violation(s) to model`)}}let A=BK();if(!A)return;if(A.action==="continue")return;if(!A.message)return;if(!UK(A.action,z.intervention.minActionForMessage))return;let T={type:"text",text:`[MetaGovernor] ${A.message}`,synthetic:!0};Y.messages.push({info:{role:"user",agent:"meta-governor"},parts:[T]})},"experimental.chat.system.transform":async(G,Y)=>{if(!z.enabled)return;if(z.protocolEnforcement.injectIntoSystem&&P)Y.system.push(`
|
|
18
|
-
### Sisyphus Protocol Enforcement`,P,"---");if(z.intervention.mode==="system"&&G.sessionID){let F=zK(G.sessionID);if(F&&F.action!=="continue"&&F.message){if(UK(F.action,z.intervention.minActionForMessage))Y.system.push(`
|
|
19
|
-
[MetaGovernor Intervention]`,F.message,"---")}}}}}}function lQ(K){let Q={severity:K.success?"leve":"grave",category:`recovery:${K.fixStrategy}`,detail:`${K.errorCode}: ${K.context??"no context"}`};return{action:K.success?"continue":"warn",score:K.success?0.5:-0.5,reasoning:`Recovery ${K.success?"succeeded":"failed"}: ${K.fixStrategy} for ${K.errorCode}`,evidence:[{source:"deviation-detector",value:Q.detail,confidence:1,weight:K.success?0.3:0.8}],shouldEscalateTo:K.success?null:"oracle"}}var fK={leve:0,media:1,grave:2};function mK(K,Q){let X=fK[Q]??0;return K.some((Z)=>(fK[Z.severity]??0)>=X)}async function aQ(K,Q,X){if(!Q)return null;let Z=X?.config??N(),$=lQ(K);if(!Z.enabled)return{lessonSaved:null,decisionSaved:null,reason:"closed-loop learning disabled"};let J=[{severity:K.success?"leve":"grave",category:`recovery:${K.fixStrategy}`,detail:`${K.errorCode}: ${K.context??"no context"}`}],q=null,B=null;if(Z.saveDecisions){let W={id:`D-${Math.abs(`${K.sessionID}-${$.action}-${Date.now()}`.split("").reduce((z,U)=>(z<<5)-z+U.charCodeAt(0)|0,0)).toString(36)}`,timestampISO:new Date().toISOString(),action:$.action,score:$.score,reasoning:$.reasoning,sessionID:K.sessionID,directory:K.directory,deviations:J.map((z)=>({severity:z.severity,category:z.category,detail:z.detail}))};try{await Q.saveMemory({content:`Decision: ${$.action} (score ${$.score.toFixed(2)}). ${$.reasoning}`,concepts:["meta-governor","decision",$.action,...J.map((z)=>z.category)],type:"fact",files:[...K.filesChanged??[]]}),B=W}catch{}}if(mK(J,Z.minSeverityToLearn)){let W=[...new Set(J.flatMap((H)=>[H.category,H.severity]))],z=J.map((H)=>`[${H.severity}] ${H.category}: ${H.detail}`).join("; "),U=`Action "${$.action}" (score ${$.score.toFixed(2)}) after deviations: ${z}. Reasoning: ${$.reasoning}`;try{q={id:(await Q.saveLesson({content:U,context:`session:${K.sessionID} dir:${K.directory}`,confidence:Math.max(0.3,Math.min(0.8,Math.abs($.score))),tags:W})).id,title:`${$.action} after ${J[0]?.category??"recovery"}`,content:U,type:"pattern",concepts:W,confidence:Math.max(0.3,Math.min(0.8,Math.abs($.score))),files:[...K.filesChanged??[]],sessionID:K.sessionID}}catch{}}let V=[];if(B)V.push("decision saved");if(q)V.push("lesson saved");else if(!mK(J,Z.minSeverityToLearn))V.push("severity below threshold");if(!B&&!q&&!V.length)V.push("no saveable content");return{lessonSaved:q,decisionSaved:B,reason:V.join("; ")||"no action taken"}}JK();function gK(){return{$schema:"http://json-schema.org/draft-07/schema#",$id:"https://raw.githubusercontent.com/herjarsa/omo-meta-governor/main/assets/omo-meta-governor.schema.json",title:"omo-meta-governor",description:"Configuration schema for @herjarsa/omo-meta-governor — Self-judging agent orchestration layer for OpenCode.",type:"object",additionalProperties:!1,properties:{$schema:{type:"string",description:"JSON Schema reference for IDE autocompletion."},enabled:{type:"boolean",description:"Master feature flag — must be true to run the orchestrator.",default:!1},decision:{type:"object",description:"Decision handler configuration.",additionalProperties:!1,properties:{maxHistoryPerSession:{type:"integer",description:"Maximum history entries per session before oldest are trimmed.",default:50,minimum:1},forceContinueAfterStops:{type:"integer",description:"How many consecutive stops before forcing continue.",default:3,minimum:1}}},memory:{type:"object",description:"Memory aggregator configuration.",additionalProperties:!1,properties:{agentmemoryTimeoutMs:{type:"integer",description:"Timeout for agentmemory queries in milliseconds.",default:2000,minimum:100},magicContextTimeoutMs:{type:"integer",description:"Timeout for magic-context queries in milliseconds.",default:1000,minimum:100},boulderStateTimeoutMs:{type:"integer",description:"Timeout for boulder-state queries in milliseconds.",default:1000,minimum:100},query:{type:"string",description:"Natural-language query for memory recall.",default:"meta_governor_context"}}},tokenPredictor:{type:"object",description:"Token predictor configuration.",additionalProperties:!1,properties:{compactBurnRateThreshold:{type:"integer",description:"Burn rate threshold (tokens/turn) above which to recommend compact-now.",default:500,minimum:0},compactUsageThreshold:{type:"number",description:"Context usage ratio (0..1) above which to recommend compact-now.",default:0.85,minimum:0,maximum:1},switchModelUsageThreshold:{type:"number",description:"Context usage ratio above which to recommend switch-model.",default:0.95,minimum:0,maximum:1},delegateConsecutiveHighBurn:{type:"integer",description:"Max consecutive high-burn turns before recommending delegate.",default:5,minimum:1}}},scoring:{type:"object",description:"Scoring engine configuration.",additionalProperties:!1,properties:{continueThreshold:{type:"number",description:"Score >= this -> continue silently.",default:0.3,minimum:0,maximum:1},warnThreshold:{type:"number",description:"Score <= -warnThreshold -> warn.",default:0.3,minimum:0,maximum:1},escalateThreshold:{type:"number",description:"Score <= -escalateThreshold -> escalate.",default:0.6,minimum:0,maximum:1},stopThreshold:{type:"number",description:"Score <= -stopThreshold -> stop.",default:0.8,minimum:0,maximum:1}}},closedLoop:{type:"object",description:"Closed-loop learning configuration.",additionalProperties:!1,properties:{saveDecisions:{type:"boolean",description:"Whether to save decision records.",default:!0},saveLessons:{type:"boolean",description:"Whether to save lessons.",default:!0}}},modelOverride:{type:"object",description:"Model override for MetaGovernor internal LLM usage.",additionalProperties:!1,properties:{providerID:{type:"string",description:"Provider ID (e.g. 'openai', 'anthropic')."},modelID:{type:"string",description:"Model ID (e.g. 'gpt-4o-mini', 'claude-sonnet-4-20250514')."},modelLimit:{type:"integer",description:"Context window size for token predictor.",minimum:1000},temperature:{type:"number",description:"Sampling temperature. Default: 0.2.",default:0.2,minimum:0,maximum:2},topP:{type:"number",description:"Top-p nucleus sampling. Default: 1.",default:1,minimum:0,maximum:1},maxTokens:{type:"integer",description:"Max output tokens for internal reasoning.",default:2048,minimum:1},reasoning:{type:"boolean",description:"Enable extended reasoning / thinking mode.",default:!1},verbosity:{type:"string",description:"Verbosity level for internal logging.",enum:["silent","minimal","verbose"],default:"minimal"}}},intervention:{type:"object",description:"Intervention config for visible decision injection.",additionalProperties:!1,properties:{mode:{type:"string",description:"How to inject: 'silent', 'message', or 'system'.",enum:["silent","message","system"],default:"silent"},includeDecisionHistory:{type:"boolean",description:"Whether to include recent decision history.",default:!0},maxHistoryMessages:{type:"integer",description:"Max history entries when includeDecisionHistory is true.",default:5,minimum:1},minActionForMessage:{type:"string",description:"Minimum action: 'warn' (all non-continue), 'escalate', or 'stop'.",enum:["warn","escalate","stop"],default:"warn"}}},protocolEnforcement:{type:"object",description:"Sisyphus protocol enforcement config.",additionalProperties:!1,properties:{enabled:{type:"boolean",description:"Master switch for protocol enforcement.",default:!1},path:{type:"string",description:"Path to protocol markdown file."},injectIntoSystem:{type:"boolean",description:"Whether to inject protocol rules into the system prompt.",default:!1},auditToolCalls:{type:"boolean",description:"Whether to audit tool calls for protocol violations.",default:!1}}},graphSync:{type:"object",description:"Graph synchronization (auto-init codegraph/graphify).",additionalProperties:!1,properties:{enabled:{type:"boolean",description:"Enable auto-initialization of codegraph and graphify.",default:!0},watch:{type:"boolean",description:"Enable watch mode (re-index on file changes).",default:!1}}}},definitions:{verbosity:{type:"string",enum:["silent","minimal","verbose"],description:"Verbosity level."},interventionMode:{type:"string",enum:["silent","message","system"],description:"Intervention injection mode."},minAction:{type:"string",enum:["warn","escalate","stop"],description:"Minimum action threshold."}}}}async function cQ(K){let Q=gK(),{writeFile:X}=await import("node:fs/promises");await X(K,JSON.stringify(Q,null,2)+`
|
|
20
|
-
`,"utf-8")}var rQ={id:"omo-meta-governor",server:HK()},uX=rQ;export{cQ as writeSchemaFile,PQ as trimHistory,zK as takeDecision,BK as takeAnyDecision,QK as stripJsoncComments,qK as storeDecision,XQ as stopWatches,i as score,KK as runMetaGovernor,u as runGraphSync,eK as resetInitializedProjects,aQ as recordRecovery,s as predict,XK as parseJsonc,o as observeAndLearn,j as logToFile,YK as loadProtocol,xQ as loadOrchestratorConfigFromSources,m as loadOrchestratorConfig,IK as loadMetaGovernorConfig,f as loadJsoncFile,yQ as isMetaGovernorEnabled,IQ as hasDecision,t as handleDecision,ZK as getUserConfigPath,$K as getProjectConfigPath,gK as generateSchema,YQ as defaultTokenPredictorConfig,S as defaultScoringConfig,bK as defaultOrchestratorConfig,v as defaultDecisionHandlerConfig,N as defaultClosedLoopConfig,uX as default,b as deepMerge,HK as createMetaGovernorPlugin,MQ as countConsecutiveStops,DQ as clearAll,RK as calculateBurnRate,VK as buildSystemInjection,jK as buildDecisionContext,WK as auditToolCall,r as aggregateRead,g as DEFAULT_PROTOCOL_PATH};
|
|
21
|
-
|
|
22
|
-
//# debugId=1032D4A61794B53D64756E2164756E21
|
|
23
|
-
//# sourceMappingURL=index.js.map
|