@datasynx/agentic-ai-cartography 2.6.0 → 2.7.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/api-bin.js +2 -2
- package/dist/{chunk-X3UWUX3G.js → chunk-HLWNO3RF.js} +70 -6
- package/dist/chunk-HLWNO3RF.js.map +1 -0
- package/dist/{chunk-PQ7Q6MI5.js → chunk-TBPGFEMQ.js} +2 -2
- package/dist/{chunk-GA4427LB.js → chunk-YVV6NIT2.js} +11 -1
- package/dist/chunk-YVV6NIT2.js.map +1 -0
- package/dist/cli.js +24 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +70 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -3
- package/dist/index.d.ts +61 -3
- package/dist/index.js +67 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp-bin.js +2 -2
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/chunk-GA4427LB.js.map +0 -1
- package/dist/chunk-X3UWUX3G.js.map +0 -1
- /package/dist/{chunk-PQ7Q6MI5.js.map → chunk-TBPGFEMQ.js.map} +0 -0
package/dist/api-bin.js
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AuthorizationError,
|
|
4
4
|
CartographyDB,
|
|
5
5
|
RulesetSchema,
|
|
6
|
+
SCHEMA_VERSION,
|
|
6
7
|
SqliteCredentialStore,
|
|
7
8
|
assertSafeBind,
|
|
8
9
|
authorize,
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
sanitizeUntrusted,
|
|
25
26
|
stableStringify,
|
|
26
27
|
stripSensitive
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-YVV6NIT2.js";
|
|
28
29
|
import {
|
|
29
30
|
EdgeSchema,
|
|
30
31
|
NODE_TYPES,
|
|
@@ -1538,7 +1539,7 @@ async function executeNlQuery(db, sessionId, search, intent, opts = {}) {
|
|
|
1538
1539
|
|
|
1539
1540
|
// src/mcp/server.ts
|
|
1540
1541
|
var SERVER_NAME = "cartography";
|
|
1541
|
-
var SERVER_VERSION = "2.
|
|
1542
|
+
var SERVER_VERSION = "2.7.0";
|
|
1542
1543
|
var SERVICE_TYPES = NODE_TYPE_GROUPS.web;
|
|
1543
1544
|
var DATA_TYPES = NODE_TYPE_GROUPS.data;
|
|
1544
1545
|
var lexicalSearch = async (db, sessionId, query, opts) => db.searchNodes(sessionId, query, { types: opts.types, limit: opts.limit }).map((node) => ({ node }));
|
|
@@ -2106,6 +2107,16 @@ async function runHttp(factory, opts = {}) {
|
|
|
2106
2107
|
const httpServer = http.createServer(async (req, res) => {
|
|
2107
2108
|
try {
|
|
2108
2109
|
const url = req.url ?? "";
|
|
2110
|
+
const probePath = new URL(url || "/", "http://probe").pathname;
|
|
2111
|
+
if (probePath === "/healthz") {
|
|
2112
|
+
res.writeHead(200, { "content-type": "application/json" }).end('{"status":"ok"}');
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
if (probePath === "/readyz") {
|
|
2116
|
+
const r = opts.readiness ? opts.readiness() : { ready: true };
|
|
2117
|
+
res.writeHead(r.ready ? 200 : 503, { "content-type": "application/json" }).end(JSON.stringify({ status: r.ready ? "ready" : "unready" }));
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
2109
2120
|
const isIngest = url.startsWith("/ingest") && opts.onIngest !== void 0;
|
|
2110
2121
|
if (!url.startsWith("/mcp") && !isIngest) {
|
|
2111
2122
|
res.writeHead(404, { "content-type": "application/json" }).end('{"error":"not found"}');
|
|
@@ -2133,7 +2144,7 @@ async function runHttp(factory, opts = {}) {
|
|
|
2133
2144
|
return;
|
|
2134
2145
|
}
|
|
2135
2146
|
const out = onIngest(value);
|
|
2136
|
-
res.writeHead(out.status, { "content-type": "application/json" }).end(JSON.stringify(out.body));
|
|
2147
|
+
res.writeHead(out.status, { "content-type": "application/json", ...out.headers ?? {} }).end(JSON.stringify(out.body));
|
|
2137
2148
|
return;
|
|
2138
2149
|
}
|
|
2139
2150
|
const sessionId = req.headers["mcp-session-id"];
|
|
@@ -2461,7 +2472,7 @@ var ContributorSchema = z3.object({
|
|
|
2461
2472
|
});
|
|
2462
2473
|
var IngestEnvelopeSchema = z3.object({
|
|
2463
2474
|
schemaVersion: z3.literal(INGEST_SCHEMA_VERSION),
|
|
2464
|
-
org: z3.string().min(1).optional(),
|
|
2475
|
+
org: z3.string().min(1).max(128).optional(),
|
|
2465
2476
|
items: z3.array(z3.object({
|
|
2466
2477
|
contentHash: z3.string(),
|
|
2467
2478
|
kind: z3.enum(["node", "edge"]),
|
|
@@ -2549,6 +2560,7 @@ function ingestEnvelope(store, envelope, opts = {}) {
|
|
|
2549
2560
|
|
|
2550
2561
|
// src/central/server.ts
|
|
2551
2562
|
function createIngestHandler(store, opts = {}) {
|
|
2563
|
+
const quota = opts.quota;
|
|
2552
2564
|
return (body) => {
|
|
2553
2565
|
const parsed = IngestEnvelopeSchema.safeParse(body);
|
|
2554
2566
|
if (!parsed.success) {
|
|
@@ -2556,6 +2568,14 @@ function createIngestHandler(store, opts = {}) {
|
|
|
2556
2568
|
logWarn("ingest: rejected invalid envelope", { issues });
|
|
2557
2569
|
return { status: 400, body: { error: "invalid envelope", issues } };
|
|
2558
2570
|
}
|
|
2571
|
+
if (quota) {
|
|
2572
|
+
const org = normalizeTenant(parsed.data.org ?? opts.defaultOrg);
|
|
2573
|
+
const decision = quota.take(org);
|
|
2574
|
+
if (!decision.allowed) {
|
|
2575
|
+
logWarn("ingest: rate limited", { org, retryAfterSec: decision.retryAfterSec });
|
|
2576
|
+
return { status: 429, body: { error: "too many requests" }, headers: { "retry-after": String(decision.retryAfterSec) } };
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2559
2579
|
try {
|
|
2560
2580
|
const result = ingestEnvelope(store, parsed.data, opts);
|
|
2561
2581
|
return { status: 200, body: result };
|
|
@@ -2566,7 +2586,41 @@ function createIngestHandler(store, opts = {}) {
|
|
|
2566
2586
|
};
|
|
2567
2587
|
}
|
|
2568
2588
|
|
|
2589
|
+
// src/central/quota.ts
|
|
2590
|
+
var DEFAULT_INGEST_QUOTA = { capacity: 120, refillMs: 6e4 };
|
|
2591
|
+
var MAX_KEYS = 1e4;
|
|
2592
|
+
var RateLimiter = class {
|
|
2593
|
+
constructor(cfg = DEFAULT_INGEST_QUOTA, now = () => Date.now()) {
|
|
2594
|
+
this.cfg = cfg;
|
|
2595
|
+
this.now = now;
|
|
2596
|
+
}
|
|
2597
|
+
buckets = /* @__PURE__ */ new Map();
|
|
2598
|
+
/** Consume one token for `key`. Returns whether the request is allowed (+ Retry-After when not). */
|
|
2599
|
+
take(key) {
|
|
2600
|
+
const t = this.now();
|
|
2601
|
+
const ratePerMs = this.cfg.capacity / this.cfg.refillMs;
|
|
2602
|
+
let b = this.buckets.get(key);
|
|
2603
|
+
if (!b) {
|
|
2604
|
+
if (this.buckets.size >= MAX_KEYS) {
|
|
2605
|
+
const oldest = this.buckets.keys().next().value;
|
|
2606
|
+
if (oldest !== void 0) this.buckets.delete(oldest);
|
|
2607
|
+
}
|
|
2608
|
+
b = { tokens: this.cfg.capacity, last: t };
|
|
2609
|
+
this.buckets.set(key, b);
|
|
2610
|
+
}
|
|
2611
|
+
b.tokens = Math.min(this.cfg.capacity, b.tokens + Math.max(0, t - b.last) * ratePerMs);
|
|
2612
|
+
b.last = t;
|
|
2613
|
+
if (b.tokens >= 1) {
|
|
2614
|
+
b.tokens -= 1;
|
|
2615
|
+
return { allowed: true, retryAfterSec: 0 };
|
|
2616
|
+
}
|
|
2617
|
+
const waitMs = (1 - b.tokens) / ratePerMs;
|
|
2618
|
+
return { allowed: false, retryAfterSec: Math.max(1, Math.ceil(waitMs / 1e3)) };
|
|
2619
|
+
}
|
|
2620
|
+
};
|
|
2621
|
+
|
|
2569
2622
|
// src/mcp/start.ts
|
|
2623
|
+
var EXPECTED_USER_VERSION = SCHEMA_VERSION;
|
|
2570
2624
|
function parseMcpArgs(argv) {
|
|
2571
2625
|
const opts = {};
|
|
2572
2626
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -2626,11 +2680,21 @@ async function startMcp(opts = {}) {
|
|
|
2626
2680
|
if (serverMode) {
|
|
2627
2681
|
const store = new SqliteStoreBackend(db);
|
|
2628
2682
|
const anonMode = opts.anonMode ?? "reject";
|
|
2629
|
-
|
|
2683
|
+
const quota = new RateLimiter(opts.ingestQuota ?? DEFAULT_INGEST_QUOTA);
|
|
2684
|
+
onIngest = createIngestHandler(store, { anonMode, defaultOrg: tenant, quota });
|
|
2630
2685
|
}
|
|
2686
|
+
const readiness = () => {
|
|
2687
|
+
try {
|
|
2688
|
+
const v = db.rawConnection().pragma("user_version", { simple: true });
|
|
2689
|
+
return { ready: v === EXPECTED_USER_VERSION, detail: { schema: v } };
|
|
2690
|
+
} catch (err) {
|
|
2691
|
+
return { ready: false, detail: { error: err instanceof Error ? err.message : String(err) } };
|
|
2692
|
+
}
|
|
2693
|
+
};
|
|
2631
2694
|
await runHttp(factory, {
|
|
2632
2695
|
port,
|
|
2633
2696
|
host,
|
|
2697
|
+
readiness,
|
|
2634
2698
|
auth: { store: authStore, ...opts.authRequired ? { required: true } : {} },
|
|
2635
2699
|
defaultTenant: tenant,
|
|
2636
2700
|
...opts.allowedHosts ? { allowedHosts: opts.allowedHosts } : {},
|
|
@@ -2659,4 +2723,4 @@ export {
|
|
|
2659
2723
|
parseMcpArgs,
|
|
2660
2724
|
startMcp
|
|
2661
2725
|
};
|
|
2662
|
-
//# sourceMappingURL=chunk-
|
|
2726
|
+
//# sourceMappingURL=chunk-HLWNO3RF.js.map
|