@hiveai/mcp 0.9.30 → 0.10.0

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/server.d.ts CHANGED
@@ -158,6 +158,14 @@ interface BriefingOutput {
158
158
  * Clients can use this flag to skip surfacing a near-empty briefing to the model.
159
159
  */
160
160
  low_value?: true;
161
+ /**
162
+ * Whether this briefing carries knowledge a capable model could NOT have inferred on its own.
163
+ * - "high": at least one surfaced memory is arbitrary/team-specific (unguessable).
164
+ * - "low": nothing team-specific matched — a generic agent would reach the same answer.
165
+ * When "low" and the project context is still auto-generated/template, the adaptive briefing
166
+ * trims that inferable context to keep the call near-zero-cost (config: adaptiveBriefing).
167
+ */
168
+ briefing_value?: "high" | "low";
161
169
  /**
162
170
  * Short, action-oriented hints surfaced to the agent based on the briefing payload.
163
171
  * Examples: "haive is uninitialized — use Read/Grep directly", "gotcha memories present — read first".
package/dist/server.js CHANGED
@@ -1074,6 +1074,7 @@ import { existsSync as existsSync15 } from "fs";
1074
1074
  import path6 from "path";
1075
1075
  import {
1076
1076
  buildFrontmatter as buildFrontmatter3,
1077
+ isLikelyGuessable,
1077
1078
  memoryFilePath as memoryFilePath3,
1078
1079
  serializeMemory as serializeMemory7
1079
1080
  } from "@hiveai/core";
@@ -1086,12 +1087,25 @@ var MemObserveInputSchema = {
1086
1087
  scope: z15.enum(["personal", "team", "module"]).default("team").describe("Visibility scope \u2014 defaults to team since discoveries benefit everyone"),
1087
1088
  module: z15.string().optional().describe("Module name (required when scope=module)"),
1088
1089
  tags: z15.array(z15.string()).default([]).describe("Tags for filtering"),
1089
- author: z15.string().optional().describe("Author handle or email")
1090
+ author: z15.string().optional().describe("Author handle or email"),
1091
+ force: z15.boolean().default(false).describe(
1092
+ "Save even if the observation looks like generic, guessable knowledge. By default, low-specificity observations (things a capable model already knows) are SKIPPED to keep the corpus high-signal \u2014 only unguessable, team-specific discoveries are worth storing."
1093
+ )
1090
1094
  };
1091
1095
  async function memObserve(input, ctx) {
1092
1096
  if (!existsSync15(ctx.paths.haiveDir)) {
1093
1097
  throw new Error(`No .ai/ directory at ${ctx.paths.root}. Run 'haive init' first.`);
1094
1098
  }
1099
+ const signalText = [input.what, input.impact, input.fix ?? ""].join(" ");
1100
+ if (!input.force && isLikelyGuessable(signalText)) {
1101
+ return {
1102
+ id: "",
1103
+ scope: input.scope,
1104
+ file_path: "",
1105
+ skipped: true,
1106
+ reason: "Observation looks like generic, guessable knowledge (low specificity) \u2014 not saved. Capture only arbitrary, team-specific facts (exact names, values, formats). Pass force=true to override."
1107
+ };
1108
+ }
1095
1109
  const slug = input.what.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim().split(/\s+/).slice(0, 6).join("-");
1096
1110
  const anchorPaths = input.where.split(/[,\n]/).map((s) => s.trim()).filter(Boolean);
1097
1111
  const baseFm = buildFrontmatter3({
@@ -1412,6 +1426,8 @@ import {
1412
1426
  queryCodeMap,
1413
1427
  resolveBriefingBudget,
1414
1428
  serializeMemory as serializeMemory9,
1429
+ specificityScore,
1430
+ GUESSABLE_THRESHOLD,
1415
1431
  tokenizeQuery as tokenizeQuery2,
1416
1432
  trackReads as trackReads3,
1417
1433
  truncateToTokens,
@@ -1837,6 +1853,14 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
1837
1853
  const memoriesEmpty = outputMemories.length === 0;
1838
1854
  const hasMemoriesDir = existsSync18(ctx.paths.memoriesDir);
1839
1855
  const isColdStart = isTemplateContext && memoriesEmpty && !lastSession && !autoContextGenerated;
1856
+ const hasUnguessableSignal = outputMemories.some(
1857
+ (m) => (m.priority === "must_read" || m.priority === "useful") && specificityScore(m.body) >= GUESSABLE_THRESHOLD
1858
+ );
1859
+ const briefingValueLow = !hasUnguessableSignal;
1860
+ const adaptiveConfig = await loadConfig3(ctx.paths);
1861
+ const bootstrapUnfilled = /Auto-generated by `haive init/i.test(projectContextRaw) && (projectContextRaw.match(/TODO —/g)?.length ?? 0) >= 2;
1862
+ const contextIsInferable = isTemplateContext || autoContextGenerated || bootstrapUnfilled;
1863
+ const adaptiveTrim = adaptiveConfig.adaptiveBriefing !== false && briefingValueLow && contextIsInferable;
1840
1864
  const hints = [];
1841
1865
  if (isColdStart) {
1842
1866
  hints.push(
@@ -1869,6 +1893,11 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
1869
1893
  );
1870
1894
  }
1871
1895
  }
1896
+ if (adaptiveTrim) {
1897
+ hints.push(
1898
+ "No team-specific policy matched these files/task \u2014 nothing here a capable model can't infer. The auto-generated project context was trimmed to keep this briefing near-zero-cost; proceed with normal Read/Grep."
1899
+ );
1900
+ }
1872
1901
  if (existsSync18(ctx.paths.haiveDir)) {
1873
1902
  await writeBriefingMarker(ctx.paths, {
1874
1903
  sessionId: process.env.HAIVE_SESSION_ID,
@@ -1884,7 +1913,12 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
1884
1913
  search_mode: searchMode,
1885
1914
  inferred_modules: inferred,
1886
1915
  ...lastSession ? { last_session: lastSession } : {},
1887
- project_context: projectContextRaw || autoContextGenerated ? {
1916
+ project_context: adaptiveTrim ? {
1917
+ content: "(adaptive briefing: auto-generated context omitted \u2014 no team-specific policy matched, so a capable model needs nothing extra here)",
1918
+ truncated: false,
1919
+ ...isTemplateContext && !autoContextGenerated ? { is_template: true } : {},
1920
+ ...autoContextGenerated ? { auto_generated: true } : {}
1921
+ } : projectContextRaw || autoContextGenerated ? {
1888
1922
  content: projectSlice.text,
1889
1923
  truncated: projectSlice.truncated,
1890
1924
  ...isTemplateContext && !autoContextGenerated ? { is_template: true } : {},
@@ -1898,6 +1932,7 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
1898
1932
  decay_warnings: decayWarnings,
1899
1933
  setup_warnings: setupWarnings,
1900
1934
  ...isColdStart ? { low_value: true } : {},
1935
+ briefing_value: briefingValueLow ? "low" : "high",
1901
1936
  ...hints.length > 0 ? { hints } : {},
1902
1937
  estimated_tokens: totalTokens,
1903
1938
  budget: {
@@ -2473,8 +2508,12 @@ var CODE_STOPWORDS = /* @__PURE__ */ new Set([
2473
2508
  "console"
2474
2509
  ]);
2475
2510
  function tokenizeDiffForLiteral(diff) {
2476
- const wsTokens = tokenizeQuery3(diff);
2477
- const wordTokens = diff.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 4 && !CODE_STOPWORDS.has(t));
2511
+ const lines = diff.split("\n");
2512
+ const looksLikeDiff = lines.some((l) => /^[+-]/.test(l));
2513
+ const addedOnly = looksLikeDiff ? lines.filter((l) => l.startsWith("+") && !l.startsWith("+++")).join("\n") : diff;
2514
+ const source = addedOnly.trim().length > 0 ? addedOnly : diff;
2515
+ const wsTokens = tokenizeQuery3(source);
2516
+ const wordTokens = source.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 4 && !CODE_STOPWORDS.has(t));
2478
2517
  return [.../* @__PURE__ */ new Set([...wsTokens, ...wordTokens])];
2479
2518
  }
2480
2519
  async function antiPatternsCheck(input, ctx) {
@@ -3825,7 +3864,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
3825
3864
  // src/server.ts
3826
3865
  import { loadConfigSync } from "@hiveai/core";
3827
3866
  var SERVER_NAME = "haive";
3828
- var SERVER_VERSION = "0.9.30";
3867
+ var SERVER_VERSION = "0.10.0";
3829
3868
  function jsonResult(data) {
3830
3869
  return {
3831
3870
  content: [