@heretyc/subagent-mcp 2.12.17 → 2.12.18
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.
|
@@ -26,6 +26,11 @@ const SUBAGENT_ENTRYPOINTS = new Set([
|
|
|
26
26
|
function finiteNumber(value) {
|
|
27
27
|
return typeof value === "number" && Number.isFinite(value);
|
|
28
28
|
}
|
|
29
|
+
function isRealClaudeModel(value) {
|
|
30
|
+
return (typeof value === "string" &&
|
|
31
|
+
value.trim() !== "" &&
|
|
32
|
+
value.trim() !== "<synthetic>");
|
|
33
|
+
}
|
|
29
34
|
function readTranscriptTail(transcriptPath) {
|
|
30
35
|
if (!transcriptPath)
|
|
31
36
|
return null;
|
|
@@ -80,12 +85,12 @@ function liftClaudeUsageFromTranscript(transcriptPath) {
|
|
|
80
85
|
continue;
|
|
81
86
|
if (msg.type !== "assistant" || !msg.message?.usage)
|
|
82
87
|
continue;
|
|
83
|
-
if (
|
|
84
|
-
|
|
88
|
+
if (!isRealClaudeModel(msg.message.model))
|
|
89
|
+
continue;
|
|
85
90
|
const usage = msg.message.usage;
|
|
86
91
|
return {
|
|
87
92
|
harness: "claude",
|
|
88
|
-
model: msg.message.model,
|
|
93
|
+
model: msg.message.model.trim(),
|
|
89
94
|
source_ref: transcriptPath,
|
|
90
95
|
usage: {
|
|
91
96
|
input: finiteNumber(usage.input_tokens) ? usage.input_tokens : 0,
|
|
@@ -97,6 +102,9 @@ function liftClaudeUsageFromTranscript(transcriptPath) {
|
|
|
97
102
|
? usage.cache_read_input_tokens
|
|
98
103
|
: 0,
|
|
99
104
|
},
|
|
105
|
+
// Claude Code statusline receives context_window.used_percentage on its
|
|
106
|
+
// own stdin payload. Recent hook transcripts do not expose that object,
|
|
107
|
+
// so this adapter cannot pass it through without a hook-readable signal.
|
|
100
108
|
harnessPercentage: null,
|
|
101
109
|
};
|
|
102
110
|
}
|
package/dist/index.js
CHANGED
|
@@ -572,7 +572,7 @@ const ORCHESTRATION_INSTRUCTIONS = "subagent-mcp - CANONICAL OPERATING MODEL (fu
|
|
|
572
572
|
const SUBAGENT_INSTRUCTIONS = "SUB-AGENT SESSION: you are a child process launched by subagent-mcp. Follow the parent prompt. Do not treat yourself as the orchestrator, do not re-trigger orchestration carryover, and do not launch further sub-agents unless the parent prompt explicitly assigns that. launch_agent is code-capped at 2 spawn levels below the main orchestrator: depth 1 may launch depth 2 workers; depth 2 workers cannot spawn further.\n\nMODEL SELECTION MODE (parallel to orchestration-mode, set via the model-selection-mode tool). DEFAULT is \"smart\" and is used whenever unset: in smart, launch_agent REJECTS any call supplying provider/model/effort selectors and the server auto-picks the best model. \"user-approved-overrides\" opens a 30-MINUTE window where selectors are HONORED, enforced LAZILY (the mode reverts to smart on the next launch_agent call after 30 minutes) and re-enabling does NOT extend an active window. HONOR-BASED: you MUST NOT set \"user-approved-overrides\" without explicit interactive USER authorization via the structured-question tool (AskUserQuestion on Claude / request-user-input on Codex); never enable it on your own initiative.";
|
|
573
573
|
const server = new McpServer({
|
|
574
574
|
name: "subagent-mcp",
|
|
575
|
-
version: "2.12.
|
|
575
|
+
version: "2.12.18",
|
|
576
576
|
description: "Launches always-interactive local Claude and Codex sub-agent sessions and is the orchestrator's sole launch channel. Claude runs via the Claude Agent SDK over the local Claude Code executable; Codex via `codex app-server` over stdio. The server never calls Anthropic or OpenAI HTTP APIs directly.",
|
|
577
577
|
}, {
|
|
578
578
|
instructions: process.env.SUBAGENT_MCP_SUBAGENT === "1"
|
|
@@ -361,9 +361,10 @@ function updateMeteringForTurn(payload, env, adapter, current, turnIndex) {
|
|
|
361
361
|
priorWindowFloor: prior?.window_floor ?? null,
|
|
362
362
|
});
|
|
363
363
|
metering.writeMetering(current, record);
|
|
364
|
-
// A valid harness-reported percentage stands on its own. Without one,
|
|
365
|
-
//
|
|
366
|
-
//
|
|
364
|
+
// A valid harness-reported percentage stands on its own. Without one, we fall
|
|
365
|
+
// back to the window: context_window_size is always numeric under the
|
|
366
|
+
// assumed-default ladder, so the null guard remains as a dead-man fallback only
|
|
367
|
+
// (the record is still persisted for observability and same-turn fail-safe agreement).
|
|
367
368
|
const hasHarnessPercentage = typeof lifted.harnessPercentage === "number" &&
|
|
368
369
|
Number.isFinite(lifted.harnessPercentage);
|
|
369
370
|
return !hasHarnessPercentage && record.context_window_size === null;
|
|
@@ -120,28 +120,44 @@ function maybeApplyLong(candidate, source, long, enabled) {
|
|
|
120
120
|
}
|
|
121
121
|
return { candidate, source };
|
|
122
122
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
function assumedDefaultResolution(window_floor) {
|
|
124
|
+
if (window_floor !== null && window_floor > DEFAULT_CONTEXT_WINDOW) {
|
|
125
|
+
return {
|
|
126
|
+
window: window_floor,
|
|
127
|
+
source: "assumed-default+floor",
|
|
128
|
+
window_floor,
|
|
129
|
+
contradiction: false,
|
|
130
|
+
};
|
|
131
131
|
}
|
|
132
|
+
return {
|
|
133
|
+
window: DEFAULT_CONTEXT_WINDOW,
|
|
134
|
+
source: "assumed-default",
|
|
135
|
+
window_floor,
|
|
136
|
+
contradiction: false,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export function resolveContextWindowDetailed(input) {
|
|
132
140
|
const promptSideTokens = finiteNumber(input.promptSideTokens)
|
|
133
141
|
? input.promptSideTokens
|
|
134
142
|
: null;
|
|
135
143
|
const priorFloor = usablePriorFloor(input.priorWindow, input.priorWindowSource, input.priorWindowFloor);
|
|
136
144
|
const observedFloor = Math.max(promptSideTokens ?? 0, priorFloor ?? 0);
|
|
137
145
|
const window_floor = observedFloor > 0 ? observedFloor : null;
|
|
146
|
+
const normalized = normalizeModelId(input.modelId);
|
|
147
|
+
if (normalized === null) {
|
|
148
|
+
return assumedDefaultResolution(window_floor);
|
|
149
|
+
}
|
|
150
|
+
const table = loadContextWindowTable();
|
|
151
|
+
if (table === null) {
|
|
152
|
+
return assumedDefaultResolution(window_floor);
|
|
153
|
+
}
|
|
138
154
|
if (input.harness === "claude") {
|
|
139
155
|
if (!/^claude-/i.test(normalized.base)) {
|
|
140
|
-
return
|
|
156
|
+
return assumedDefaultResolution(window_floor);
|
|
141
157
|
}
|
|
142
158
|
const entry = table.claude[normalized.base] ?? table.family_defaults?.claude ?? null;
|
|
143
159
|
if (entry === null) {
|
|
144
|
-
return
|
|
160
|
+
return assumedDefaultResolution(window_floor);
|
|
145
161
|
}
|
|
146
162
|
const mapped = Object.prototype.hasOwnProperty.call(table.claude, normalized.base);
|
|
147
163
|
let candidate = entry.default;
|
|
@@ -154,7 +170,7 @@ export function resolveContextWindowDetailed(input) {
|
|
|
154
170
|
source = "ratchet";
|
|
155
171
|
}
|
|
156
172
|
else {
|
|
157
|
-
return { window:
|
|
173
|
+
return { window: entry.long ?? entry.default, source: "contradiction", window_floor, contradiction: true };
|
|
158
174
|
}
|
|
159
175
|
}
|
|
160
176
|
if (priorFloor !== null && priorFloor > candidate) {
|
|
@@ -163,7 +179,7 @@ export function resolveContextWindowDetailed(input) {
|
|
|
163
179
|
source = "prior";
|
|
164
180
|
}
|
|
165
181
|
else {
|
|
166
|
-
return { window:
|
|
182
|
+
return { window: entry.long ?? entry.default, source: "contradiction", window_floor, contradiction: true };
|
|
167
183
|
}
|
|
168
184
|
}
|
|
169
185
|
return { window: candidate, source, window_floor, contradiction: false };
|
|
@@ -171,7 +187,7 @@ export function resolveContextWindowDetailed(input) {
|
|
|
171
187
|
if (input.harness === "codex") {
|
|
172
188
|
const entry = table.codex[normalized.base] ?? null;
|
|
173
189
|
if (entry === null) {
|
|
174
|
-
return
|
|
190
|
+
return assumedDefaultResolution(window_floor);
|
|
175
191
|
}
|
|
176
192
|
let candidate = entry.default;
|
|
177
193
|
let source = "mapping";
|
|
@@ -182,7 +198,7 @@ export function resolveContextWindowDetailed(input) {
|
|
|
182
198
|
source = "ratchet";
|
|
183
199
|
}
|
|
184
200
|
else {
|
|
185
|
-
return { window:
|
|
201
|
+
return { window: entry.long ?? entry.default, source: "contradiction", window_floor, contradiction: true };
|
|
186
202
|
}
|
|
187
203
|
}
|
|
188
204
|
if (priorFloor !== null && priorFloor > candidate) {
|
|
@@ -191,12 +207,12 @@ export function resolveContextWindowDetailed(input) {
|
|
|
191
207
|
source = "prior";
|
|
192
208
|
}
|
|
193
209
|
else {
|
|
194
|
-
return { window:
|
|
210
|
+
return { window: entry.long ?? entry.default, source: "contradiction", window_floor, contradiction: true };
|
|
195
211
|
}
|
|
196
212
|
}
|
|
197
213
|
return { window: candidate, source, window_floor, contradiction: false };
|
|
198
214
|
}
|
|
199
|
-
return
|
|
215
|
+
return assumedDefaultResolution(window_floor);
|
|
200
216
|
}
|
|
201
217
|
export function resolveContextWindow(harness, modelId) {
|
|
202
218
|
return resolveContextWindowDetailed({ harness, modelId }).window;
|
package/package.json
CHANGED