@algosuite/vo-mcp 0.2.0-beta.16 → 0.2.0-beta.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.
- package/dist/cli.js +151 -58
- package/dist/cli.js.map +4 -4
- package/dist/index.js +146 -54
- package/dist/index.js.map +4 -4
- package/dist/runner-cli.js +758 -318
- package/dist/runner-cli.js.map +4 -4
- package/dist/runner-supervisor.js +258 -38
- package/dist/runner-supervisor.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1625,7 +1625,7 @@ var init_sync_config = __esm({
|
|
|
1625
1625
|
// src/cli.ts
|
|
1626
1626
|
import { homedir as homedir6, hostname } from "node:os";
|
|
1627
1627
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
1628
|
-
import { join as
|
|
1628
|
+
import { join as join9 } from "node:path";
|
|
1629
1629
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1630
1630
|
|
|
1631
1631
|
// src/server.ts
|
|
@@ -2481,7 +2481,11 @@ async function handleConsensusJudgment(deps, rawInput, signal) {
|
|
|
2481
2481
|
...engineResult.low_confidence_sources !== void 0 ? { low_confidence_sources: engineResult.low_confidence_sources } : {},
|
|
2482
2482
|
// Escalation (from citation grade or human-tiebreak synthesizer).
|
|
2483
2483
|
...engineResult.escalation_required !== void 0 ? { escalation_required: engineResult.escalation_required } : {},
|
|
2484
|
-
...engineResult.escalation_reason !== void 0 ? { escalation_reason: engineResult.escalation_reason } : {}
|
|
2484
|
+
...engineResult.escalation_reason !== void 0 ? { escalation_reason: engineResult.escalation_reason } : {},
|
|
2485
|
+
// Critique-uptake (2026-07-20 red-team fix) — the engine computes this
|
|
2486
|
+
// on every call; this spread closes the gap where the visibility report
|
|
2487
|
+
// was itself silently dropped at the payload boundary.
|
|
2488
|
+
...engineResult.critique_uptake !== void 0 ? { critique_uptake: engineResult.critique_uptake } : {}
|
|
2485
2489
|
};
|
|
2486
2490
|
const envelope = {
|
|
2487
2491
|
tool: TOOL_NAME4,
|
|
@@ -5741,6 +5745,121 @@ async function handleHqWhiteboardRead(_deps, rawInput, signal) {
|
|
|
5741
5745
|
return jsonContent(await callWhiteboard("GET", input, signal));
|
|
5742
5746
|
}
|
|
5743
5747
|
|
|
5748
|
+
// src/tools/skills/skill-corpus.ts
|
|
5749
|
+
init_common();
|
|
5750
|
+
import { existsSync as existsSync6, statSync as statSync4 } from "node:fs";
|
|
5751
|
+
import { dirname as dirname5, isAbsolute, join as join8, resolve as resolve2 } from "node:path";
|
|
5752
|
+
import {
|
|
5753
|
+
loadSkillsFromDir
|
|
5754
|
+
} from "@algosuite/skill-registry";
|
|
5755
|
+
var LIST_TOOL_NAME = "vo_skill_list";
|
|
5756
|
+
var GET_TOOL_NAME = "vo_skill_get";
|
|
5757
|
+
var listDescription = "List the Algosuite skill corpus (name + trigger description for every skill). Call once near session start to learn which skills exist; then fetch the full instructions for a relevant skill with vo_skill_get. This is the same corpus Claude Code loads natively from .claude/skills \u2014 served over MCP so every vendor works from identical playbooks. Pass refresh:true to re-scan from disk.";
|
|
5758
|
+
var getDescription = "Fetch the full markdown instructions of one Algosuite skill by name. Follow the returned instructions for the current task the same way a native skill invocation would. Use vo_skill_list to discover skill names.";
|
|
5759
|
+
var listInputSchema = {
|
|
5760
|
+
type: "object",
|
|
5761
|
+
properties: {
|
|
5762
|
+
refresh: {
|
|
5763
|
+
type: "boolean",
|
|
5764
|
+
description: "Re-scan the skills directory instead of using the cached corpus."
|
|
5765
|
+
}
|
|
5766
|
+
},
|
|
5767
|
+
required: []
|
|
5768
|
+
};
|
|
5769
|
+
var getInputSchema = {
|
|
5770
|
+
type: "object",
|
|
5771
|
+
properties: {
|
|
5772
|
+
name: {
|
|
5773
|
+
type: "string",
|
|
5774
|
+
description: "Skill name exactly as returned by vo_skill_list."
|
|
5775
|
+
}
|
|
5776
|
+
},
|
|
5777
|
+
required: ["name"]
|
|
5778
|
+
};
|
|
5779
|
+
var MAX_WALK_UP_LEVELS = 8;
|
|
5780
|
+
var cachedCorpus = null;
|
|
5781
|
+
function resolveSkillsDir(env = process.env, startDir = process.cwd()) {
|
|
5782
|
+
const override = env.VO_SKILLS_DIR;
|
|
5783
|
+
if (typeof override === "string" && override.length > 0) {
|
|
5784
|
+
const abs = isAbsolute(override) ? override : resolve2(startDir, override);
|
|
5785
|
+
return existsSync6(abs) && statSync4(abs).isDirectory() ? abs : null;
|
|
5786
|
+
}
|
|
5787
|
+
let dir = resolve2(startDir);
|
|
5788
|
+
for (let i = 0; i < MAX_WALK_UP_LEVELS; i += 1) {
|
|
5789
|
+
const candidate = join8(dir, ".claude", "skills");
|
|
5790
|
+
if (existsSync6(candidate) && statSync4(candidate).isDirectory()) return candidate;
|
|
5791
|
+
const parent = dirname5(dir);
|
|
5792
|
+
if (parent === dir) break;
|
|
5793
|
+
dir = parent;
|
|
5794
|
+
}
|
|
5795
|
+
return null;
|
|
5796
|
+
}
|
|
5797
|
+
function loadCorpus() {
|
|
5798
|
+
const skillsDir = resolveSkillsDir();
|
|
5799
|
+
if (skillsDir === null) {
|
|
5800
|
+
return {
|
|
5801
|
+
skills: [],
|
|
5802
|
+
skillsDir: null,
|
|
5803
|
+
unavailableReason: "No skills directory found. Set VO_SKILLS_DIR or run inside a repo with .claude/skills."
|
|
5804
|
+
};
|
|
5805
|
+
}
|
|
5806
|
+
try {
|
|
5807
|
+
return { skills: loadSkillsFromDir(skillsDir), skillsDir, unavailableReason: null };
|
|
5808
|
+
} catch (err) {
|
|
5809
|
+
const message = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
|
|
5810
|
+
return { skills: [], skillsDir, unavailableReason: message };
|
|
5811
|
+
}
|
|
5812
|
+
}
|
|
5813
|
+
function getCorpus(refresh) {
|
|
5814
|
+
if (refresh || cachedCorpus === null) {
|
|
5815
|
+
cachedCorpus = loadCorpus();
|
|
5816
|
+
}
|
|
5817
|
+
return cachedCorpus;
|
|
5818
|
+
}
|
|
5819
|
+
async function handleSkillList(_deps, rawInput) {
|
|
5820
|
+
const input = rawInput ?? {};
|
|
5821
|
+
const refresh = input.refresh === true;
|
|
5822
|
+
const corpus = getCorpus(refresh);
|
|
5823
|
+
return jsonContent({
|
|
5824
|
+
corpus_available: corpus.unavailableReason === null,
|
|
5825
|
+
skills_dir: corpus.skillsDir,
|
|
5826
|
+
unavailable_reason: corpus.unavailableReason,
|
|
5827
|
+
skill_count: corpus.skills.length,
|
|
5828
|
+
skills: corpus.skills.map((s) => ({ name: s.name, description: s.description }))
|
|
5829
|
+
});
|
|
5830
|
+
}
|
|
5831
|
+
async function handleSkillGet(_deps, rawInput) {
|
|
5832
|
+
const input = rawInput ?? {};
|
|
5833
|
+
if (typeof input.name !== "string" || input.name.trim().length === 0) {
|
|
5834
|
+
throw invalidParams(GET_TOOL_NAME, 'input field "name" (non-empty string) is required');
|
|
5835
|
+
}
|
|
5836
|
+
const requested = input.name.trim();
|
|
5837
|
+
const corpus = getCorpus(false);
|
|
5838
|
+
if (corpus.unavailableReason !== null) {
|
|
5839
|
+
return jsonContent({
|
|
5840
|
+
corpus_available: false,
|
|
5841
|
+
unavailable_reason: corpus.unavailableReason,
|
|
5842
|
+
skill: null
|
|
5843
|
+
});
|
|
5844
|
+
}
|
|
5845
|
+
const skill = corpus.skills.find((s) => s.name === requested);
|
|
5846
|
+
if (skill === void 0) {
|
|
5847
|
+
throw invalidParams(
|
|
5848
|
+
GET_TOOL_NAME,
|
|
5849
|
+
`unknown skill "${requested}". Known skills: ${corpus.skills.map((s) => s.name).join(", ")}`
|
|
5850
|
+
);
|
|
5851
|
+
}
|
|
5852
|
+
return jsonContent({
|
|
5853
|
+
corpus_available: true,
|
|
5854
|
+
skill: {
|
|
5855
|
+
name: skill.name,
|
|
5856
|
+
description: skill.description,
|
|
5857
|
+
instructions: skill.body,
|
|
5858
|
+
source_path: skill.sourcePath
|
|
5859
|
+
}
|
|
5860
|
+
});
|
|
5861
|
+
}
|
|
5862
|
+
|
|
5744
5863
|
// src/server.ts
|
|
5745
5864
|
function buildToolRegistry() {
|
|
5746
5865
|
return {
|
|
@@ -5951,6 +6070,22 @@ function buildToolRegistry() {
|
|
|
5951
6070
|
inputSchema: readInputSchema
|
|
5952
6071
|
},
|
|
5953
6072
|
handler: handleHqWhiteboardRead
|
|
6073
|
+
},
|
|
6074
|
+
[LIST_TOOL_NAME]: {
|
|
6075
|
+
definition: {
|
|
6076
|
+
name: LIST_TOOL_NAME,
|
|
6077
|
+
description: listDescription,
|
|
6078
|
+
inputSchema: listInputSchema
|
|
6079
|
+
},
|
|
6080
|
+
handler: handleSkillList
|
|
6081
|
+
},
|
|
6082
|
+
[GET_TOOL_NAME]: {
|
|
6083
|
+
definition: {
|
|
6084
|
+
name: GET_TOOL_NAME,
|
|
6085
|
+
description: getDescription,
|
|
6086
|
+
inputSchema: getInputSchema
|
|
6087
|
+
},
|
|
6088
|
+
handler: handleSkillGet
|
|
5954
6089
|
}
|
|
5955
6090
|
};
|
|
5956
6091
|
}
|
|
@@ -6006,7 +6141,7 @@ function createServer(options) {
|
|
|
6006
6141
|
// src/cache/sqlite-cache.ts
|
|
6007
6142
|
import { createHash as createHash3 } from "node:crypto";
|
|
6008
6143
|
import { chmodSync as chmodSync3, mkdirSync as mkdirSync5 } from "node:fs";
|
|
6009
|
-
import { dirname as
|
|
6144
|
+
import { dirname as dirname6 } from "node:path";
|
|
6010
6145
|
import { DatabaseSync } from "node:sqlite";
|
|
6011
6146
|
|
|
6012
6147
|
// src/cache/canonicalize.ts
|
|
@@ -6051,7 +6186,7 @@ function normalizeString(s) {
|
|
|
6051
6186
|
function createSqliteCache(options) {
|
|
6052
6187
|
const fileBacked = options.dbPath !== ":memory:";
|
|
6053
6188
|
if (fileBacked) {
|
|
6054
|
-
mkdirSync5(
|
|
6189
|
+
mkdirSync5(dirname6(options.dbPath), { recursive: true, mode: 448 });
|
|
6055
6190
|
}
|
|
6056
6191
|
const versionNamespace = options.cacheVersionNamespace ?? "";
|
|
6057
6192
|
const db = new DatabaseSync(options.dbPath);
|
|
@@ -6243,59 +6378,15 @@ function createNullConsensusEngineClient(reason = NULL_CLIENT_DEFAULT_REASON) {
|
|
|
6243
6378
|
}
|
|
6244
6379
|
|
|
6245
6380
|
// src/consensus/meta-model-caller.ts
|
|
6246
|
-
var META_MODEL_API_BASE_URL = "https://api.meta.ai/v1";
|
|
6247
6381
|
var META_CONSENSUS_MODEL = "muse-spark-1.1";
|
|
6248
6382
|
var META_MODEL_API_KEY_ENV = "MODEL_API_KEY";
|
|
6249
6383
|
var META_MODEL_API_KEY_ALIAS = "META_API";
|
|
6250
|
-
function resolveMetaKey(env) {
|
|
6251
|
-
return String(env[META_MODEL_API_KEY_ENV] || env[META_MODEL_API_KEY_ALIAS] || "").trim();
|
|
6252
|
-
}
|
|
6253
|
-
function positiveMaxTokens(value) {
|
|
6254
|
-
const parsed = Math.floor(Number(value));
|
|
6255
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : 2048;
|
|
6256
|
-
}
|
|
6257
6384
|
function createMetaModelCaller(options = {}) {
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
if (!key) throw new Error(`Missing ${META_MODEL_API_KEY_ENV} for Meta Model API`);
|
|
6264
|
-
const messages = [
|
|
6265
|
-
...systemPrompt ? [{ role: "system", content: systemPrompt }] : [],
|
|
6266
|
-
{ role: "user", content: prompt }
|
|
6267
|
-
];
|
|
6268
|
-
const response = await fetchImpl(`${META_MODEL_API_BASE_URL}/chat/completions`, {
|
|
6269
|
-
method: "POST",
|
|
6270
|
-
headers: {
|
|
6271
|
-
Authorization: `Bearer ${key}`,
|
|
6272
|
-
"Content-Type": "application/json"
|
|
6273
|
-
},
|
|
6274
|
-
body: JSON.stringify({
|
|
6275
|
-
model: model || META_CONSENSUS_MODEL,
|
|
6276
|
-
messages,
|
|
6277
|
-
max_tokens: positiveMaxTokens(maxTokens),
|
|
6278
|
-
reasoning_effort: reasoningEffort
|
|
6279
|
-
}),
|
|
6280
|
-
signal
|
|
6281
|
-
});
|
|
6282
|
-
const payload = await response.json();
|
|
6283
|
-
if (!response.ok) {
|
|
6284
|
-
const message = String(payload.error?.message || response.statusText || "request failed").slice(0, 500);
|
|
6285
|
-
throw Object.assign(new Error(`Meta Model API ${response.status}: ${message}`), { status: response.status });
|
|
6286
|
-
}
|
|
6287
|
-
const content = payload.choices?.[0]?.message?.content;
|
|
6288
|
-
if (typeof content !== "string" || !content.trim()) {
|
|
6289
|
-
throw new Error(`Meta Model API returned no text (finish=${payload.choices?.[0]?.finish_reason || "unknown"})`);
|
|
6290
|
-
}
|
|
6291
|
-
const inputTokens = Number(payload.usage?.prompt_tokens || 0);
|
|
6292
|
-
const outputTokens = Number(payload.usage?.completion_tokens || 0);
|
|
6293
|
-
return {
|
|
6294
|
-
content,
|
|
6295
|
-
inputTokens,
|
|
6296
|
-
outputTokens,
|
|
6297
|
-
totalTokens: Number(payload.usage?.total_tokens || inputTokens + outputTokens)
|
|
6298
|
-
};
|
|
6385
|
+
void options;
|
|
6386
|
+
return async function callMetaWithMetrics2() {
|
|
6387
|
+
throw new Error(
|
|
6388
|
+
"Muse Spark direct consensus is disabled. Use an explicit sanitized task capsule through the AlgoSuite Model Firewall."
|
|
6389
|
+
);
|
|
6299
6390
|
};
|
|
6300
6391
|
}
|
|
6301
6392
|
var callMetaWithMetrics = createMetaModelCaller();
|
|
@@ -6568,6 +6659,10 @@ function createEngineConsensusClient(options) {
|
|
|
6568
6659
|
...mapFanOutDiagnostics(response.fan_out_diagnostics) !== void 0 ? { fan_out_diagnostics: mapFanOutDiagnostics(response.fan_out_diagnostics) } : {},
|
|
6569
6660
|
// Stage A7-shadow — adaptive-vs-incumbent comparison (PII-free; present iff shadow on).
|
|
6570
6661
|
...mapShadowSynthesis(response.shadow_synthesis) !== void 0 ? { shadow_synthesis: mapShadowSynthesis(response.shadow_synthesis) } : {},
|
|
6662
|
+
// Critique-uptake (2026-07-20 red-team fix) — verifier-critique
|
|
6663
|
+
// visibility report; previously computed by the engine on every
|
|
6664
|
+
// call but dropped at this boundary.
|
|
6665
|
+
...response.critique_uptake !== void 0 ? { critique_uptake: response.critique_uptake } : {},
|
|
6571
6666
|
// Source-grounded additive outputs (Tier-4 features).
|
|
6572
6667
|
...useSourceGrounded ? { source_grounded: true } : {},
|
|
6573
6668
|
...sourceExtras?.citation_grade !== void 0 ? { citation_grade: sourceExtras.citation_grade } : {},
|
|
@@ -6602,8 +6697,6 @@ function probeProviders(env = process.env) {
|
|
|
6602
6697
|
if ((env["ANTHROPIC_API_KEY"] ?? "").trim().length > 0) out.push("anthropic");
|
|
6603
6698
|
if ((env["OPENAI_API_KEY"] ?? "").trim().length > 0) out.push("openai");
|
|
6604
6699
|
if ((env["GOOGLE_API_KEY"] ?? "").trim().length > 0) out.push("google");
|
|
6605
|
-
if ((env["DEEPSEEK_API_KEY"] ?? "").trim().length > 0) out.push("deepseek");
|
|
6606
|
-
if ((env[META_MODEL_API_KEY_ENV] ?? "").trim().length > 0 || (env[META_MODEL_API_KEY_ALIAS] ?? "").trim().length > 0) out.push("meta");
|
|
6607
6700
|
return out;
|
|
6608
6701
|
}
|
|
6609
6702
|
async function loadFactoryAndCallers(injectedEngine, injectedShared) {
|
|
@@ -6950,7 +7043,7 @@ async function runLogin(opts = {}) {
|
|
|
6950
7043
|
const nowIso = opts.nowIso ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
6951
7044
|
const openBrowser = opts.openBrowser ?? defaultOpenBrowser;
|
|
6952
7045
|
const state = randomBytes(32).toString("base64url");
|
|
6953
|
-
return new Promise((
|
|
7046
|
+
return new Promise((resolve3, reject) => {
|
|
6954
7047
|
let settled = false;
|
|
6955
7048
|
const finish = (err, result) => {
|
|
6956
7049
|
if (settled) return;
|
|
@@ -6958,7 +7051,7 @@ async function runLogin(opts = {}) {
|
|
|
6958
7051
|
clearTimeout(timer);
|
|
6959
7052
|
server.close();
|
|
6960
7053
|
if (err) reject(err);
|
|
6961
|
-
else
|
|
7054
|
+
else resolve3(result);
|
|
6962
7055
|
};
|
|
6963
7056
|
const server = createServer2((req, res) => {
|
|
6964
7057
|
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
@@ -7073,7 +7166,7 @@ init_common();
|
|
|
7073
7166
|
function defaultCacheDbPath() {
|
|
7074
7167
|
const env = process.env["VO_MCP_DB_PATH"];
|
|
7075
7168
|
if (env && env.length > 0) return env;
|
|
7076
|
-
return
|
|
7169
|
+
return join9(homedir6(), ".claude", "vo-mcp-cache.db");
|
|
7077
7170
|
}
|
|
7078
7171
|
async function probeEngineVersion() {
|
|
7079
7172
|
try {
|