@heretyc/subagent-mcp 2.8.7 → 2.8.9
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/directives/orchestration-claude.md +6 -5
- package/directives/orchestration-codex.md +6 -5
- package/directives/reminder-on.md +2 -0
- package/directives/short-on.md +1 -1
- package/dist/drivers.js +59 -3
- package/dist/index.js +139 -19
- package/dist/init.js +5 -1
- package/dist/orchestration/model-mode.js +132 -0
- package/dist/routing-table.json +2469 -3561
- package/dist/setup.js +2 -2
- package/package.json +2 -2
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { cwdHash, stateDir } from "./marker.js";
|
|
4
|
+
/**
|
|
5
|
+
* Per-project model-selection mode — the SINGLE source of truth for whether a
|
|
6
|
+
* working directory is in "smart" mode (the default; provider/model/effort
|
|
7
|
+
* selectors are rejected and the best model is chosen automatically) or
|
|
8
|
+
* "user-approved-overrides" mode (the user has explicitly authorized manual
|
|
9
|
+
* selectors for a bounded window).
|
|
10
|
+
*
|
|
11
|
+
* State is a per-project file in the SAME shared state dir as the marker,
|
|
12
|
+
* keyed by the SAME cwdHash so path-keying style stays uniform. The
|
|
13
|
+
* user-approved-overrides grant is time-boxed: WINDOW_MS after enable, the
|
|
14
|
+
* next resolveMode() lazily reverts the project to smart mode.
|
|
15
|
+
*
|
|
16
|
+
* FAIL-SAFE: filesystem reads return safe defaults ("smart") on any failure;
|
|
17
|
+
* writes mirror marker.ts perms (0o700 dir / 0o600 file).
|
|
18
|
+
*/
|
|
19
|
+
const WINDOW_MS = 30 * 60 * 1000;
|
|
20
|
+
export function modelModePath(cwd) {
|
|
21
|
+
return join(stateDir, `model-${cwdHash(cwd)}.json`);
|
|
22
|
+
}
|
|
23
|
+
function readModelMode(cwd) {
|
|
24
|
+
try {
|
|
25
|
+
const raw = readFileSync(modelModePath(cwd), "utf8");
|
|
26
|
+
const parsed = JSON.parse(raw);
|
|
27
|
+
const mode = parsed.mode === "user-approved-overrides" ? "user-approved-overrides" : "smart";
|
|
28
|
+
const enabled_at = typeof parsed.enabled_at === "number" ? parsed.enabled_at : null;
|
|
29
|
+
return { mode, enabled_at };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Missing/corrupt/invalid -> safe default (smart, never enabled).
|
|
33
|
+
return { mode: "smart", enabled_at: null };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function writeModelMode(cwd, state) {
|
|
37
|
+
try {
|
|
38
|
+
// Owner-only perms (mirror marker.ts): the file persists an enable-time.
|
|
39
|
+
mkdirSync(stateDir, { recursive: true, mode: 0o700 });
|
|
40
|
+
writeFileSync(modelModePath(cwd), JSON.stringify(state), {
|
|
41
|
+
encoding: "utf8",
|
|
42
|
+
mode: 0o600,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Fail-safe: never throw to the caller.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function resolveMode(cwd, now = Date.now()) {
|
|
50
|
+
const state = readModelMode(cwd);
|
|
51
|
+
if (state.mode === "user-approved-overrides" &&
|
|
52
|
+
typeof state.enabled_at === "number" &&
|
|
53
|
+
now - state.enabled_at > WINDOW_MS) {
|
|
54
|
+
// Lazy revert side-effect: the grant has expired, persist smart mode.
|
|
55
|
+
writeModelMode(cwd, { mode: "smart", enabled_at: null });
|
|
56
|
+
return {
|
|
57
|
+
mode: "smart",
|
|
58
|
+
enabled_at: null,
|
|
59
|
+
window_remaining_ms: 0,
|
|
60
|
+
reverted: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (state.mode === "user-approved-overrides") {
|
|
64
|
+
return {
|
|
65
|
+
mode: "user-approved-overrides",
|
|
66
|
+
enabled_at: state.enabled_at,
|
|
67
|
+
window_remaining_ms: Math.max(0, WINDOW_MS - (now - state.enabled_at)),
|
|
68
|
+
reverted: false,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
mode: "smart",
|
|
73
|
+
enabled_at: state.enabled_at,
|
|
74
|
+
window_remaining_ms: 0,
|
|
75
|
+
reverted: false,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function setMode(cwd, mode, now = Date.now()) {
|
|
79
|
+
if (mode === "smart") {
|
|
80
|
+
writeModelMode(cwd, { mode: "smart", enabled_at: null });
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const cur = resolveMode(cwd, now);
|
|
84
|
+
if (cur.mode === "user-approved-overrides") {
|
|
85
|
+
// Re-enabling an already-active window must NOT refresh/extend it: the
|
|
86
|
+
// original enable-timestamp stands.
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
writeModelMode(cwd, { mode: "user-approved-overrides", enabled_at: now });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return resolveMode(cwd, now);
|
|
93
|
+
}
|
|
94
|
+
export function gateLaunch(cwd, selectors, now = Date.now()) {
|
|
95
|
+
const r = resolveMode(cwd, now);
|
|
96
|
+
const supplied = !!(selectors.provider || selectors.model || selectors.effort);
|
|
97
|
+
if (r.mode === "user-approved-overrides") {
|
|
98
|
+
return { allowed: true, mode: r.mode, reverted: r.reverted };
|
|
99
|
+
}
|
|
100
|
+
if (supplied) {
|
|
101
|
+
return {
|
|
102
|
+
allowed: false,
|
|
103
|
+
mode: "smart",
|
|
104
|
+
message: SELECTOR_REJECTION_MESSAGE,
|
|
105
|
+
reverted: r.reverted,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return { allowed: true, mode: "smart", reverted: r.reverted };
|
|
109
|
+
}
|
|
110
|
+
export const SELECTOR_REJECTION_MESSAGE = [
|
|
111
|
+
"Model/provider/effort selection is DISABLED in smart mode (the default). " +
|
|
112
|
+
"The best model is ALREADY being selected for you from the latest " +
|
|
113
|
+
"benchmarking data, rigorous ongoing research, and numerous environment " +
|
|
114
|
+
"conditions you may not be aware of — relaunch WITHOUT provider/model/effort.",
|
|
115
|
+
"",
|
|
116
|
+
"If you have a specific, scoped need for a particular provider/model/effort, " +
|
|
117
|
+
"you must ALWAYS stop and ask the USER for authorization using the " +
|
|
118
|
+
"structured-question tool (AskUserQuestion on Claude / request-user-input on " +
|
|
119
|
+
"Codex; if no structured-question tool exists, a plain yes/no question), THEN " +
|
|
120
|
+
'call `model-selection-mode` with mode "user-approved-overrides" before retrying.',
|
|
121
|
+
"",
|
|
122
|
+
"Fallback ladder (a): if you are blocked here because the structured-question " +
|
|
123
|
+
"tool ITSELF is unavailable/failing (a provider issue), do NOT guess — keep " +
|
|
124
|
+
"working until you actually need the answer, then RETURN to your caller with " +
|
|
125
|
+
"the question plus the possible multiple-choice answers; the calling/" +
|
|
126
|
+
"orchestrator agent asks the user in the orchestration context and relaunches " +
|
|
127
|
+
"you with the answer.",
|
|
128
|
+
"",
|
|
129
|
+
"Fallback ladder (b): if you are blocked due to a REAL error (not a deliberate " +
|
|
130
|
+
"smart-mode policy block), the user needs to know — surface it and consult the " +
|
|
131
|
+
"user before continuing.",
|
|
132
|
+
].join("\n");
|