@algosuite/vo-mcp 0.2.0-beta.38 → 0.2.0-beta.39
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/agent-auth-probe-cli.mjs +10 -5
- package/dist/cli.js +58 -0
- package/dist/cli.js.map +2 -2
- package/dist/index.js +56 -0
- package/dist/index.js.map +2 -2
- package/dist/runner-cli.js +181 -30
- package/dist/runner-cli.js.map +4 -4
- package/dist/runner-supervisor.js +36 -0
- package/dist/runner-supervisor.js.map +3 -3
- package/package.json +1 -1
|
@@ -290,6 +290,7 @@ var VO_SESSION_STATE_TOOL = "mcp__vo-mcp__vo_report_session_state";
|
|
|
290
290
|
var VO_HEADLESS_PNPM_TOOL = "Bash(pnpm *)";
|
|
291
291
|
var VO_HEADLESS_PNPM_FROM_DIR_TOOL = "Bash(pnpm --dir *)";
|
|
292
292
|
var VO_RESEARCH_TOOLS = ["WebFetch", "WebSearch"];
|
|
293
|
+
var VO_WORKFLOW_TOOLS = ["Workflow"];
|
|
293
294
|
var SAFE_PERMISSION_MODES = /* @__PURE__ */ new Set(["acceptEdits", "plan", "default", "dontAsk", "delegate"]);
|
|
294
295
|
function normalizeClaudePermissionMode(value) {
|
|
295
296
|
const normalized = String(value ?? "").trim() || DEFAULT_PERMISSION_MODE;
|
|
@@ -298,11 +299,14 @@ function normalizeClaudePermissionMode(value) {
|
|
|
298
299
|
}
|
|
299
300
|
return normalized;
|
|
300
301
|
}
|
|
301
|
-
function buildClaudeArgs({ permissionMode = DEFAULT_PERMISSION_MODE, maxTurns, model, effort, maxBudgetUsd, env = process.env } = {}) {
|
|
302
|
+
function buildClaudeArgs({ permissionMode = DEFAULT_PERMISSION_MODE, maxTurns, model, effort, maxBudgetUsd, researchHarness = false, env = process.env } = {}) {
|
|
302
303
|
const effectivePermissionMode = normalizeClaudePermissionMode(permissionMode);
|
|
303
|
-
const
|
|
304
|
+
const noWeb = String(env?.VO_CODE_RUNNER_NO_WEB ?? "").trim() === "1";
|
|
305
|
+
const research = noWeb ? [] : VO_RESEARCH_TOOLS;
|
|
306
|
+
const noWorkflow = noWeb || String(env?.VO_CODE_RUNNER_NO_WORKFLOW ?? "").trim() === "1";
|
|
307
|
+
const workflow = researchHarness === true && !noWorkflow ? VO_WORKFLOW_TOOLS : [];
|
|
304
308
|
const baseTools = effectivePermissionMode === DEFAULT_PERMISSION_MODE ? [VO_SESSION_STATE_TOOL, VO_HEADLESS_PNPM_TOOL, VO_HEADLESS_PNPM_FROM_DIR_TOOL] : [VO_SESSION_STATE_TOOL];
|
|
305
|
-
const allowedTools = [...baseTools, ...research].join(",");
|
|
309
|
+
const allowedTools = [...baseTools, ...research, ...workflow].join(",");
|
|
306
310
|
const args = [
|
|
307
311
|
"-p",
|
|
308
312
|
"--output-format",
|
|
@@ -341,6 +345,7 @@ import path2 from "node:path";
|
|
|
341
345
|
// ../../scripts/virtual-office/code-runner/agent-token-usage.mjs
|
|
342
346
|
var MAX_TOKEN_COUNT = 1e9;
|
|
343
347
|
var MAX_COST_USD = 1e4;
|
|
348
|
+
var NO_AGENT_SPAWNED_ECONOMICS = Object.freeze({ cost_usd: 0, cost_basis: "no_agent_spawned" });
|
|
344
349
|
function count(value) {
|
|
345
350
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return null;
|
|
346
351
|
return Math.min(MAX_TOKEN_COUNT, Math.round(value));
|
|
@@ -615,8 +620,8 @@ var ClaudeRunner = class {
|
|
|
615
620
|
get binary() {
|
|
616
621
|
return "claude";
|
|
617
622
|
}
|
|
618
|
-
buildArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd } = {}) {
|
|
619
|
-
return buildClaudeArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd });
|
|
623
|
+
buildArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd, researchHarness } = {}) {
|
|
624
|
+
return buildClaudeArgs({ permissionMode, maxTurns, model, effort, maxBudgetUsd, researchHarness });
|
|
620
625
|
}
|
|
621
626
|
parseEvent(line) {
|
|
622
627
|
return parseStreamEvent(line);
|
package/dist/cli.js
CHANGED
|
@@ -3009,6 +3009,8 @@ async function handleVerifyAnswer(deps, rawInput, signal) {
|
|
|
3009
3009
|
engine_version: engineResult.engine_version,
|
|
3010
3010
|
degraded: engineResult.degraded,
|
|
3011
3011
|
...engineResult.quorum_failed === true ? { quorum_failed: true } : {},
|
|
3012
|
+
// The verification receipt (moat decision_id) — the thing an agent pastes as `receipt id: <uuid>`.
|
|
3013
|
+
...engineResult.receipt_id ? { receipt_id: engineResult.receipt_id } : {},
|
|
3012
3014
|
gate_type: gateType,
|
|
3013
3015
|
...kbResult.error !== null ? { kb_unavailable: true } : {},
|
|
3014
3016
|
...kbTruncated > 0 ? { kb_rules_truncated: kbTruncated } : {}
|
|
@@ -3276,6 +3278,10 @@ async function handleConsensusJudgment(deps, rawInput, signal) {
|
|
|
3276
3278
|
engine_version: engineResult.engine_version,
|
|
3277
3279
|
degraded: engineResult.degraded,
|
|
3278
3280
|
...engineResult.quorum_failed === true ? { quorum_failed: true } : {},
|
|
3281
|
+
// The verification receipt (moat decision_id) — the thing an agent pastes as `receipt id: <uuid>`.
|
|
3282
|
+
// NOTE: a content-hash cache hit replays the ORIGINAL call's receipt_id (same claim, same verdict, no new spend) —
|
|
3283
|
+
// a receipt asserts the stage ran for this claim, not one-receipt-per-call.
|
|
3284
|
+
...engineResult.receipt_id ? { receipt_id: engineResult.receipt_id } : {},
|
|
3279
3285
|
gate_type: gateType,
|
|
3280
3286
|
// ─── Consensus-engine feature outputs (additive; 2026-06-13) ─────────────
|
|
3281
3287
|
// Feature 2 (calibrated-confidence) — ON by default; the engine attaches
|
|
@@ -6758,6 +6764,7 @@ init_common();
|
|
|
6758
6764
|
var UPSERT_TOOL_NAME = "vo_private_knowledge_upsert";
|
|
6759
6765
|
var CONTEXT_TOOL_NAME = "vo_private_knowledge_context";
|
|
6760
6766
|
var INVALIDATE_TOOL_NAME = "vo_private_knowledge_invalidate";
|
|
6767
|
+
var STALE_TOOL_NAME = "vo_private_knowledge_stale";
|
|
6761
6768
|
var KNOWLEDGE_CLASSES = ["memory", "skill", "doctrine", "hook", "command"];
|
|
6762
6769
|
var PRECISION_CHAR_BUDGET = 12e3;
|
|
6763
6770
|
var upsertInputSchema = {
|
|
@@ -6790,9 +6797,26 @@ var invalidateInputSchema = {
|
|
|
6790
6797
|
required: ["knowledge_class", "source_path"],
|
|
6791
6798
|
additionalProperties: false
|
|
6792
6799
|
};
|
|
6800
|
+
var staleInputSchema = {
|
|
6801
|
+
type: "object",
|
|
6802
|
+
properties: {
|
|
6803
|
+
days: { type: "number", minimum: 1, maximum: 3650, description: "Window in days (default 90): entries at least this old that were never recalled into an agent context, or not within the window." },
|
|
6804
|
+
limit: { type: "number", minimum: 1, maximum: 500 }
|
|
6805
|
+
},
|
|
6806
|
+
additionalProperties: false
|
|
6807
|
+
};
|
|
6808
|
+
var staleDescription = `The FORGETTING REPORT: lists the authenticated operator\u2019s live private-knowledge entries that are at least N days old and have never been recalled into an agent context (or not within N days). Metadata only. SURFACES ONLY \u2014 never auto-invalidates or auto-merges: two memories that disagree may both have been right in different contexts, so you decide. Act on a candidate deliberately with ${INVALIDATE_TOOL_NAME}; recall counts come from ${CONTEXT_TOOL_NAME} reads that actually placed the entry into returned context.`;
|
|
6793
6809
|
var upsertDescription = "Uploads or refreshes the authenticated operator\u2019s private cloud knowledge. Works for Claude, Codex, Cursor, and cowork clients via the same vo-mcp login credential. Returns metadata only, not raw stored content. PRECISION DISCIPLINE: keep each entry tight and focused (~1-3 pages) with a descriptive retrieval-friendly title \u2014 retrieval surfaces whole entries, so small dense entries beat bulk dumps. Split large corpora into focused entries, then run a retrieval self-test via vo_private_knowledge_context before relying on the knowledge.";
|
|
6794
6810
|
var contextDescription = "Retrieves prompt-ready private knowledge context for the authenticated operator. Returns snippets/context only; no raw corpus download. Also the retrieval self-test surface: after upserting critical knowledge, query for it here and confirm the entry surfaces before trusting it in downstream work.";
|
|
6795
6811
|
var invalidateDescription = `Soft-deletes one private-knowledge entry for the authenticated operator: closes the live entry\u2019s validity window (bi-temporal) so it stops surfacing in retrieval. Never destroys data \u2014 invalidated versions remain queryable server-side via include_invalidated. Identify the entry by the same { knowledge_class, source_path } used at upsert; a not_found response means no live entry matches. After invalidating, self-test via ${CONTEXT_TOOL_NAME} to confirm the entry no longer surfaces.`;
|
|
6812
|
+
function isStaleInput(value) {
|
|
6813
|
+
if (value === void 0 || value === null) return true;
|
|
6814
|
+
if (typeof value !== "object") return false;
|
|
6815
|
+
const input = value;
|
|
6816
|
+
if (input["days"] !== void 0 && typeof input["days"] !== "number") return false;
|
|
6817
|
+
if (input["limit"] !== void 0 && typeof input["limit"] !== "number") return false;
|
|
6818
|
+
return true;
|
|
6819
|
+
}
|
|
6796
6820
|
function isKnowledgeClass(value) {
|
|
6797
6821
|
return typeof value === "string" && KNOWLEDGE_CLASSES.includes(value);
|
|
6798
6822
|
}
|
|
@@ -6872,6 +6896,30 @@ async function handlePrivateKnowledgeInvalidate(_deps, rawInput, _signal, fetchF
|
|
|
6872
6896
|
const payload = await callPrivateKnowledge("/api/v1/knowledge/private/invalidate", rawInput, fetchFn);
|
|
6873
6897
|
return jsonContent({ tool: INVALIDATE_TOOL_NAME, schema_version: 1, payload });
|
|
6874
6898
|
}
|
|
6899
|
+
async function handlePrivateKnowledgeStale(_deps, rawInput, _signal, fetchFn = globalThis.fetch) {
|
|
6900
|
+
if (!isStaleInput(rawInput)) {
|
|
6901
|
+
throw invalidParams(STALE_TOOL_NAME, "expected { optional days, optional limit }.");
|
|
6902
|
+
}
|
|
6903
|
+
const auth = await getCloudAuth(fetchFn);
|
|
6904
|
+
if (!auth.ok) return jsonContent({ tool: STALE_TOOL_NAME, schema_version: 1, payload: { ok: false, reason: auth.reason } });
|
|
6905
|
+
const params = new URLSearchParams();
|
|
6906
|
+
if (rawInput?.days !== void 0) params.set("days", String(Math.trunc(rawInput.days)));
|
|
6907
|
+
if (rawInput?.limit !== void 0) params.set("limit", String(Math.trunc(rawInput.limit)));
|
|
6908
|
+
const qs = params.toString();
|
|
6909
|
+
const response = await fetchFn(`${auth.controlPlaneUrl}/api/v1/knowledge/private/stale${qs ? `?${qs}` : ""}`, {
|
|
6910
|
+
method: "GET",
|
|
6911
|
+
headers: { authorization: `Bearer ${auth.token}` }
|
|
6912
|
+
});
|
|
6913
|
+
const text = await response.text();
|
|
6914
|
+
let parsed;
|
|
6915
|
+
try {
|
|
6916
|
+
parsed = text ? JSON.parse(text) : null;
|
|
6917
|
+
} catch {
|
|
6918
|
+
parsed = null;
|
|
6919
|
+
}
|
|
6920
|
+
const payload = response.status < 200 || response.status >= 300 ? { ok: false, status: response.status, response: parsed ?? text } : parsed;
|
|
6921
|
+
return jsonContent({ tool: STALE_TOOL_NAME, schema_version: 1, payload });
|
|
6922
|
+
}
|
|
6875
6923
|
async function handlePrivateKnowledgeContext(_deps, rawInput, _signal, fetchFn = globalThis.fetch) {
|
|
6876
6924
|
if (!isContextInput(rawInput)) {
|
|
6877
6925
|
throw invalidParams(CONTEXT_TOOL_NAME, "expected { query, optional limit, optional knowledge_class }.");
|
|
@@ -7416,6 +7464,14 @@ function buildToolRegistry() {
|
|
|
7416
7464
|
},
|
|
7417
7465
|
handler: handlePrivateKnowledgeInvalidate
|
|
7418
7466
|
},
|
|
7467
|
+
[STALE_TOOL_NAME]: {
|
|
7468
|
+
definition: {
|
|
7469
|
+
name: STALE_TOOL_NAME,
|
|
7470
|
+
description: staleDescription,
|
|
7471
|
+
inputSchema: staleInputSchema
|
|
7472
|
+
},
|
|
7473
|
+
handler: handlePrivateKnowledgeStale
|
|
7474
|
+
},
|
|
7419
7475
|
[POST_TOOL_NAME]: {
|
|
7420
7476
|
definition: {
|
|
7421
7477
|
name: POST_TOOL_NAME,
|
|
@@ -8272,8 +8328,10 @@ function createMoatConsensusClient(opts) {
|
|
|
8272
8328
|
}
|
|
8273
8329
|
const agreeing = normalizeAgreeing(parsed.models_agreeing);
|
|
8274
8330
|
const reasoning = agreeing !== void 0 ? `${parsed.reason} (${agreeing} models agreeing)` : parsed.reason;
|
|
8331
|
+
const receiptId = typeof parsed.decision_id === "string" && parsed.decision_id.trim().length > 0 ? parsed.decision_id.trim().slice(0, 120) : null;
|
|
8275
8332
|
return {
|
|
8276
8333
|
ok: true,
|
|
8334
|
+
...receiptId ? { receipt_id: receiptId } : {},
|
|
8277
8335
|
synthesized_verdict: {
|
|
8278
8336
|
verdict: parsed.approved ? "pass" : "fail",
|
|
8279
8337
|
confidence: normalizeConfidence(parsed.confidence),
|