@algosuite/vo-mcp 0.2.0-beta.2 → 0.2.0-beta.4

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/index.js CHANGED
@@ -1122,9 +1122,15 @@ function createMemoryEventsWriter() {
1122
1122
  function readVoMcpVersion() {
1123
1123
  try {
1124
1124
  const here = dirname3(fileURLToPath2(import.meta.url));
1125
- const pkgPath = join4(here, "..", "..", "package.json");
1126
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
1127
- return typeof pkg.version === "string" ? pkg.version : "0.0.0-unknown";
1125
+ for (const rel of ["..", ["..", ".."], ["..", "..", ".."]]) {
1126
+ try {
1127
+ const segs = Array.isArray(rel) ? rel : [rel];
1128
+ const pkg = JSON.parse(readFileSync4(join4(here, ...segs, "package.json"), "utf8"));
1129
+ if (pkg.name === "@algosuite/vo-mcp" && typeof pkg.version === "string") return pkg.version;
1130
+ } catch {
1131
+ }
1132
+ }
1133
+ return "0.0.0-unknown";
1128
1134
  } catch {
1129
1135
  return "0.0.0-unknown";
1130
1136
  }
@@ -2044,6 +2050,8 @@ async function handleConsensusJudgment(deps, rawInput, signal) {
2044
2050
  ...engineResult.synthesized_verdict.confidence_badge !== void 0 ? { confidence_badge: engineResult.synthesized_verdict.confidence_badge } : {},
2045
2051
  // Feature 1 (agreement-gate) — fan-out diagnostics (present iff the gate ran).
2046
2052
  ...engineResult.fan_out_diagnostics !== void 0 ? { fan_out_diagnostics: engineResult.fan_out_diagnostics } : {},
2053
+ // Stage A7-shadow — adaptive-vs-incumbent comparison (PII-free; present iff shadow on).
2054
+ ...engineResult.shadow_synthesis !== void 0 ? { shadow_synthesis: engineResult.shadow_synthesis } : {},
2047
2055
  // Source-grounded Tier-4 outputs (present iff the call was source-grounded).
2048
2056
  ...engineResult.source_grounded === true ? { source_grounded: true } : {},
2049
2057
  ...engineResult.citation_grade !== void 0 ? { citation_grade: engineResult.citation_grade } : {},
@@ -4538,7 +4546,7 @@ var inputSchema19 = {
4538
4546
  required: ["operator_id", "session_id", "agent_type", "context_used_pct"],
4539
4547
  additionalProperties: false
4540
4548
  };
4541
- var description19 = "Reports per-session context-window utilization to VO and returns a directive: 'continue' (under 70%), 'prepare_handoff' (70-84%), or 'execute_handoff_now' (\u226585%). Implements V1 launch gate #9 (fleet context lifecycle management) per the official VO roadmap. V1 backend is stub-local \u2014 computes the directive purely from `context_used_pct` against the documented thresholds without a network call. Phase 3 wires this to the deployed vo-control-plane HTTP API; the response shape stays stable across the cutover (`backend_mode` field in the payload tells the caller which mode produced the verdict).";
4549
+ var description19 = "Reports per-session context-window utilization to VO and returns a directive: 'continue' (under 70%), 'prepare_handoff' (70-84%), or 'execute_handoff_now' (\u226585%). Implements V1 launch gate #9 (fleet context lifecycle management) per the official VO roadmap. Cloud-control-plane mode when VO_CONTROL_PLANE_URL + VO_CONTROL_PLANE_ADMIN_TOKEN + VO_TENANT_ID are set; auto-allocates the session on first report so interactive agents (Claude Code, Cursor, Codex, Continue) appear on the live fleet whiteboard. Stub-local fallback when cloud config is absent or fails. The response shape stays stable across modes (`backend_mode` field in the payload tells the caller which mode produced the verdict).";
4542
4550
  function isStringArray2(v, maxItems) {
4543
4551
  if (!Array.isArray(v)) return false;
4544
4552
  if (v.length > maxItems) return false;
@@ -4566,30 +4574,62 @@ function isToolInput19(v) {
4566
4574
  function getCloudConfig() {
4567
4575
  const url = process.env["VO_CONTROL_PLANE_URL"];
4568
4576
  const token = process.env["VO_CONTROL_PLANE_ADMIN_TOKEN"];
4569
- if (!url || !token) return null;
4570
- return { url, token };
4577
+ const tenant_id = process.env["VO_TENANT_ID"];
4578
+ if (!url || !token || !tenant_id) return null;
4579
+ return { url, token, tenant_id };
4571
4580
  }
4572
4581
  async function tryCloudReportState(cloud, input) {
4573
4582
  try {
4574
- const body = {
4583
+ const reportBody = {
4575
4584
  context_used_pct: input.context_used_pct
4576
4585
  };
4577
- if (input.current_goal !== void 0) body["current_goal"] = input.current_goal;
4586
+ if (input.current_goal !== void 0) reportBody["current_goal"] = input.current_goal;
4578
4587
  if (input.recent_files_touched !== void 0) {
4579
- body["recent_files_touched"] = input.recent_files_touched;
4588
+ reportBody["recent_files_touched"] = input.recent_files_touched;
4580
4589
  }
4581
4590
  if (input.recent_tool_uses !== void 0) {
4582
- body["recent_tool_uses"] = input.recent_tool_uses;
4591
+ reportBody["recent_tool_uses"] = input.recent_tool_uses;
4583
4592
  }
4584
- const url = `${cloud.url}/api/v1/session/${input.session_id}/report-state`;
4585
- const response = await fetch(url, {
4593
+ const reportUrl = `${cloud.url}/api/v1/session/${input.session_id}/report-state`;
4594
+ let response = await fetch(reportUrl, {
4586
4595
  method: "POST",
4587
4596
  headers: {
4588
4597
  "Content-Type": "application/json",
4589
4598
  "Authorization": `Bearer ${cloud.token}`
4590
4599
  },
4591
- body: JSON.stringify(body)
4600
+ body: JSON.stringify(reportBody)
4592
4601
  });
4602
+ if (response.status === 404) {
4603
+ const allocateBody = {
4604
+ operator_id: input.operator_id,
4605
+ tenant_id: cloud.tenant_id,
4606
+ agent_type: input.agent_type,
4607
+ current_goal: input.current_goal ?? "Interactive session"
4608
+ };
4609
+ if (input.context_used_pct > 0) {
4610
+ allocateBody["initial_context_used_pct"] = input.context_used_pct;
4611
+ }
4612
+ const allocateUrl = `${cloud.url}/api/v1/session`;
4613
+ const allocateResponse = await fetch(allocateUrl, {
4614
+ method: "POST",
4615
+ headers: {
4616
+ "Content-Type": "application/json",
4617
+ "Authorization": `Bearer ${cloud.token}`
4618
+ },
4619
+ body: JSON.stringify(allocateBody)
4620
+ });
4621
+ if (!allocateResponse.ok) {
4622
+ return null;
4623
+ }
4624
+ response = await fetch(reportUrl, {
4625
+ method: "POST",
4626
+ headers: {
4627
+ "Content-Type": "application/json",
4628
+ "Authorization": `Bearer ${cloud.token}`
4629
+ },
4630
+ body: JSON.stringify(reportBody)
4631
+ });
4632
+ }
4593
4633
  if (!response.ok) {
4594
4634
  return null;
4595
4635
  }
@@ -4890,14 +4930,13 @@ function isToolInput22(v) {
4890
4930
  return true;
4891
4931
  }
4892
4932
  function deriveProjectSlug(cwd) {
4893
- const normalized = cwd.replace(/\\/g, "/");
4894
- return normalized.replace(/^([A-Z]):/i, (_, drive) => `${drive.toUpperCase()}-`).replace(/\/$/g, "").split("/").join("--").replace(/\s+/g, "-");
4933
+ return cwd.replace(/\\/g, "/").replace(/\/+$/g, "").replace(/^([a-zA-Z]):/, (_m, drive) => `${drive.toUpperCase()}:`).replace(/[^a-zA-Z0-9]/g, "-");
4895
4934
  }
4896
4935
  function getMemoryDir(cwd) {
4897
4936
  const slug = deriveProjectSlug(cwd);
4898
4937
  return join7(homedir5(), ".claude", "projects", slug, "memory");
4899
4938
  }
4900
- async function pullMemory(controlPlaneUrl, token, memoryDir, sessionId, fetchFn) {
4939
+ async function pullMemory(controlPlaneUrl, token, memoryDir, fetchFn) {
4901
4940
  const url = `${controlPlaneUrl}/api/v1/agent-config/memory/me`;
4902
4941
  const response = await fetchFn(url, {
4903
4942
  method: "GET",
@@ -5010,103 +5049,53 @@ async function pushMemory(controlPlaneUrl, token, memoryDir, sessionId, fetchFn)
5010
5049
  }
5011
5050
  return { pushed: localFiles.length, created, updated };
5012
5051
  }
5013
- async function handleSyncConfig(deps, rawInput, _signal, fetchFn = globalThis.fetch) {
5014
- if (!isToolInput22(rawInput)) {
5015
- throw invalidParams(
5016
- TOOL_NAME22,
5017
- 'invalid input. Required: { action: "pull" | "push" }. Optional: { cwd: "<path>" }.'
5018
- );
5019
- }
5052
+ async function runMemorySync(action, cwd, sessionId, fetchFn = globalThis.fetch) {
5020
5053
  const controlPlaneUrl = process.env["VO_CONTROL_PLANE_URL"];
5021
5054
  if (!controlPlaneUrl) {
5022
- return jsonContent({
5023
- tool: TOOL_NAME22,
5024
- schema_version: 1,
5025
- payload: {
5026
- synced: false,
5027
- reason: "VO_CONTROL_PLANE_URL not set \u2014 cloud mode disabled"
5028
- }
5029
- });
5055
+ return { synced: false, reason: "VO_CONTROL_PLANE_URL not set \u2014 cloud mode disabled" };
5030
5056
  }
5031
5057
  const { createAuthTokenSourceFromEnv: createAuthTokenSourceFromEnv2 } = await Promise.resolve().then(() => (init_auth_token_source(), auth_token_source_exports));
5032
5058
  const { readStoredCredential: readStoredCredential2 } = await Promise.resolve().then(() => (init_credential_store(), credential_store_exports));
5033
5059
  const tokenSource = createAuthTokenSourceFromEnv2(process.env, fetchFn, () => readStoredCredential2(process.env));
5034
5060
  if (!tokenSource) {
5035
- return jsonContent({
5036
- tool: TOOL_NAME22,
5037
- schema_version: 1,
5038
- payload: {
5039
- synced: false,
5040
- reason: "No auth configured. Run `vo-mcp login` to authenticate as an operator."
5041
- }
5042
- });
5061
+ return { synced: false, reason: "No auth configured. Run `vo-mcp login` to authenticate as an operator." };
5043
5062
  }
5044
5063
  const token = await tokenSource.getToken();
5045
5064
  if (!token) {
5046
- return jsonContent({
5047
- tool: TOOL_NAME22,
5048
- schema_version: 1,
5049
- payload: {
5050
- synced: false,
5051
- reason: "Failed to obtain auth token. Run `vo-mcp login` to re-authenticate."
5052
- }
5053
- });
5065
+ return { synced: false, reason: "Failed to obtain auth token. Run `vo-mcp login` to re-authenticate." };
5054
5066
  }
5055
- const cwd = rawInput.cwd?.trim() || process.cwd();
5056
5067
  const memoryDir = getMemoryDir(cwd);
5068
+ const baseUrl = controlPlaneUrl.replace(/\/+$/, "");
5057
5069
  try {
5058
- if (rawInput.action === "pull") {
5059
- const result = await pullMemory(
5060
- controlPlaneUrl.replace(/\/+$/, ""),
5061
- token,
5062
- memoryDir,
5063
- deps.sessionId,
5064
- fetchFn
5065
- );
5066
- return jsonContent({
5067
- tool: TOOL_NAME22,
5068
- schema_version: 1,
5069
- payload: {
5070
- synced: true,
5071
- action: "pull",
5072
- pulled: result.pulled,
5073
- files: result.files,
5074
- memory_dir: memoryDir
5075
- }
5076
- });
5077
- } else {
5078
- const result = await pushMemory(
5079
- controlPlaneUrl.replace(/\/+$/, ""),
5080
- token,
5081
- memoryDir,
5082
- deps.sessionId,
5083
- fetchFn
5084
- );
5085
- return jsonContent({
5086
- tool: TOOL_NAME22,
5087
- schema_version: 1,
5088
- payload: {
5089
- synced: true,
5090
- action: "push",
5091
- pushed: result.pushed,
5092
- created: result.created,
5093
- updated: result.updated,
5094
- memory_dir: memoryDir
5095
- }
5096
- });
5070
+ if (action === "pull") {
5071
+ const result2 = await pullMemory(baseUrl, token, memoryDir, fetchFn);
5072
+ return { synced: true, action: "pull", pulled: result2.pulled, files: result2.files, memory_dir: memoryDir };
5097
5073
  }
5074
+ const result = await pushMemory(baseUrl, token, memoryDir, sessionId, fetchFn);
5075
+ return {
5076
+ synced: true,
5077
+ action: "push",
5078
+ pushed: result.pushed,
5079
+ created: result.created,
5080
+ updated: result.updated,
5081
+ memory_dir: memoryDir
5082
+ };
5098
5083
  } catch (err) {
5099
5084
  const message = err instanceof Error ? err.message : String(err);
5100
- return jsonContent({
5101
- tool: TOOL_NAME22,
5102
- schema_version: 1,
5103
- payload: {
5104
- synced: false,
5105
- reason: `Sync failed: ${message}`
5106
- }
5107
- });
5085
+ return { synced: false, reason: `Sync failed: ${message}` };
5108
5086
  }
5109
5087
  }
5088
+ async function handleSyncConfig(deps, rawInput, _signal, fetchFn = globalThis.fetch) {
5089
+ if (!isToolInput22(rawInput)) {
5090
+ throw invalidParams(
5091
+ TOOL_NAME22,
5092
+ 'invalid input. Required: { action: "pull" | "push" }. Optional: { cwd: "<path>" }.'
5093
+ );
5094
+ }
5095
+ const cwd = rawInput.cwd?.trim() || process.cwd();
5096
+ const result = await runMemorySync(rawInput.action, cwd, deps.session.sessionId, fetchFn);
5097
+ return jsonContent({ tool: TOOL_NAME22, schema_version: 1, payload: result });
5098
+ }
5110
5099
 
5111
5100
  // src/server.ts
5112
5101
  function buildToolRegistry() {
@@ -5621,6 +5610,25 @@ function mapFanOutDiagnostics(fd) {
5621
5610
  refused: fd.refused
5622
5611
  };
5623
5612
  }
5613
+ var SHADOW_SYNTHESIS_ENV_VAR = "VO_CONSENSUS_SHADOW";
5614
+ function shadowEnabled(env) {
5615
+ const raw = (env ?? {})[SHADOW_SYNTHESIS_ENV_VAR];
5616
+ if (raw === void 0) return true;
5617
+ const norm = raw.trim().toLowerCase();
5618
+ return !(norm === "0" || norm === "false" || norm === "no" || norm === "off" || norm === "");
5619
+ }
5620
+ function mapShadowSynthesis(s) {
5621
+ if (s === void 0) return void 0;
5622
+ return {
5623
+ incumbent: { verdict: s.incumbent.verdict, confidence: s.incumbent.confidence, synthesizer: s.incumbent.synthesizer },
5624
+ adaptive: {
5625
+ verdict: s.adaptive.verdict,
5626
+ confidence: s.adaptive.confidence,
5627
+ ...s.adaptive.calibrated_confidence !== void 0 ? { calibrated_confidence: s.adaptive.calibrated_confidence } : {}
5628
+ },
5629
+ agree: s.agree
5630
+ };
5631
+ }
5624
5632
  function mapCitationGrade(cg) {
5625
5633
  if (cg === void 0) return void 0;
5626
5634
  return {
@@ -5761,7 +5769,12 @@ function createEngineConsensusClient(options) {
5761
5769
  const engineOptions = {
5762
5770
  panel,
5763
5771
  ...options.per_model_timeout_ms !== void 0 ? { per_model_timeout_ms: options.per_model_timeout_ms } : {},
5764
- ...agreementGate !== void 0 ? { agreement_gate: agreementGate } : {}
5772
+ ...agreementGate !== void 0 ? { agreement_gate: agreementGate } : {},
5773
+ // Stage A7-shadow: run the adaptive verdict alongside the live one for grading.
5774
+ // Cheap (pure log-odds over already-fetched verdicts; no extra model calls),
5775
+ // PII-free, and never alters the live verdict. ON by default; kill with
5776
+ // VO_CONSENSUS_SHADOW=0. Cold-start has no skill registry → neutral priors.
5777
+ shadow_synthesis: { enabled: shadowEnabled(options.env) }
5765
5778
  };
5766
5779
  const sources = request.source_urls;
5767
5780
  const useSourceGrounded = sources !== void 0 && sources.length > 0 && typeof engine.runSourceGroundedConsensus === "function";
@@ -5817,6 +5830,8 @@ function createEngineConsensusClient(options) {
5817
5830
  ...sourceExtras?.escalation_reason !== void 0 ? { escalation_reason: sourceExtras.escalation_reason } : response.escalation_reason !== void 0 ? { escalation_reason: response.escalation_reason } : {},
5818
5831
  // Feature 1 (agreement-gate) — fan-out diagnostics (additive telemetry).
5819
5832
  ...mapFanOutDiagnostics(response.fan_out_diagnostics) !== void 0 ? { fan_out_diagnostics: mapFanOutDiagnostics(response.fan_out_diagnostics) } : {},
5833
+ // Stage A7-shadow — adaptive-vs-incumbent comparison (PII-free; present iff shadow on).
5834
+ ...mapShadowSynthesis(response.shadow_synthesis) !== void 0 ? { shadow_synthesis: mapShadowSynthesis(response.shadow_synthesis) } : {},
5820
5835
  // Source-grounded additive outputs (Tier-4 features).
5821
5836
  ...useSourceGrounded ? { source_grounded: true } : {},
5822
5837
  ...sourceExtras?.citation_grade !== void 0 ? { citation_grade: sourceExtras.citation_grade } : {},