@hiveai/mcp 0.9.31 → 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/index.js +44 -5
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +8 -0
- package/dist/server.js +44 -5
- package/dist/server.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1076,6 +1076,7 @@ import { existsSync as existsSync15 } from "fs";
|
|
|
1076
1076
|
import path6 from "path";
|
|
1077
1077
|
import {
|
|
1078
1078
|
buildFrontmatter as buildFrontmatter3,
|
|
1079
|
+
isLikelyGuessable,
|
|
1079
1080
|
memoryFilePath as memoryFilePath3,
|
|
1080
1081
|
serializeMemory as serializeMemory7
|
|
1081
1082
|
} from "@hiveai/core";
|
|
@@ -1088,12 +1089,25 @@ var MemObserveInputSchema = {
|
|
|
1088
1089
|
scope: z15.enum(["personal", "team", "module"]).default("team").describe("Visibility scope \u2014 defaults to team since discoveries benefit everyone"),
|
|
1089
1090
|
module: z15.string().optional().describe("Module name (required when scope=module)"),
|
|
1090
1091
|
tags: z15.array(z15.string()).default([]).describe("Tags for filtering"),
|
|
1091
|
-
author: z15.string().optional().describe("Author handle or email")
|
|
1092
|
+
author: z15.string().optional().describe("Author handle or email"),
|
|
1093
|
+
force: z15.boolean().default(false).describe(
|
|
1094
|
+
"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."
|
|
1095
|
+
)
|
|
1092
1096
|
};
|
|
1093
1097
|
async function memObserve(input, ctx) {
|
|
1094
1098
|
if (!existsSync15(ctx.paths.haiveDir)) {
|
|
1095
1099
|
throw new Error(`No .ai/ directory at ${ctx.paths.root}. Run 'haive init' first.`);
|
|
1096
1100
|
}
|
|
1101
|
+
const signalText = [input.what, input.impact, input.fix ?? ""].join(" ");
|
|
1102
|
+
if (!input.force && isLikelyGuessable(signalText)) {
|
|
1103
|
+
return {
|
|
1104
|
+
id: "",
|
|
1105
|
+
scope: input.scope,
|
|
1106
|
+
file_path: "",
|
|
1107
|
+
skipped: true,
|
|
1108
|
+
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."
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1097
1111
|
const slug = input.what.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim().split(/\s+/).slice(0, 6).join("-");
|
|
1098
1112
|
const anchorPaths = input.where.split(/[,\n]/).map((s) => s.trim()).filter(Boolean);
|
|
1099
1113
|
const baseFm = buildFrontmatter3({
|
|
@@ -1414,6 +1428,8 @@ import {
|
|
|
1414
1428
|
queryCodeMap,
|
|
1415
1429
|
resolveBriefingBudget,
|
|
1416
1430
|
serializeMemory as serializeMemory9,
|
|
1431
|
+
specificityScore,
|
|
1432
|
+
GUESSABLE_THRESHOLD,
|
|
1417
1433
|
tokenizeQuery as tokenizeQuery2,
|
|
1418
1434
|
trackReads as trackReads3,
|
|
1419
1435
|
truncateToTokens,
|
|
@@ -1839,6 +1855,14 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
|
|
|
1839
1855
|
const memoriesEmpty = outputMemories.length === 0;
|
|
1840
1856
|
const hasMemoriesDir = existsSync18(ctx.paths.memoriesDir);
|
|
1841
1857
|
const isColdStart = isTemplateContext && memoriesEmpty && !lastSession && !autoContextGenerated;
|
|
1858
|
+
const hasUnguessableSignal = outputMemories.some(
|
|
1859
|
+
(m) => (m.priority === "must_read" || m.priority === "useful") && specificityScore(m.body) >= GUESSABLE_THRESHOLD
|
|
1860
|
+
);
|
|
1861
|
+
const briefingValueLow = !hasUnguessableSignal;
|
|
1862
|
+
const adaptiveConfig = await loadConfig3(ctx.paths);
|
|
1863
|
+
const bootstrapUnfilled = /Auto-generated by `haive init/i.test(projectContextRaw) && (projectContextRaw.match(/TODO —/g)?.length ?? 0) >= 2;
|
|
1864
|
+
const contextIsInferable = isTemplateContext || autoContextGenerated || bootstrapUnfilled;
|
|
1865
|
+
const adaptiveTrim = adaptiveConfig.adaptiveBriefing !== false && briefingValueLow && contextIsInferable;
|
|
1842
1866
|
const hints = [];
|
|
1843
1867
|
if (isColdStart) {
|
|
1844
1868
|
hints.push(
|
|
@@ -1871,6 +1895,11 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
|
|
|
1871
1895
|
);
|
|
1872
1896
|
}
|
|
1873
1897
|
}
|
|
1898
|
+
if (adaptiveTrim) {
|
|
1899
|
+
hints.push(
|
|
1900
|
+
"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."
|
|
1901
|
+
);
|
|
1902
|
+
}
|
|
1874
1903
|
if (existsSync18(ctx.paths.haiveDir)) {
|
|
1875
1904
|
await writeBriefingMarker(ctx.paths, {
|
|
1876
1905
|
sessionId: process.env.HAIVE_SESSION_ID,
|
|
@@ -1886,7 +1915,12 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
|
|
|
1886
1915
|
search_mode: searchMode,
|
|
1887
1916
|
inferred_modules: inferred,
|
|
1888
1917
|
...lastSession ? { last_session: lastSession } : {},
|
|
1889
|
-
project_context:
|
|
1918
|
+
project_context: adaptiveTrim ? {
|
|
1919
|
+
content: "(adaptive briefing: auto-generated context omitted \u2014 no team-specific policy matched, so a capable model needs nothing extra here)",
|
|
1920
|
+
truncated: false,
|
|
1921
|
+
...isTemplateContext && !autoContextGenerated ? { is_template: true } : {},
|
|
1922
|
+
...autoContextGenerated ? { auto_generated: true } : {}
|
|
1923
|
+
} : projectContextRaw || autoContextGenerated ? {
|
|
1890
1924
|
content: projectSlice.text,
|
|
1891
1925
|
truncated: projectSlice.truncated,
|
|
1892
1926
|
...isTemplateContext && !autoContextGenerated ? { is_template: true } : {},
|
|
@@ -1900,6 +1934,7 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
|
|
|
1900
1934
|
decay_warnings: decayWarnings,
|
|
1901
1935
|
setup_warnings: setupWarnings,
|
|
1902
1936
|
...isColdStart ? { low_value: true } : {},
|
|
1937
|
+
briefing_value: briefingValueLow ? "low" : "high",
|
|
1903
1938
|
...hints.length > 0 ? { hints } : {},
|
|
1904
1939
|
estimated_tokens: totalTokens,
|
|
1905
1940
|
budget: {
|
|
@@ -2475,8 +2510,12 @@ var CODE_STOPWORDS = /* @__PURE__ */ new Set([
|
|
|
2475
2510
|
"console"
|
|
2476
2511
|
]);
|
|
2477
2512
|
function tokenizeDiffForLiteral(diff) {
|
|
2478
|
-
const
|
|
2479
|
-
const
|
|
2513
|
+
const lines = diff.split("\n");
|
|
2514
|
+
const looksLikeDiff = lines.some((l) => /^[+-]/.test(l));
|
|
2515
|
+
const addedOnly = looksLikeDiff ? lines.filter((l) => l.startsWith("+") && !l.startsWith("+++")).join("\n") : diff;
|
|
2516
|
+
const source = addedOnly.trim().length > 0 ? addedOnly : diff;
|
|
2517
|
+
const wsTokens = tokenizeQuery3(source);
|
|
2518
|
+
const wordTokens = source.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 4 && !CODE_STOPWORDS.has(t));
|
|
2480
2519
|
return [.../* @__PURE__ */ new Set([...wsTokens, ...wordTokens])];
|
|
2481
2520
|
}
|
|
2482
2521
|
async function antiPatternsCheck(input, ctx) {
|
|
@@ -3827,7 +3866,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
3827
3866
|
// src/server.ts
|
|
3828
3867
|
import { loadConfigSync } from "@hiveai/core";
|
|
3829
3868
|
var SERVER_NAME = "haive";
|
|
3830
|
-
var SERVER_VERSION = "0.
|
|
3869
|
+
var SERVER_VERSION = "0.10.0";
|
|
3831
3870
|
function jsonResult(data) {
|
|
3832
3871
|
return {
|
|
3833
3872
|
content: [
|