hive-intelligence 1.5.1 → 1.5.3
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/build/{chunk-XQPEFCSY.js → chunk-VZBDTSWA.js} +2 -1
- package/build/{chunk-AGM2CIRL.js → chunk-Y5XA3SFY.js} +241 -28
- package/build/cli.js +5 -5
- package/build/{doctor-XG5IQCXK.js → doctor-VRZYKQGL.js} +1 -1
- package/build/{mcpServer-XHIN5JER.js → mcpServer-DARSGHUH.js} +1 -1
- package/build/monitor-worker.js +2 -2
- package/build/release.json +4 -4
- package/build/{serve-PWMT5IRU.js → serve-NCMFZSMB.js} +1 -1
- package/build/server.js +9 -2
- package/build/stdio.js +1 -1
- package/package.json +3 -3
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getSupabaseAdmin,
|
|
8
8
|
resolveEndpoint,
|
|
9
9
|
secureLogger
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Y5XA3SFY.js";
|
|
11
11
|
|
|
12
12
|
// src/services/wallet-service.ts
|
|
13
13
|
async function consumeCredits(args) {
|
|
@@ -133,6 +133,7 @@ async function executeToolByName(toolName, args, options) {
|
|
|
133
133
|
transport: "rest",
|
|
134
134
|
requestId: options?.requestId,
|
|
135
135
|
clients: getSharedClients(),
|
|
136
|
+
analytics: options?.analytics,
|
|
136
137
|
beforeExecution: options?.beforeExecution
|
|
137
138
|
});
|
|
138
139
|
if (result.validationErrors) {
|
|
@@ -20827,7 +20827,7 @@ var require_websocket = __commonJS({
|
|
|
20827
20827
|
var http = __require("http");
|
|
20828
20828
|
var net2 = __require("net");
|
|
20829
20829
|
var tls = __require("tls");
|
|
20830
|
-
var { randomBytes: randomBytes4, createHash:
|
|
20830
|
+
var { randomBytes: randomBytes4, createHash: createHash9 } = __require("crypto");
|
|
20831
20831
|
var { Duplex, Readable } = __require("stream");
|
|
20832
20832
|
var { URL: URL2 } = __require("url");
|
|
20833
20833
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -21495,7 +21495,7 @@ var require_websocket = __commonJS({
|
|
|
21495
21495
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
21496
21496
|
return;
|
|
21497
21497
|
}
|
|
21498
|
-
const digest2 =
|
|
21498
|
+
const digest2 = createHash9("sha1").update(key + GUID).digest("base64");
|
|
21499
21499
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
21500
21500
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
21501
21501
|
return;
|
|
@@ -21864,7 +21864,7 @@ var require_websocket_server = __commonJS({
|
|
|
21864
21864
|
var EventEmitter = __require("events");
|
|
21865
21865
|
var http = __require("http");
|
|
21866
21866
|
var { Duplex } = __require("stream");
|
|
21867
|
-
var { createHash:
|
|
21867
|
+
var { createHash: createHash9 } = __require("crypto");
|
|
21868
21868
|
var extension = require_extension();
|
|
21869
21869
|
var PerMessageDeflate = require_permessage_deflate();
|
|
21870
21870
|
var subprotocol = require_subprotocol();
|
|
@@ -22171,7 +22171,7 @@ var require_websocket_server = __commonJS({
|
|
|
22171
22171
|
);
|
|
22172
22172
|
}
|
|
22173
22173
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
22174
|
-
const digest2 =
|
|
22174
|
+
const digest2 = createHash9("sha1").update(key + GUID).digest("base64");
|
|
22175
22175
|
const headers = [
|
|
22176
22176
|
"HTTP/1.1 101 Switching Protocols",
|
|
22177
22177
|
"Upgrade: websocket",
|
|
@@ -62904,11 +62904,30 @@ function getCircuitBreaker(serviceName) {
|
|
|
62904
62904
|
state: "CLOSED" /* CLOSED */,
|
|
62905
62905
|
failures: 0,
|
|
62906
62906
|
lastFailureTime: 0,
|
|
62907
|
+
lastErrorMessage: null,
|
|
62907
62908
|
serviceName
|
|
62908
62909
|
});
|
|
62909
62910
|
}
|
|
62910
62911
|
return circuitBreakers.get(serviceName);
|
|
62911
62912
|
}
|
|
62913
|
+
function failureMessage(error) {
|
|
62914
|
+
let message = "";
|
|
62915
|
+
if (error instanceof AxiosError) {
|
|
62916
|
+
const data = error.response?.data;
|
|
62917
|
+
const fromBody = [
|
|
62918
|
+
data?.message,
|
|
62919
|
+
data?.error,
|
|
62920
|
+
data?.status?.error_message
|
|
62921
|
+
].find((value) => typeof value === "string" && value.trim());
|
|
62922
|
+
message = typeof fromBody === "string" ? fromBody : error.message;
|
|
62923
|
+
} else if (error instanceof Error) {
|
|
62924
|
+
message = error.message;
|
|
62925
|
+
} else if (error) {
|
|
62926
|
+
message = String(error);
|
|
62927
|
+
}
|
|
62928
|
+
const compact = message.replace(/\s+/g, " ").trim();
|
|
62929
|
+
return compact ? compact.slice(0, 240) : null;
|
|
62930
|
+
}
|
|
62912
62931
|
function isRetryableError(error) {
|
|
62913
62932
|
if (!error.response) {
|
|
62914
62933
|
const retryableCodes = [
|
|
@@ -63004,7 +63023,7 @@ var ResilientHttpClient = class {
|
|
|
63004
63023
|
);
|
|
63005
63024
|
} else {
|
|
63006
63025
|
throw new Error(
|
|
63007
|
-
`Circuit breaker OPEN for ${this.config.serviceName}. Service has failed ${breaker.failures} consecutive times. Will retry in ${Math.ceil((this.config.circuitBreakerResetTimeout - (now - breaker.lastFailureTime)) / 1e3)}s`
|
|
63026
|
+
`Circuit breaker OPEN for ${this.config.serviceName}. Service has failed ${breaker.failures} consecutive times. Will retry in ${Math.ceil((this.config.circuitBreakerResetTimeout - (now - breaker.lastFailureTime)) / 1e3)}s` + (breaker.lastErrorMessage ? `. Last error: ${breaker.lastErrorMessage}` : "")
|
|
63008
63027
|
);
|
|
63009
63028
|
}
|
|
63010
63029
|
break;
|
|
@@ -63034,11 +63053,13 @@ var ResilientHttpClient = class {
|
|
|
63034
63053
|
/**
|
|
63035
63054
|
* Record a failed request (may open circuit breaker)
|
|
63036
63055
|
*/
|
|
63037
|
-
recordFailure() {
|
|
63056
|
+
recordFailure(error) {
|
|
63038
63057
|
if (!this.config.enableCircuitBreaker) return;
|
|
63039
63058
|
const breaker = this.circuitBreaker;
|
|
63040
63059
|
breaker.failures++;
|
|
63041
63060
|
breaker.lastFailureTime = Date.now();
|
|
63061
|
+
const message = failureMessage(error);
|
|
63062
|
+
if (message) breaker.lastErrorMessage = message;
|
|
63042
63063
|
if (breaker.state === "HALF_OPEN" /* HALF_OPEN */) {
|
|
63043
63064
|
breaker.state = "OPEN" /* OPEN */;
|
|
63044
63065
|
secureLogger.warn(
|
|
@@ -63068,7 +63089,7 @@ var ResilientHttpClient = class {
|
|
|
63068
63089
|
} catch (error) {
|
|
63069
63090
|
lastError = error;
|
|
63070
63091
|
if (error instanceof AxiosError && isRetryableError(error)) {
|
|
63071
|
-
this.recordFailure();
|
|
63092
|
+
this.recordFailure(error);
|
|
63072
63093
|
if (attempt < maxRetries) {
|
|
63073
63094
|
const delay2 = calculateBackoffDelay(
|
|
63074
63095
|
attempt,
|
|
@@ -63091,7 +63112,7 @@ var ResilientHttpClient = class {
|
|
|
63091
63112
|
if (error instanceof AxiosError) {
|
|
63092
63113
|
const status = error.response?.status ?? 0;
|
|
63093
63114
|
if (!status || status >= 500 || status === 429) {
|
|
63094
|
-
this.recordFailure();
|
|
63115
|
+
this.recordFailure(error);
|
|
63095
63116
|
}
|
|
63096
63117
|
}
|
|
63097
63118
|
}
|
|
@@ -84857,7 +84878,8 @@ var ERROR_SUGGESTIONS = {
|
|
|
84857
84878
|
};
|
|
84858
84879
|
function createErrorResponse7(code, message, additionalContext) {
|
|
84859
84880
|
const suggestion = ERROR_SUGGESTIONS[code] || ERROR_SUGGESTIONS.API_ERROR;
|
|
84860
|
-
|
|
84881
|
+
const bareMessage = message.replace(/^(?:\s*\*\*Error:\*\*\s*)+/, "");
|
|
84882
|
+
let errorText = `**Error:** ${bareMessage}
|
|
84861
84883
|
|
|
84862
84884
|
**Code:** ${code}
|
|
84863
84885
|
|
|
@@ -85678,6 +85700,147 @@ function getAnalyticsWriter() {
|
|
|
85678
85700
|
return defaultWriter;
|
|
85679
85701
|
}
|
|
85680
85702
|
|
|
85703
|
+
// src/services/posthog-sink.ts
|
|
85704
|
+
import { createHash as createHash5 } from "crypto";
|
|
85705
|
+
var POSTHOG_DISTINCT_ID_DOMAIN = "hive-posthog-principal-v1";
|
|
85706
|
+
var MAX_QUEUE_SIZE2 = 500;
|
|
85707
|
+
var FLUSH_INTERVAL_MS2 = 5e3;
|
|
85708
|
+
var FLUSH_BATCH_SIZE2 = 50;
|
|
85709
|
+
var DROP_LOG_INTERVAL_MS2 = 6e4;
|
|
85710
|
+
var CAPTURE_TIMEOUT_MS = 1e4;
|
|
85711
|
+
function posthogDistinctId(raw) {
|
|
85712
|
+
return createHash5("sha256").update(`${POSTHOG_DISTINCT_ID_DOMAIN}\0${raw}`).digest("hex");
|
|
85713
|
+
}
|
|
85714
|
+
async function defaultPostBatch(url, body) {
|
|
85715
|
+
const response = await fetch(url, {
|
|
85716
|
+
method: "POST",
|
|
85717
|
+
headers: { "Content-Type": "application/json" },
|
|
85718
|
+
body: JSON.stringify(body),
|
|
85719
|
+
signal: AbortSignal.timeout(CAPTURE_TIMEOUT_MS)
|
|
85720
|
+
});
|
|
85721
|
+
return { ok: response.ok, status: response.status };
|
|
85722
|
+
}
|
|
85723
|
+
function defaultDependencies2() {
|
|
85724
|
+
return {
|
|
85725
|
+
projectToken: () => getEnvVar("POSTHOG_PROJECT_TOKEN"),
|
|
85726
|
+
host: () => getEnvVar("POSTHOG_HOST"),
|
|
85727
|
+
postBatch: defaultPostBatch,
|
|
85728
|
+
maxQueueSize: MAX_QUEUE_SIZE2,
|
|
85729
|
+
flushIntervalMs: FLUSH_INTERVAL_MS2,
|
|
85730
|
+
flushBatchSize: FLUSH_BATCH_SIZE2
|
|
85731
|
+
};
|
|
85732
|
+
}
|
|
85733
|
+
function createPosthogSink(overrides = {}) {
|
|
85734
|
+
const deps = {
|
|
85735
|
+
...defaultDependencies2(),
|
|
85736
|
+
...overrides
|
|
85737
|
+
};
|
|
85738
|
+
const queue = [];
|
|
85739
|
+
let dropped = 0;
|
|
85740
|
+
let lastDropLoggedAt = 0;
|
|
85741
|
+
let timer = null;
|
|
85742
|
+
let flushing = null;
|
|
85743
|
+
function ensureTimer() {
|
|
85744
|
+
if (timer) return;
|
|
85745
|
+
timer = setInterval(() => {
|
|
85746
|
+
void flush();
|
|
85747
|
+
}, deps.flushIntervalMs);
|
|
85748
|
+
timer.unref?.();
|
|
85749
|
+
}
|
|
85750
|
+
async function drain() {
|
|
85751
|
+
const token = deps.projectToken();
|
|
85752
|
+
const host = deps.host();
|
|
85753
|
+
if (!token || !host) return;
|
|
85754
|
+
const batch = queue.splice(0, queue.length);
|
|
85755
|
+
if (batch.length === 0) return;
|
|
85756
|
+
try {
|
|
85757
|
+
const { ok, status } = await deps.postBatch(
|
|
85758
|
+
`${host.replace(/\/$/, "")}/batch/`,
|
|
85759
|
+
{ api_key: token, batch }
|
|
85760
|
+
);
|
|
85761
|
+
if (!ok) {
|
|
85762
|
+
dropped += batch.length;
|
|
85763
|
+
secureLogger.warn("PostHog batch capture failed", {
|
|
85764
|
+
status,
|
|
85765
|
+
eventCount: batch.length,
|
|
85766
|
+
droppedTotal: dropped
|
|
85767
|
+
});
|
|
85768
|
+
}
|
|
85769
|
+
} catch (error) {
|
|
85770
|
+
dropped += batch.length;
|
|
85771
|
+
secureLogger.warn("PostHog batch capture threw", {
|
|
85772
|
+
eventCount: batch.length,
|
|
85773
|
+
droppedTotal: dropped,
|
|
85774
|
+
errorMessage: error instanceof Error ? error.message : "unknown"
|
|
85775
|
+
});
|
|
85776
|
+
}
|
|
85777
|
+
}
|
|
85778
|
+
function flush() {
|
|
85779
|
+
if (flushing) return flushing;
|
|
85780
|
+
flushing = drain().catch(() => void 0).finally(() => {
|
|
85781
|
+
flushing = null;
|
|
85782
|
+
});
|
|
85783
|
+
return flushing;
|
|
85784
|
+
}
|
|
85785
|
+
return {
|
|
85786
|
+
enqueueToolCall(event) {
|
|
85787
|
+
try {
|
|
85788
|
+
if (!deps.projectToken() || !deps.host()) return false;
|
|
85789
|
+
if (!event.isMaterial || event.isInternal) return false;
|
|
85790
|
+
if (!event.principalRaw || event.authLane === "anonymous") return false;
|
|
85791
|
+
if (queue.length >= deps.maxQueueSize) {
|
|
85792
|
+
dropped += 1;
|
|
85793
|
+
const now = Date.now();
|
|
85794
|
+
if (now - lastDropLoggedAt >= DROP_LOG_INTERVAL_MS2) {
|
|
85795
|
+
lastDropLoggedAt = now;
|
|
85796
|
+
secureLogger.warn(
|
|
85797
|
+
"PostHog queue is full \u2014 mirror events are being dropped",
|
|
85798
|
+
{ queueSize: queue.length, droppedTotal: dropped }
|
|
85799
|
+
);
|
|
85800
|
+
}
|
|
85801
|
+
return false;
|
|
85802
|
+
}
|
|
85803
|
+
queue.push({
|
|
85804
|
+
event: "mcp_tool_call",
|
|
85805
|
+
distinct_id: posthogDistinctId(event.principalRaw),
|
|
85806
|
+
timestamp: event.ts ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
85807
|
+
properties: {
|
|
85808
|
+
source: "mcp",
|
|
85809
|
+
tool_name: event.toolName,
|
|
85810
|
+
success: event.success,
|
|
85811
|
+
duration_ms: Math.max(0, Math.round(event.durationMs)),
|
|
85812
|
+
transport: event.transport,
|
|
85813
|
+
provider: event.provider ?? null,
|
|
85814
|
+
category: event.category ?? null,
|
|
85815
|
+
auth_lane: event.authLane ?? null,
|
|
85816
|
+
client: event.clientProfile ?? null
|
|
85817
|
+
}
|
|
85818
|
+
});
|
|
85819
|
+
ensureTimer();
|
|
85820
|
+
if (queue.length >= deps.flushBatchSize) void flush();
|
|
85821
|
+
return true;
|
|
85822
|
+
} catch {
|
|
85823
|
+
return false;
|
|
85824
|
+
}
|
|
85825
|
+
},
|
|
85826
|
+
flush,
|
|
85827
|
+
stop() {
|
|
85828
|
+
if (timer) {
|
|
85829
|
+
clearInterval(timer);
|
|
85830
|
+
timer = null;
|
|
85831
|
+
}
|
|
85832
|
+
},
|
|
85833
|
+
getStats() {
|
|
85834
|
+
return { queued: queue.length, dropped };
|
|
85835
|
+
}
|
|
85836
|
+
};
|
|
85837
|
+
}
|
|
85838
|
+
var defaultSink = null;
|
|
85839
|
+
function getPosthogSink() {
|
|
85840
|
+
if (!defaultSink) defaultSink = createPosthogSink();
|
|
85841
|
+
return defaultSink;
|
|
85842
|
+
}
|
|
85843
|
+
|
|
85681
85844
|
// src/services/client-profile.ts
|
|
85682
85845
|
var MCP_REMOTE_PATTERN = /^(.*?) \(via mcp-remote ([\d.]+)\)$/;
|
|
85683
85846
|
var MAX_NAME_LENGTH = 256;
|
|
@@ -86081,6 +86244,22 @@ function logToolCall(endpoint, context, hive, success, durationMs, args, extra =
|
|
|
86081
86244
|
});
|
|
86082
86245
|
} catch {
|
|
86083
86246
|
}
|
|
86247
|
+
try {
|
|
86248
|
+
getPosthogSink().enqueueToolCall({
|
|
86249
|
+
toolName: endpoint.tool.name,
|
|
86250
|
+
success,
|
|
86251
|
+
durationMs,
|
|
86252
|
+
transport: context.transport,
|
|
86253
|
+
provider: getProviderNameForTool(endpoint),
|
|
86254
|
+
category: getCategoryNameForTool(endpoint.tool.name),
|
|
86255
|
+
principalRaw: context.analytics?.principalRaw ?? null,
|
|
86256
|
+
authLane: context.analytics?.authLane ?? null,
|
|
86257
|
+
clientProfile: clientProfileFromName(context.analytics?.clientName),
|
|
86258
|
+
isMaterial: getMcpCreditCost(endpoint.tool.name) > 0,
|
|
86259
|
+
isInternal: context.analytics?.isInternal === true || context.transport === "health"
|
|
86260
|
+
});
|
|
86261
|
+
} catch {
|
|
86262
|
+
}
|
|
86084
86263
|
}
|
|
86085
86264
|
function validationErrorResult(endpoint, validationErrors, durationMs, args) {
|
|
86086
86265
|
const errorCopy = agentErrorCopy("invalid_input", {
|
|
@@ -86502,6 +86681,14 @@ function isSolanaChain(chain, address) {
|
|
|
86502
86681
|
if (chain) return SOLANA_CHAIN_NAMES.has(normalizeChain(chain));
|
|
86503
86682
|
return !address.trim().toLowerCase().startsWith("0x");
|
|
86504
86683
|
}
|
|
86684
|
+
function looksLikeNameService(address) {
|
|
86685
|
+
return /\.[a-z]{2,}$/i.test(address.trim());
|
|
86686
|
+
}
|
|
86687
|
+
function nameServiceError(address) {
|
|
86688
|
+
return errorResult3(
|
|
86689
|
+
`"${address}" looks like an ENS or name-service name, which isn't supported yet. Pass a 0x address (EVM) or a base58 address (Solana).`
|
|
86690
|
+
);
|
|
86691
|
+
}
|
|
86505
86692
|
function errorResult3(message) {
|
|
86506
86693
|
return {
|
|
86507
86694
|
content: [{ type: "text", text: JSON.stringify({ error: message }) }],
|
|
@@ -86592,7 +86779,12 @@ function heroTools(endpoints, options = {}) {
|
|
|
86592
86779
|
change_24h_percent: value[`${vsCurrency}_24h_change`] ?? null
|
|
86593
86780
|
};
|
|
86594
86781
|
}
|
|
86595
|
-
|
|
86782
|
+
const tokenExists = Object.keys(payload).some((key) => key !== "_hive");
|
|
86783
|
+
return {
|
|
86784
|
+
token: query,
|
|
86785
|
+
vs_currency: vsCurrency,
|
|
86786
|
+
note: tokenExists ? `No ${vsCurrency} price available for "${query}". The quote currency may be unsupported; try vs_currency "usd".` : `No price found for "${query}". Verify the CoinGecko id or symbol, or pass chain + address for a contract token.`
|
|
86787
|
+
};
|
|
86596
86788
|
};
|
|
86597
86789
|
const trimOnchainPrice = (address) => (payload) => {
|
|
86598
86790
|
const data = payload.data;
|
|
@@ -86608,7 +86800,10 @@ function heroTools(endpoints, options = {}) {
|
|
|
86608
86800
|
};
|
|
86609
86801
|
}
|
|
86610
86802
|
}
|
|
86611
|
-
return {
|
|
86803
|
+
return {
|
|
86804
|
+
address,
|
|
86805
|
+
note: `No onchain price found for ${address} on this network. Verify the contract address and chain.`
|
|
86806
|
+
};
|
|
86612
86807
|
};
|
|
86613
86808
|
const getTokenPrice = {
|
|
86614
86809
|
metadata: {
|
|
@@ -86635,6 +86830,7 @@ function heroTools(endpoints, options = {}) {
|
|
|
86635
86830
|
const vsCurrency = (parsed.data.vs_currency ?? "usd").toLowerCase();
|
|
86636
86831
|
const format = parsed.data.response_format ?? "concise";
|
|
86637
86832
|
if (address) {
|
|
86833
|
+
if (looksLikeNameService(address)) return nameServiceError(address);
|
|
86638
86834
|
const network = GECKO_NETWORKS[normalizeChain(chain)] ?? normalizeChain(chain);
|
|
86639
86835
|
const result3 = await executeUnderlying("get_onchain_token_price", {
|
|
86640
86836
|
network,
|
|
@@ -86734,6 +86930,7 @@ function heroTools(endpoints, options = {}) {
|
|
|
86734
86930
|
}
|
|
86735
86931
|
const { address, chain } = parsed.data;
|
|
86736
86932
|
const format = parsed.data.response_format ?? "concise";
|
|
86933
|
+
if (looksLikeNameService(address)) return nameServiceError(address);
|
|
86737
86934
|
if (isSolanaChain(chain, address)) {
|
|
86738
86935
|
const result3 = await executeUnderlying("get_solana_token_security", {
|
|
86739
86936
|
contract_address: address
|
|
@@ -86882,6 +87079,7 @@ function heroTools(endpoints, options = {}) {
|
|
|
86882
87079
|
}
|
|
86883
87080
|
const { address, chain } = parsed.data;
|
|
86884
87081
|
const format = parsed.data.response_format ?? "concise";
|
|
87082
|
+
if (looksLikeNameService(address)) return nameServiceError(address);
|
|
86885
87083
|
if (isSolanaChain(chain, address)) {
|
|
86886
87084
|
const result3 = await executeUnderlying("helius_get_wallet_balances", {
|
|
86887
87085
|
wallet: address
|
|
@@ -91138,7 +91336,7 @@ async function runMcpProtocolHealth(options = {}) {
|
|
|
91138
91336
|
}
|
|
91139
91337
|
|
|
91140
91338
|
// src/health/oauthLifecycle.ts
|
|
91141
|
-
import { createHash as
|
|
91339
|
+
import { createHash as createHash7, randomBytes as randomBytes3 } from "crypto";
|
|
91142
91340
|
|
|
91143
91341
|
// src/auth/oauth/provider.ts
|
|
91144
91342
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
@@ -91514,10 +91712,10 @@ function isHiveOAuthAccessToken(token) {
|
|
|
91514
91712
|
}
|
|
91515
91713
|
|
|
91516
91714
|
// src/auth/oauth/store.ts
|
|
91517
|
-
import { createHash as
|
|
91715
|
+
import { createHash as createHash6 } from "crypto";
|
|
91518
91716
|
var REVOKED_FAMILY_TTL_SECONDS = 7776e3;
|
|
91519
91717
|
function digest(value) {
|
|
91520
|
-
return
|
|
91718
|
+
return createHash6("sha256").update(value).digest("hex");
|
|
91521
91719
|
}
|
|
91522
91720
|
function parseJson(raw) {
|
|
91523
91721
|
if (!raw) return void 0;
|
|
@@ -91969,7 +92167,7 @@ async function operationRejects(operation) {
|
|
|
91969
92167
|
}
|
|
91970
92168
|
async function issueCanaryFamily(args) {
|
|
91971
92169
|
const verifier = randomBytes3(48).toString("base64url");
|
|
91972
|
-
const challenge =
|
|
92170
|
+
const challenge = createHash7("sha256").update(verifier).digest("base64url");
|
|
91973
92171
|
let consentLocation;
|
|
91974
92172
|
const response = {
|
|
91975
92173
|
redirect(status, location) {
|
|
@@ -92281,7 +92479,7 @@ async function runOAuthLifecycleHealth(overrides = {}) {
|
|
|
92281
92479
|
import Coingecko2 from "@coingecko/coingecko-typescript";
|
|
92282
92480
|
|
|
92283
92481
|
// src/tools/goplus/goplusClient.ts
|
|
92284
|
-
import { createHash as
|
|
92482
|
+
import { createHash as createHash8 } from "crypto";
|
|
92285
92483
|
function parsePositiveInteger(value, fallback) {
|
|
92286
92484
|
const parsed = Number.parseInt(value || "", 10);
|
|
92287
92485
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
@@ -92375,7 +92573,7 @@ var GoPlusClient = class {
|
|
|
92375
92573
|
const time = Math.floor(Date.now() / 1e3);
|
|
92376
92574
|
const timeStr = time.toString();
|
|
92377
92575
|
const signInput = this.appKey + timeStr + this.appSecret;
|
|
92378
|
-
const sign =
|
|
92576
|
+
const sign = createHash8("sha1").update(signInput).digest("hex");
|
|
92379
92577
|
secureLogger.info("GoPlus: requesting access token", {
|
|
92380
92578
|
appKeyLength: this.appKey.length,
|
|
92381
92579
|
appSecretLength: this.appSecret.length,
|
|
@@ -97380,8 +97578,9 @@ var PROVIDER_AVAILABILITY_TTL_MS = 6e4;
|
|
|
97380
97578
|
var AVAILABILITY_SEVERITY = {
|
|
97381
97579
|
ok: 0,
|
|
97382
97580
|
degraded: 1,
|
|
97383
|
-
|
|
97384
|
-
|
|
97581
|
+
plan_required: 2,
|
|
97582
|
+
missing_key: 3,
|
|
97583
|
+
failing: 4
|
|
97385
97584
|
};
|
|
97386
97585
|
function availabilityFromRuntimeStatus(status) {
|
|
97387
97586
|
switch (status) {
|
|
@@ -97392,7 +97591,11 @@ function availabilityFromRuntimeStatus(status) {
|
|
|
97392
97591
|
return "ok";
|
|
97393
97592
|
case "missing_key":
|
|
97394
97593
|
return "missing_key";
|
|
97594
|
+
// A lapsed or exhausted upstream plan fails deterministically until the
|
|
97595
|
+
// account changes, unlike a transient rate limit or wobble, so it demotes
|
|
97596
|
+
// like a missing key instead of staying ranked as merely degraded.
|
|
97395
97597
|
case "plan_required":
|
|
97598
|
+
return "plan_required";
|
|
97396
97599
|
case "rate_limited":
|
|
97397
97600
|
case "degraded":
|
|
97398
97601
|
return "degraded";
|
|
@@ -97401,7 +97604,7 @@ function availabilityFromRuntimeStatus(status) {
|
|
|
97401
97604
|
}
|
|
97402
97605
|
}
|
|
97403
97606
|
function isUnavailable(availability) {
|
|
97404
|
-
return availability === "missing_key" || availability === "failing";
|
|
97607
|
+
return availability === "missing_key" || availability === "plan_required" || availability === "failing";
|
|
97405
97608
|
}
|
|
97406
97609
|
function worseOf(left, right) {
|
|
97407
97610
|
return AVAILABILITY_SEVERITY[right] > AVAILABILITY_SEVERITY[left] ? right : left;
|
|
@@ -98165,7 +98368,8 @@ function singularizeToken(token) {
|
|
|
98165
98368
|
return token;
|
|
98166
98369
|
}
|
|
98167
98370
|
function parseSearchTokens(query) {
|
|
98168
|
-
|
|
98371
|
+
const tokens = query.toLowerCase().replace(/0x[a-f0-9]{20,}/g, " ").replace(/[1-9A-HJ-NP-Za-km-z]{32,}/g, " ").replace(/https?:\/\/\S+/g, " ").replace(/[\?¿!¡"'`()\[\]{}:;|/\\]+/g, " ").replace(/[-_]+/g, " ").split(/[\s,]+/).map(normalizeSearchToken).filter((token) => token.length > 1).filter((token) => !SEARCH_STOPWORDS.has(token)).map(singularizeToken);
|
|
98372
|
+
return [...new Set(tokens)];
|
|
98169
98373
|
}
|
|
98170
98374
|
function searchTokenVariants(token) {
|
|
98171
98375
|
const normalized = singularizeToken(normalizeSearchToken(token));
|
|
@@ -98202,9 +98406,12 @@ function queryMatchScore(entry, query) {
|
|
|
98202
98406
|
entry.provider,
|
|
98203
98407
|
entry.summary
|
|
98204
98408
|
].join(" ").toLowerCase();
|
|
98409
|
+
const nameTitleTokenSet = new Set(parseSearchTokens(nameTitleText));
|
|
98410
|
+
const coreTextTokenSet = new Set(parseSearchTokens(coreText));
|
|
98205
98411
|
const score = tokens.reduce((total, token) => {
|
|
98206
|
-
|
|
98207
|
-
if (
|
|
98412
|
+
const exactToken = singularizeToken(normalizeSearchToken(token));
|
|
98413
|
+
if (nameTitleTokenSet.has(exactToken)) return total + 24;
|
|
98414
|
+
if (coreTextTokenSet.has(exactToken)) return total + 14;
|
|
98208
98415
|
if (textMatchesSearchToken(nameTitleText, token)) return total + 12;
|
|
98209
98416
|
if (textMatchesSearchToken(entry.summary, token)) return total + 6;
|
|
98210
98417
|
if (textMatchesSearchToken(coreText, token)) return total + 4;
|
|
@@ -98446,13 +98653,13 @@ function dynamicTools(endpoints, options = {}) {
|
|
|
98446
98653
|
(toolset) => toolsetCatalogEntry(toolset, providerByToolName)
|
|
98447
98654
|
);
|
|
98448
98655
|
const searchToolsSchema = z17.object({
|
|
98449
|
-
query: z17.string().optional().describe(
|
|
98656
|
+
query: z17.string().max(512).optional().describe(
|
|
98450
98657
|
"Search text matched against tool name, title, category, provider, and summary."
|
|
98451
98658
|
),
|
|
98452
|
-
provider: z17.string().optional().describe(
|
|
98659
|
+
provider: z17.string().max(128).optional().describe(
|
|
98453
98660
|
"Optional provider filter such as CoinGecko, Moralis, Tenderly, Helius, GoPlus, CCXT, Codex, Alchemy, DeFiLlama, Hyperliquid, or Open Data Fetch."
|
|
98454
98661
|
),
|
|
98455
|
-
category: z17.string().optional().describe("Optional category filter, for example Portfolio & Wallet."),
|
|
98662
|
+
category: z17.string().max(128).optional().describe("Optional category filter, for example Portfolio & Wallet."),
|
|
98456
98663
|
limit: z17.number().int().min(1).max(MAX_SEARCH_LIMIT).optional().describe(`Maximum tools to return. Default ${DEFAULT_SEARCH_LIMIT}.`),
|
|
98457
98664
|
cursor: z17.string().optional().describe("Pagination cursor from the previous response."),
|
|
98458
98665
|
toolset_id: z17.string().max(100).optional().describe(
|
|
@@ -99352,7 +99559,7 @@ function buildServerInstructions(scope) {
|
|
|
99352
99559
|
`Hive serves live crypto market data to AI agents over a compact ${ROOT_META_TOOL_COUNT}-tool root. Loop: search_tools -> get_api_endpoint_schema -> ${READ_ENDPOINT_INVOKER} for reads (${STATEFUL_WRITE_ENDPOINT_INVOKER} only after explicit user approval; validate_task_result before structured answers). Every material response carries a _hive receipt (provider, fetched_at, runtime_status, _hive.receipt_id); cite it when answering.`,
|
|
99353
99560
|
`For the three dominant intents call the hero tools directly: get_token_price, check_token_safety, get_wallet_portfolio (response_format "concise" default, "detailed" available).`,
|
|
99354
99561
|
`Degraded providers are reported, not hidden: search_tools marks each tool's availability, and unavailable tools return runtime_status with cause and next_action instead of data. Follow next_action; never retry an unchanged failing call in a loop.`,
|
|
99355
|
-
`Discovery is free and cheap: resources hive://toolsets, hive://providers, hive://tools; the ${UNDERLYING_TOOL_COUNT}-tool catalog stays reachable through search_tools or scoped category endpoints. Use limit/page/per_page to keep responses small; a material execution costs 1 credit on the hosted service.`
|
|
99562
|
+
`Discovery is free and cheap: resources hive://toolsets, hive://providers, hive://tools; the ${UNDERLYING_TOOL_COUNT}-tool catalog stays reachable through search_tools or scoped category endpoints. Use limit and cursor on search_tools, and limit/page/per_page/offset on data endpoints, to keep responses small; a material execution costs 1 credit on the hosted service.`
|
|
99356
99563
|
].join(" ");
|
|
99357
99564
|
}
|
|
99358
99565
|
function compactCanaryRun(run) {
|
|
@@ -99696,7 +99903,11 @@ var HiveMCPServer = class {
|
|
|
99696
99903
|
}
|
|
99697
99904
|
}
|
|
99698
99905
|
getProviderStatusCatalog() {
|
|
99699
|
-
|
|
99906
|
+
const snapshot = getProviderAvailabilitySnapshot();
|
|
99907
|
+
return getProviderStatusCatalog().map((provider) => {
|
|
99908
|
+
const observed = snapshot.byProviderName[provider.name];
|
|
99909
|
+
return provider.status === "ok" && observed && observed !== "ok" ? { ...provider, status: observed } : provider;
|
|
99910
|
+
});
|
|
99700
99911
|
}
|
|
99701
99912
|
setupHandlers() {
|
|
99702
99913
|
this.server.server.oninitialized = () => {
|
|
@@ -99807,6 +100018,8 @@ var HiveMCPServer = class {
|
|
|
99807
100018
|
note: `Root /mcp exposes ${ROOT_META_TOOL_COUNT} meta-tools optimized for LLM agents. Use category endpoints (/hive_*/mcp) only for specialized integrations requiring direct tool access.`,
|
|
99808
100019
|
runtimeStatuses: TASK_TOOLSET_RUNTIME_STATUSES,
|
|
99809
100020
|
runtimeStatusSemantics: RUNTIME_STATUS_SEMANTICS,
|
|
100021
|
+
availability_source: getProviderAvailabilitySnapshot().source,
|
|
100022
|
+
canary_observed_at: getProviderAvailabilitySnapshot().canaryObservedAt,
|
|
99810
100023
|
providers
|
|
99811
100024
|
},
|
|
99812
100025
|
null,
|
package/build/cli.js
CHANGED
|
@@ -3440,7 +3440,7 @@ program2.hook("preAction", (thisCommand) => {
|
|
|
3440
3440
|
setCliFlags({ apiKey: opts.apiKey, noRetry: opts.retry === false });
|
|
3441
3441
|
});
|
|
3442
3442
|
program2.action(async () => {
|
|
3443
|
-
const { startStdio } = await import("./serve-
|
|
3443
|
+
const { startStdio } = await import("./serve-NCMFZSMB.js");
|
|
3444
3444
|
await startStdio(program2.opts().envFile);
|
|
3445
3445
|
});
|
|
3446
3446
|
program2.command("serve").description("Start the MCP server").option("--http", "Start HTTP server instead of stdio").option("--port <number>", "HTTP server port", "8080").action(async (opts) => {
|
|
@@ -3453,10 +3453,10 @@ program2.command("serve").description("Start the MCP server").option("--http", "
|
|
|
3453
3453
|
);
|
|
3454
3454
|
process.exit(ExitCode.INVALID_ARGS);
|
|
3455
3455
|
}
|
|
3456
|
-
const { startHttp } = await import("./serve-
|
|
3456
|
+
const { startHttp } = await import("./serve-NCMFZSMB.js");
|
|
3457
3457
|
await startHttp(port, program2.opts().envFile);
|
|
3458
3458
|
} else {
|
|
3459
|
-
const { startStdio } = await import("./serve-
|
|
3459
|
+
const { startStdio } = await import("./serve-NCMFZSMB.js");
|
|
3460
3460
|
await startStdio(program2.opts().envFile);
|
|
3461
3461
|
}
|
|
3462
3462
|
});
|
|
@@ -3666,7 +3666,7 @@ program2.command("uninstall").description(
|
|
|
3666
3666
|
if (exitCode !== 0) process.exit(exitCode);
|
|
3667
3667
|
});
|
|
3668
3668
|
program2.command("doctor").description("Diagnose environment and server connectivity").option("--probe", "Run live API probes (slower)").action(async (opts) => {
|
|
3669
|
-
const { runDoctor } = await import("./doctor-
|
|
3669
|
+
const { runDoctor } = await import("./doctor-VRZYKQGL.js");
|
|
3670
3670
|
await runDoctor(opts);
|
|
3671
3671
|
});
|
|
3672
3672
|
program2.command("upgrade").description("Update Hive to the latest published version").action(async () => {
|
|
@@ -3714,7 +3714,7 @@ program2.command("usage").description("Show your API usage and plan limits").act
|
|
|
3714
3714
|
await runUsage();
|
|
3715
3715
|
});
|
|
3716
3716
|
program2.command("status").description("Quick health and version check").action(async () => {
|
|
3717
|
-
const { runStatus } = await import("./doctor-
|
|
3717
|
+
const { runStatus } = await import("./doctor-VRZYKQGL.js");
|
|
3718
3718
|
await runStatus();
|
|
3719
3719
|
});
|
|
3720
3720
|
program2.command("open [target]").description("Open Hive dashboard, docs, status, or GitHub in browser").action(async (target) => {
|
|
@@ -204,7 +204,7 @@ ${fails === 0 ? "All checks passed" : `${fails} issues found`}${warns ? ` (${war
|
|
|
204
204
|
if (fails > 0) process.exit(1);
|
|
205
205
|
}
|
|
206
206
|
async function runStatus() {
|
|
207
|
-
const { SERVER_VERSION } = await import("./mcpServer-
|
|
207
|
+
const { SERVER_VERSION } = await import("./mcpServer-DARSGHUH.js");
|
|
208
208
|
const { resolveApiKey, resolveApiUrl } = await import("./config-dir-5IH7MOOT.js");
|
|
209
209
|
const { getActiveProfile, maskKey } = await import("./auth-Y4GXW376.js");
|
|
210
210
|
const apiUrl = resolveApiUrl();
|
package/build/monitor-worker.js
CHANGED
|
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
|
|
|
2
2
|
import {
|
|
3
3
|
consumeCredits,
|
|
4
4
|
executeToolByName
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VZBDTSWA.js";
|
|
6
6
|
import {
|
|
7
7
|
HyperliquidAPI,
|
|
8
8
|
MIN_MONITOR_CADENCE_MS,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
monitorCadenceIntervalMs,
|
|
16
16
|
runScheduledHealthCanaries,
|
|
17
17
|
secureLogger
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-Y5XA3SFY.js";
|
|
19
19
|
import "./chunk-L326MQZP.js";
|
|
20
20
|
import "./chunk-EPF36Q3Z.js";
|
|
21
21
|
import "./chunk-ZXKFJQDE.js";
|
package/build/release.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "hive-intelligence",
|
|
3
|
-
"version": "1.5.
|
|
4
|
-
"buildSha": "
|
|
5
|
-
"imageDigest": "sha256:
|
|
3
|
+
"version": "1.5.3",
|
|
4
|
+
"buildSha": "0adb32f0c05315fa9381d143b9f2d0e89514ce63",
|
|
5
|
+
"imageDigest": "sha256:4ab4777877e1be050153bca1c1be9d72b5a7fe7d68e5439d7aabcccaa63c9806",
|
|
6
6
|
"deployedUrl": "https://mcp.hiveintelligence.xyz",
|
|
7
|
-
"manifest": "https://raw.githubusercontent.com/hive-intel/hive-sdk/v1.5.
|
|
7
|
+
"manifest": "https://raw.githubusercontent.com/hive-intel/hive-sdk/v1.5.3/releases/v1.5.3.json"
|
|
8
8
|
}
|
|
@@ -7,7 +7,7 @@ async function startStdio(envFile) {
|
|
|
7
7
|
dotenv.config({ path: envFile || ".env", quiet: true });
|
|
8
8
|
console.log = (...args) => console.error("[LOG]", ...args);
|
|
9
9
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
10
|
-
const { createHiveMcpServer, SERVER_NAME, SERVER_VERSION } = await import("./mcpServer-
|
|
10
|
+
const { createHiveMcpServer, SERVER_NAME, SERVER_VERSION } = await import("./mcpServer-DARSGHUH.js");
|
|
11
11
|
const { getPendingUpdateVersion } = await import("./update-check-IEXPOYYR.js");
|
|
12
12
|
const transport = new StdioServerTransport();
|
|
13
13
|
const pendingUpdate = getPendingUpdateVersion();
|
package/build/server.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ensureWallet,
|
|
7
7
|
executeToolByName,
|
|
8
8
|
getWalletStatus
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VZBDTSWA.js";
|
|
10
10
|
import {
|
|
11
11
|
CategoryEndpoints,
|
|
12
12
|
HERO_TOOL_NAMES,
|
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
validateEndpointArgs,
|
|
96
96
|
verifyApiKey,
|
|
97
97
|
waitForRedisAvailability
|
|
98
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-Y5XA3SFY.js";
|
|
99
99
|
import {
|
|
100
100
|
HIVE_AGENT_SKILLS
|
|
101
101
|
} from "./chunk-L326MQZP.js";
|
|
@@ -8202,6 +8202,13 @@ app.post(
|
|
|
8202
8202
|
authReq.hiveSubjectContext,
|
|
8203
8203
|
() => executeToolByName(executionToolName, endpointArgs, {
|
|
8204
8204
|
requestId: req.requestId,
|
|
8205
|
+
// Same identity context the hero branch passes — without it every
|
|
8206
|
+
// non-hero keyed REST call wrote a NULL-principal analytics row.
|
|
8207
|
+
analytics: {
|
|
8208
|
+
principalRaw: authReq.userId,
|
|
8209
|
+
authLane: "api_key",
|
|
8210
|
+
isInternal: isMonitorSecretRequest(req)
|
|
8211
|
+
},
|
|
8205
8212
|
beforeExecution: keyedBeforeExecution
|
|
8206
8213
|
})
|
|
8207
8214
|
);
|
package/build/stdio.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hive-intelligence",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "Evidence-backed crypto due diligence for AI agents, with sources, freshness, and a runtime receipt on every call.",
|
|
5
5
|
"mcpName": "xyz.hiveintelligence/mcp",
|
|
6
6
|
"type": "module",
|
|
@@ -169,10 +169,10 @@
|
|
|
169
169
|
"express-rate-limit": "8.5.2"
|
|
170
170
|
},
|
|
171
171
|
"esbuild": "0.28.1",
|
|
172
|
-
"fast-uri": "3.1.
|
|
172
|
+
"fast-uri": "3.1.7",
|
|
173
173
|
"hono": "4.12.34",
|
|
174
174
|
"ip-address": "10.5.0",
|
|
175
|
-
"qs": "6.
|
|
175
|
+
"qs": "6.16.0"
|
|
176
176
|
},
|
|
177
177
|
"devDependencies": {
|
|
178
178
|
"@types/cors": "^2.8.19",
|