@kontextmind/kxm 0.7.12 → 0.7.14
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/.claude-plugin/marketplace.json +1 -1
- package/package.json +1 -1
- package/plugins/kxm/.claude-plugin/plugin.json +1 -1
- package/plugins/kxm/dist/cli.js +63 -5
- package/plugins/kxm/dist/mcp-server.js +1 -1
- package/plugins/kxm/dist/runtime.js +79 -15
- package/plugins/kxm/package.json +1 -1
- package/plugins/kxm/src/mcp-server.ts +1 -1
- package/plugins/kxm/src/modes.ts +80 -7
- package/plugins/kxm/src/policy-draft.d.mts +1 -0
- package/plugins/kxm/src/policy-draft.mjs +16 -1
- package/plugins/kxm/src/prices.ts +32 -0
- package/plugins/kxm/src/vnext-pi-producer.ts +17 -12
- package/scripts/harness-run.d.mts +3 -1
- package/scripts/harness-run.mjs +46 -13
- package/scripts/roster-policy.d.mts +4 -0
- package/scripts/roster-policy.mjs +30 -8
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "kxm",
|
|
4
4
|
"displayName": "KXM",
|
|
5
|
-
"version": "0.7.
|
|
5
|
+
"version": "0.7.14",
|
|
6
6
|
"description": "Headless multi-agent orchestration, durable workflows, and a live operator dashboard for Pi and Claude Code",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "KontextMind",
|
package/plugins/kxm/dist/cli.js
CHANGED
|
@@ -24813,6 +24813,18 @@ function loadPriceCatalog(rootOrPath) {
|
|
|
24813
24813
|
const content = readFileSync7(candidatePath, "utf8");
|
|
24814
24814
|
return parsePriceCatalog(content);
|
|
24815
24815
|
}
|
|
24816
|
+
function loadPriceCatalogForEstimate(options) {
|
|
24817
|
+
let catalog;
|
|
24818
|
+
try {
|
|
24819
|
+
catalog = options?.priceCatalog ? parsePriceCatalog(JSON.stringify(options.priceCatalog)) : loadPriceCatalog(options?.projectRoot ?? process.cwd());
|
|
24820
|
+
} catch {
|
|
24821
|
+
return { catalog: void 0, unavailable: true, stale: false };
|
|
24822
|
+
}
|
|
24823
|
+
if (catalog && catalog.date !== (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)) {
|
|
24824
|
+
return { catalog: void 0, unavailable: false, stale: true };
|
|
24825
|
+
}
|
|
24826
|
+
return { catalog, unavailable: false, stale: false };
|
|
24827
|
+
}
|
|
24816
24828
|
|
|
24817
24829
|
// plugins/kxm/src/vnext-engine.ts
|
|
24818
24830
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
@@ -46205,6 +46217,41 @@ function resolveActiveMode(config, majorModeName = "coder", domainNames = []) {
|
|
|
46205
46217
|
model: major.model || "grok/grok-4.6"
|
|
46206
46218
|
};
|
|
46207
46219
|
}
|
|
46220
|
+
var CATALOG_DATE_RE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
46221
|
+
function boundedCatalogDate(value) {
|
|
46222
|
+
return typeof value === "string" && CATALOG_DATE_RE.test(value) ? value : void 0;
|
|
46223
|
+
}
|
|
46224
|
+
function catalogDateForStatus(loaded, injected, projectRoot) {
|
|
46225
|
+
const fromLoaded = boundedCatalogDate(loaded.catalog?.date);
|
|
46226
|
+
if (fromLoaded) return fromLoaded;
|
|
46227
|
+
const fromInjected = boundedCatalogDate(injected?.date);
|
|
46228
|
+
if (fromInjected) return fromInjected;
|
|
46229
|
+
if (!loaded.stale) return void 0;
|
|
46230
|
+
try {
|
|
46231
|
+
return boundedCatalogDate(loadPriceCatalog(projectRoot)?.date);
|
|
46232
|
+
} catch {
|
|
46233
|
+
return void 0;
|
|
46234
|
+
}
|
|
46235
|
+
}
|
|
46236
|
+
function describePriceCatalogStatus(loaded, catalogDate) {
|
|
46237
|
+
if (loaded.stale) {
|
|
46238
|
+
return {
|
|
46239
|
+
catalogStatus: "stale",
|
|
46240
|
+
catalogReason: catalogDate ? `price catalog stale (dated ${catalogDate})` : "price catalog stale"
|
|
46241
|
+
};
|
|
46242
|
+
}
|
|
46243
|
+
if (loaded.unavailable) {
|
|
46244
|
+
return { catalogStatus: "corrupt", catalogReason: "price catalog corrupt" };
|
|
46245
|
+
}
|
|
46246
|
+
if (!loaded.catalog) {
|
|
46247
|
+
return { catalogStatus: "missing", catalogReason: "price catalog missing" };
|
|
46248
|
+
}
|
|
46249
|
+
return { catalogStatus: "verified", catalogReason: "price catalog verified" };
|
|
46250
|
+
}
|
|
46251
|
+
function formatExplainCost(value, footprint, suffix = "") {
|
|
46252
|
+
if (value !== null) return `$${value.toFixed(4)}${suffix}`;
|
|
46253
|
+
return footprint.catalogStatus === "verified" ? "unmetered/unknown" : footprint.catalogReason;
|
|
46254
|
+
}
|
|
46208
46255
|
function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog) {
|
|
46209
46256
|
const breakdown = [];
|
|
46210
46257
|
const baseSystemPromptChars = 3200;
|
|
@@ -46250,7 +46297,14 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
46250
46297
|
const totalTokens = breakdown.reduce((sum, item) => sum + item.estimatedTokens, 0);
|
|
46251
46298
|
const maxContextWindow = 2e5;
|
|
46252
46299
|
const contextWindowRatio = Math.round(totalTokens / maxContextWindow * 1e3) / 10;
|
|
46253
|
-
const
|
|
46300
|
+
const loaded = loadPriceCatalogForEstimate(
|
|
46301
|
+
catalog ? { priceCatalog: catalog } : { projectRoot }
|
|
46302
|
+
);
|
|
46303
|
+
const catalogInfo = describePriceCatalogStatus(
|
|
46304
|
+
loaded,
|
|
46305
|
+
catalogDateForStatus(loaded, catalog, projectRoot)
|
|
46306
|
+
);
|
|
46307
|
+
const cat = loaded.catalog;
|
|
46254
46308
|
const rawModel = resolved.model || "grok/grok-4.6";
|
|
46255
46309
|
const [prov, mod] = rawModel.includes("/") ? rawModel.split("/", 2) : [void 0, rawModel];
|
|
46256
46310
|
const inputCost = cat ? calculateModelCost(cat, {
|
|
@@ -46289,7 +46343,9 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
46289
46343
|
inputCostUsd: inputCost?.costUsd ?? null,
|
|
46290
46344
|
cacheReadCostUsd: cacheReadCost?.costUsd ?? null,
|
|
46291
46345
|
outputCostEstimateUsd: outputEstimateCost?.costUsd ?? null
|
|
46292
|
-
}
|
|
46346
|
+
},
|
|
46347
|
+
catalogStatus: catalogInfo.catalogStatus,
|
|
46348
|
+
catalogReason: catalogInfo.catalogReason
|
|
46293
46349
|
};
|
|
46294
46350
|
}
|
|
46295
46351
|
function formatModesExplainReport(footprint) {
|
|
@@ -46307,6 +46363,8 @@ ${divider}
|
|
|
46307
46363
|
out += `Enabled Domains: ${footprint.enabledDomains.length > 0 ? footprint.enabledDomains.join(", ") : "(none)"}
|
|
46308
46364
|
`;
|
|
46309
46365
|
out += `Target Model: ${footprint.model}
|
|
46366
|
+
`;
|
|
46367
|
+
out += `Catalog status: ${footprint.catalogReason}
|
|
46310
46368
|
|
|
46311
46369
|
`;
|
|
46312
46370
|
out += `CONTEXT BREAKDOWN:
|
|
@@ -46326,11 +46384,11 @@ ${divider}
|
|
|
46326
46384
|
`;
|
|
46327
46385
|
out += `PROJECTED COSTS (per turn):
|
|
46328
46386
|
`;
|
|
46329
|
-
out += ` \u2022 Initial Turn Input Cost: ${footprint.projectedCost.inputCostUsd
|
|
46387
|
+
out += ` \u2022 Initial Turn Input Cost: ${formatExplainCost(footprint.projectedCost.inputCostUsd, footprint)}
|
|
46330
46388
|
`;
|
|
46331
|
-
out += ` \u2022 Subsequent Cache-Read Cost: ${footprint.projectedCost.cacheReadCostUsd
|
|
46389
|
+
out += ` \u2022 Subsequent Cache-Read Cost: ${formatExplainCost(footprint.projectedCost.cacheReadCostUsd, footprint, " (approx 90% savings)")}
|
|
46332
46390
|
`;
|
|
46333
|
-
out += ` \u2022 Output Estimate (1k tokens): ${footprint.projectedCost.outputCostEstimateUsd
|
|
46391
|
+
out += ` \u2022 Output Estimate (1k tokens): ${formatExplainCost(footprint.projectedCost.outputCostEstimateUsd, footprint)}
|
|
46334
46392
|
`;
|
|
46335
46393
|
out += `${divider}
|
|
46336
46394
|
`;
|
|
@@ -17036,7 +17036,7 @@ async function deliverInboxNotification(messageId, delivered, notify) {
|
|
|
17036
17036
|
}
|
|
17037
17037
|
|
|
17038
17038
|
// plugins/kxm/src/mcp-server.ts
|
|
17039
|
-
var VERSION = "0.7.
|
|
17039
|
+
var VERSION = "0.7.14";
|
|
17040
17040
|
var inbox = /* @__PURE__ */ new Map();
|
|
17041
17041
|
var notifiedInbox = /* @__PURE__ */ new Set();
|
|
17042
17042
|
var meshClient;
|
|
@@ -22674,6 +22674,18 @@ function loadPriceCatalog(rootOrPath) {
|
|
|
22674
22674
|
const content = readFileSync5(candidatePath, "utf8");
|
|
22675
22675
|
return parsePriceCatalog(content);
|
|
22676
22676
|
}
|
|
22677
|
+
function loadPriceCatalogForEstimate(options) {
|
|
22678
|
+
let catalog;
|
|
22679
|
+
try {
|
|
22680
|
+
catalog = options?.priceCatalog ? parsePriceCatalog(JSON.stringify(options.priceCatalog)) : loadPriceCatalog(options?.projectRoot ?? process.cwd());
|
|
22681
|
+
} catch {
|
|
22682
|
+
return { catalog: void 0, unavailable: true, stale: false };
|
|
22683
|
+
}
|
|
22684
|
+
if (catalog && catalog.date !== (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)) {
|
|
22685
|
+
return { catalog: void 0, unavailable: false, stale: true };
|
|
22686
|
+
}
|
|
22687
|
+
return { catalog, unavailable: false, stale: false };
|
|
22688
|
+
}
|
|
22677
22689
|
|
|
22678
22690
|
// plugins/kxm/src/vnext-engine.ts
|
|
22679
22691
|
var import_yaml5 = __toESM(require_dist(), 1);
|
|
@@ -27286,10 +27298,16 @@ function createVnextPiProducer(options = {}) {
|
|
|
27286
27298
|
const cacheReadTokens = typeof usage?.cacheRead === "number" ? usage.cacheRead : null;
|
|
27287
27299
|
const cacheWriteTokens = typeof usage?.cacheWrite === "number" ? usage.cacheWrite : null;
|
|
27288
27300
|
const contextTokens = typeof usage?.contextUsage?.tokens === "number" ? usage.contextUsage.tokens : tokensIn;
|
|
27289
|
-
const
|
|
27290
|
-
|
|
27291
|
-
|
|
27292
|
-
|
|
27301
|
+
const providerMetadata = {};
|
|
27302
|
+
const loaded = loadPriceCatalogForEstimate({
|
|
27303
|
+
priceCatalog: options.priceCatalog,
|
|
27304
|
+
projectRoot: options.projectRoot
|
|
27305
|
+
});
|
|
27306
|
+
if (loaded.unavailable) providerMetadata.priceCatalogUnavailable = true;
|
|
27307
|
+
if (loaded.stale) providerMetadata.priceCatalogStale = true;
|
|
27308
|
+
const catalog = loaded.catalog;
|
|
27309
|
+
const costBasis = "unknown";
|
|
27310
|
+
const costUsd = null;
|
|
27293
27311
|
if (catalog) {
|
|
27294
27312
|
const calculated = calculateModelCost(catalog, {
|
|
27295
27313
|
model: resolved.model,
|
|
@@ -27300,10 +27318,10 @@ function createVnextPiProducer(options = {}) {
|
|
|
27300
27318
|
cacheWriteTokens,
|
|
27301
27319
|
contextTokens
|
|
27302
27320
|
});
|
|
27303
|
-
if (calculated) {
|
|
27304
|
-
|
|
27305
|
-
|
|
27306
|
-
|
|
27321
|
+
if (calculated && Number.isFinite(calculated.costUsd)) {
|
|
27322
|
+
providerMetadata.listCostUsd = calculated.costUsd;
|
|
27323
|
+
providerMetadata.listPriceRef = calculated.priceRef;
|
|
27324
|
+
providerMetadata.listPriceSha256 = catalog.sha256;
|
|
27307
27325
|
}
|
|
27308
27326
|
}
|
|
27309
27327
|
return {
|
|
@@ -27320,9 +27338,9 @@ function createVnextPiProducer(options = {}) {
|
|
|
27320
27338
|
provider: resolved.provider,
|
|
27321
27339
|
requestedModel: resolved.model,
|
|
27322
27340
|
effectiveModel: resolved.model,
|
|
27341
|
+
providerMetadata,
|
|
27323
27342
|
...resolved.thinking !== void 0 ? { thinking: resolved.thinking } : {},
|
|
27324
|
-
agentRole: request.agentRole ?? request.agentId
|
|
27325
|
-
...priceRef !== void 0 ? { priceRef } : {}
|
|
27343
|
+
agentRole: request.agentRole ?? request.agentId
|
|
27326
27344
|
};
|
|
27327
27345
|
},
|
|
27328
27346
|
async closeRun(runId) {
|
|
@@ -28371,6 +28389,41 @@ function resolveActiveMode(config, majorModeName = "coder", domainNames = []) {
|
|
|
28371
28389
|
model: major.model || "grok/grok-4.6"
|
|
28372
28390
|
};
|
|
28373
28391
|
}
|
|
28392
|
+
var CATALOG_DATE_RE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
28393
|
+
function boundedCatalogDate(value) {
|
|
28394
|
+
return typeof value === "string" && CATALOG_DATE_RE.test(value) ? value : void 0;
|
|
28395
|
+
}
|
|
28396
|
+
function catalogDateForStatus(loaded, injected, projectRoot) {
|
|
28397
|
+
const fromLoaded = boundedCatalogDate(loaded.catalog?.date);
|
|
28398
|
+
if (fromLoaded) return fromLoaded;
|
|
28399
|
+
const fromInjected = boundedCatalogDate(injected?.date);
|
|
28400
|
+
if (fromInjected) return fromInjected;
|
|
28401
|
+
if (!loaded.stale) return void 0;
|
|
28402
|
+
try {
|
|
28403
|
+
return boundedCatalogDate(loadPriceCatalog(projectRoot)?.date);
|
|
28404
|
+
} catch {
|
|
28405
|
+
return void 0;
|
|
28406
|
+
}
|
|
28407
|
+
}
|
|
28408
|
+
function describePriceCatalogStatus(loaded, catalogDate) {
|
|
28409
|
+
if (loaded.stale) {
|
|
28410
|
+
return {
|
|
28411
|
+
catalogStatus: "stale",
|
|
28412
|
+
catalogReason: catalogDate ? `price catalog stale (dated ${catalogDate})` : "price catalog stale"
|
|
28413
|
+
};
|
|
28414
|
+
}
|
|
28415
|
+
if (loaded.unavailable) {
|
|
28416
|
+
return { catalogStatus: "corrupt", catalogReason: "price catalog corrupt" };
|
|
28417
|
+
}
|
|
28418
|
+
if (!loaded.catalog) {
|
|
28419
|
+
return { catalogStatus: "missing", catalogReason: "price catalog missing" };
|
|
28420
|
+
}
|
|
28421
|
+
return { catalogStatus: "verified", catalogReason: "price catalog verified" };
|
|
28422
|
+
}
|
|
28423
|
+
function formatExplainCost(value, footprint, suffix = "") {
|
|
28424
|
+
if (value !== null) return `$${value.toFixed(4)}${suffix}`;
|
|
28425
|
+
return footprint.catalogStatus === "verified" ? "unmetered/unknown" : footprint.catalogReason;
|
|
28426
|
+
}
|
|
28374
28427
|
function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog) {
|
|
28375
28428
|
const breakdown = [];
|
|
28376
28429
|
const baseSystemPromptChars = 3200;
|
|
@@ -28416,7 +28469,14 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
28416
28469
|
const totalTokens = breakdown.reduce((sum, item) => sum + item.estimatedTokens, 0);
|
|
28417
28470
|
const maxContextWindow = 2e5;
|
|
28418
28471
|
const contextWindowRatio = Math.round(totalTokens / maxContextWindow * 1e3) / 10;
|
|
28419
|
-
const
|
|
28472
|
+
const loaded = loadPriceCatalogForEstimate(
|
|
28473
|
+
catalog ? { priceCatalog: catalog } : { projectRoot }
|
|
28474
|
+
);
|
|
28475
|
+
const catalogInfo = describePriceCatalogStatus(
|
|
28476
|
+
loaded,
|
|
28477
|
+
catalogDateForStatus(loaded, catalog, projectRoot)
|
|
28478
|
+
);
|
|
28479
|
+
const cat = loaded.catalog;
|
|
28420
28480
|
const rawModel = resolved.model || "grok/grok-4.6";
|
|
28421
28481
|
const [prov, mod] = rawModel.includes("/") ? rawModel.split("/", 2) : [void 0, rawModel];
|
|
28422
28482
|
const inputCost = cat ? calculateModelCost(cat, {
|
|
@@ -28455,7 +28515,9 @@ function calculatePromptFootprint(resolved, projectRoot = process.cwd(), catalog
|
|
|
28455
28515
|
inputCostUsd: inputCost?.costUsd ?? null,
|
|
28456
28516
|
cacheReadCostUsd: cacheReadCost?.costUsd ?? null,
|
|
28457
28517
|
outputCostEstimateUsd: outputEstimateCost?.costUsd ?? null
|
|
28458
|
-
}
|
|
28518
|
+
},
|
|
28519
|
+
catalogStatus: catalogInfo.catalogStatus,
|
|
28520
|
+
catalogReason: catalogInfo.catalogReason
|
|
28459
28521
|
};
|
|
28460
28522
|
}
|
|
28461
28523
|
function formatModesExplainReport(footprint) {
|
|
@@ -28473,6 +28535,8 @@ ${divider}
|
|
|
28473
28535
|
out += `Enabled Domains: ${footprint.enabledDomains.length > 0 ? footprint.enabledDomains.join(", ") : "(none)"}
|
|
28474
28536
|
`;
|
|
28475
28537
|
out += `Target Model: ${footprint.model}
|
|
28538
|
+
`;
|
|
28539
|
+
out += `Catalog status: ${footprint.catalogReason}
|
|
28476
28540
|
|
|
28477
28541
|
`;
|
|
28478
28542
|
out += `CONTEXT BREAKDOWN:
|
|
@@ -28492,11 +28556,11 @@ ${divider}
|
|
|
28492
28556
|
`;
|
|
28493
28557
|
out += `PROJECTED COSTS (per turn):
|
|
28494
28558
|
`;
|
|
28495
|
-
out += ` \u2022 Initial Turn Input Cost: ${footprint.projectedCost.inputCostUsd
|
|
28559
|
+
out += ` \u2022 Initial Turn Input Cost: ${formatExplainCost(footprint.projectedCost.inputCostUsd, footprint)}
|
|
28496
28560
|
`;
|
|
28497
|
-
out += ` \u2022 Subsequent Cache-Read Cost: ${footprint.projectedCost.cacheReadCostUsd
|
|
28561
|
+
out += ` \u2022 Subsequent Cache-Read Cost: ${formatExplainCost(footprint.projectedCost.cacheReadCostUsd, footprint, " (approx 90% savings)")}
|
|
28498
28562
|
`;
|
|
28499
|
-
out += ` \u2022 Output Estimate (1k tokens): ${footprint.projectedCost.outputCostEstimateUsd
|
|
28563
|
+
out += ` \u2022 Output Estimate (1k tokens): ${formatExplainCost(footprint.projectedCost.outputCostEstimateUsd, footprint)}
|
|
28500
28564
|
`;
|
|
28501
28565
|
out += `${divider}
|
|
28502
28566
|
`;
|
package/plugins/kxm/package.json
CHANGED
|
@@ -7,7 +7,7 @@ import { AGENT_COMMANDS_MAP, enforceToolPolicy, getMcpTools, reconcileInbox } fr
|
|
|
7
7
|
import { deliverInboxNotification } from "./inbox.ts";
|
|
8
8
|
import type { HubEvent, MessageRecord } from "./protocol.ts";
|
|
9
9
|
|
|
10
|
-
const VERSION = "0.7.
|
|
10
|
+
const VERSION = "0.7.14";
|
|
11
11
|
const inbox = new Map<string, MessageRecord>();
|
|
12
12
|
const notifiedInbox = new Set<string>();
|
|
13
13
|
let meshClient: HubClient | undefined;
|
package/plugins/kxm/src/modes.ts
CHANGED
|
@@ -8,7 +8,15 @@
|
|
|
8
8
|
import { existsSync, readFileSync } from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { parse } from "yaml";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
calculateModelCost,
|
|
13
|
+
loadPriceCatalog,
|
|
14
|
+
loadPriceCatalogForEstimate,
|
|
15
|
+
type PriceCatalog,
|
|
16
|
+
type PriceCatalogEstimateSource,
|
|
17
|
+
} from "./prices.ts";
|
|
18
|
+
|
|
19
|
+
export type PriceCatalogStatus = "verified" | "stale" | "corrupt" | "missing";
|
|
12
20
|
|
|
13
21
|
export interface MajorMode {
|
|
14
22
|
description?: string | undefined;
|
|
@@ -60,6 +68,8 @@ export interface PromptFootprint {
|
|
|
60
68
|
cacheReadCostUsd: number | null;
|
|
61
69
|
outputCostEstimateUsd: number | null;
|
|
62
70
|
};
|
|
71
|
+
catalogStatus: PriceCatalogStatus;
|
|
72
|
+
catalogReason: string;
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
export const DEFAULT_MODES_CONFIG: ModesConfig = Object.freeze({
|
|
@@ -195,6 +205,59 @@ export function resolveActiveMode(
|
|
|
195
205
|
};
|
|
196
206
|
}
|
|
197
207
|
|
|
208
|
+
const CATALOG_DATE_RE = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
|
|
209
|
+
|
|
210
|
+
function boundedCatalogDate(value: unknown): string | undefined {
|
|
211
|
+
return typeof value === "string" && CATALOG_DATE_RE.test(value) ? value : undefined;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function catalogDateForStatus(
|
|
215
|
+
loaded: PriceCatalogEstimateSource,
|
|
216
|
+
injected: PriceCatalog | undefined,
|
|
217
|
+
projectRoot: string,
|
|
218
|
+
): string | undefined {
|
|
219
|
+
const fromLoaded = boundedCatalogDate(loaded.catalog?.date);
|
|
220
|
+
if (fromLoaded) return fromLoaded;
|
|
221
|
+
const fromInjected = boundedCatalogDate(injected?.date);
|
|
222
|
+
if (fromInjected) return fromInjected;
|
|
223
|
+
if (!loaded.stale) return undefined;
|
|
224
|
+
try {
|
|
225
|
+
return boundedCatalogDate(loadPriceCatalog(projectRoot)?.date);
|
|
226
|
+
} catch {
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function describePriceCatalogStatus(
|
|
232
|
+
loaded: PriceCatalogEstimateSource,
|
|
233
|
+
catalogDate?: string,
|
|
234
|
+
): { catalogStatus: PriceCatalogStatus; catalogReason: string } {
|
|
235
|
+
if (loaded.stale) {
|
|
236
|
+
return {
|
|
237
|
+
catalogStatus: "stale",
|
|
238
|
+
catalogReason: catalogDate
|
|
239
|
+
? `price catalog stale (dated ${catalogDate})`
|
|
240
|
+
: "price catalog stale",
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
if (loaded.unavailable) {
|
|
244
|
+
return { catalogStatus: "corrupt", catalogReason: "price catalog corrupt" };
|
|
245
|
+
}
|
|
246
|
+
if (!loaded.catalog) {
|
|
247
|
+
return { catalogStatus: "missing", catalogReason: "price catalog missing" };
|
|
248
|
+
}
|
|
249
|
+
return { catalogStatus: "verified", catalogReason: "price catalog verified" };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function formatExplainCost(
|
|
253
|
+
value: number | null,
|
|
254
|
+
footprint: PromptFootprint,
|
|
255
|
+
suffix = "",
|
|
256
|
+
): string {
|
|
257
|
+
if (value !== null) return `$${value.toFixed(4)}${suffix}`;
|
|
258
|
+
return footprint.catalogStatus === "verified" ? "unmetered/unknown" : footprint.catalogReason;
|
|
259
|
+
}
|
|
260
|
+
|
|
198
261
|
/**
|
|
199
262
|
* Calculate the exact prompt token footprint and projected costs for a mode configuration.
|
|
200
263
|
*/
|
|
@@ -258,8 +321,15 @@ export function calculatePromptFootprint(
|
|
|
258
321
|
const maxContextWindow = 200000;
|
|
259
322
|
const contextWindowRatio = Math.round((totalTokens / maxContextWindow) * 1000) / 10;
|
|
260
323
|
|
|
261
|
-
// 5. Projected Costs
|
|
262
|
-
const
|
|
324
|
+
// 5. Projected Costs — unverified or stale catalogs stay unknown.
|
|
325
|
+
const loaded = loadPriceCatalogForEstimate(
|
|
326
|
+
catalog ? { priceCatalog: catalog } : { projectRoot },
|
|
327
|
+
);
|
|
328
|
+
const catalogInfo = describePriceCatalogStatus(
|
|
329
|
+
loaded,
|
|
330
|
+
catalogDateForStatus(loaded, catalog, projectRoot),
|
|
331
|
+
);
|
|
332
|
+
const cat = loaded.catalog;
|
|
263
333
|
const rawModel = resolved.model || "grok/grok-4.6";
|
|
264
334
|
const [prov, mod] = rawModel.includes("/") ? rawModel.split("/", 2) : [undefined, rawModel];
|
|
265
335
|
|
|
@@ -309,6 +379,8 @@ export function calculatePromptFootprint(
|
|
|
309
379
|
cacheReadCostUsd: cacheReadCost?.costUsd ?? null,
|
|
310
380
|
outputCostEstimateUsd: outputEstimateCost?.costUsd ?? null,
|
|
311
381
|
},
|
|
382
|
+
catalogStatus: catalogInfo.catalogStatus,
|
|
383
|
+
catalogReason: catalogInfo.catalogReason,
|
|
312
384
|
};
|
|
313
385
|
}
|
|
314
386
|
|
|
@@ -324,7 +396,8 @@ export function formatModesExplainReport(footprint: PromptFootprint): string {
|
|
|
324
396
|
out += `${divider}\n`;
|
|
325
397
|
out += `Major Mode: ${footprint.majorMode}\n`;
|
|
326
398
|
out += `Enabled Domains: ${footprint.enabledDomains.length > 0 ? footprint.enabledDomains.join(", ") : "(none)"}\n`;
|
|
327
|
-
out += `Target Model: ${footprint.model}\n
|
|
399
|
+
out += `Target Model: ${footprint.model}\n`;
|
|
400
|
+
out += `Catalog status: ${footprint.catalogReason}\n\n`;
|
|
328
401
|
|
|
329
402
|
out += `CONTEXT BREAKDOWN:\n`;
|
|
330
403
|
for (const item of footprint.breakdown) {
|
|
@@ -339,9 +412,9 @@ export function formatModesExplainReport(footprint: PromptFootprint): string {
|
|
|
339
412
|
out += ` ${totalPad} ${totalStr} (${footprint.contextWindowRatio}% of 200k window)\n\n`;
|
|
340
413
|
|
|
341
414
|
out += `PROJECTED COSTS (per turn):\n`;
|
|
342
|
-
out += ` • Initial Turn Input Cost: ${footprint.projectedCost.inputCostUsd
|
|
343
|
-
out += ` • Subsequent Cache-Read Cost: ${footprint.projectedCost.cacheReadCostUsd
|
|
344
|
-
out += ` • Output Estimate (1k tokens): ${footprint.projectedCost.outputCostEstimateUsd
|
|
415
|
+
out += ` • Initial Turn Input Cost: ${formatExplainCost(footprint.projectedCost.inputCostUsd, footprint)}\n`;
|
|
416
|
+
out += ` • Subsequent Cache-Read Cost: ${formatExplainCost(footprint.projectedCost.cacheReadCostUsd, footprint, " (approx 90% savings)")}\n`;
|
|
417
|
+
out += ` • Output Estimate (1k tokens): ${formatExplainCost(footprint.projectedCost.outputCostEstimateUsd, footprint)}\n`;
|
|
345
418
|
out += `${divider}\n`;
|
|
346
419
|
|
|
347
420
|
return out;
|
|
@@ -31,6 +31,7 @@ export interface PolicyDraftOptions {
|
|
|
31
31
|
readonly ceilings: Readonly<Record<string, PolicyDraftCeiling>>;
|
|
32
32
|
readonly nativePiBrakeProviders: readonly string[];
|
|
33
33
|
readonly piAllowedProviders: readonly string[];
|
|
34
|
+
readonly piNativeVendorProviders?: Readonly<Record<string, string>>;
|
|
34
35
|
readonly vendorAliases?: Readonly<Record<string, string>>;
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -408,8 +408,23 @@ function validateModelSemantics(model, label, options, evidence, issues) {
|
|
|
408
408
|
}
|
|
409
409
|
if (model.harness === "pi") {
|
|
410
410
|
const parts = typeof model.model === "string" ? model.model.split("/") : [];
|
|
411
|
-
|
|
411
|
+
const nativeVendors = isObject(options.piNativeVendorProviders) ? options.piNativeVendorProviders : {};
|
|
412
|
+
const provider = parts[0];
|
|
413
|
+
const owned = own(nativeVendors, provider) ? canonicalVendor(nativeVendors[provider], aliases) : "";
|
|
414
|
+
const minParts = owned ? 2 : 3;
|
|
415
|
+
const maxParts = owned ? 2 : Number.POSITIVE_INFINITY;
|
|
416
|
+
if (
|
|
417
|
+
parts.length < minParts
|
|
418
|
+
|| parts.length > maxParts
|
|
419
|
+
|| parts.some((part) => !part)
|
|
420
|
+
|| !options.piAllowedProviders.includes(provider)
|
|
421
|
+
|| (owned && !/^gemini-[a-z0-9.-]+$/.test(parts[1]))
|
|
422
|
+
) {
|
|
412
423
|
issues.push(issue("semantic", "unsupported_pi_model", label, "Pi model must use an allowlisted aggregator prefix"));
|
|
424
|
+
} else if (owned) {
|
|
425
|
+
if (owned !== vendor) {
|
|
426
|
+
issues.push(issue("semantic", "pi_native_vendor_forbidden", label, "native vendor cannot use Pi"));
|
|
427
|
+
}
|
|
413
428
|
} else {
|
|
414
429
|
const prefix = canonicalVendor(parts[1], aliases);
|
|
415
430
|
if (options.nativePiBrakeProviders.includes(prefix) || options.nativePiBrakeProviders.includes(vendor)) {
|
|
@@ -135,3 +135,35 @@ export function loadPriceCatalog(rootOrPath: string): PriceCatalog | undefined {
|
|
|
135
135
|
return parsePriceCatalog(content);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
/** Result of a hash-verified, freshness-gated catalog load used for list estimates. */
|
|
139
|
+
export interface PriceCatalogEstimateSource {
|
|
140
|
+
readonly catalog: PriceCatalog | undefined;
|
|
141
|
+
readonly unavailable: boolean;
|
|
142
|
+
readonly stale: boolean;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Load a price catalog the way one-shot settlement does: re-parse injected
|
|
147
|
+
* catalogs so the digest is checked, treat missing files as unknown, and drop
|
|
148
|
+
* any snapshot whose date is not today. Callers must not throw after spend.
|
|
149
|
+
*/
|
|
150
|
+
export function loadPriceCatalogForEstimate(options?: {
|
|
151
|
+
priceCatalog?: PriceCatalog | undefined;
|
|
152
|
+
projectRoot?: string | undefined;
|
|
153
|
+
}): PriceCatalogEstimateSource {
|
|
154
|
+
let catalog: PriceCatalog | undefined;
|
|
155
|
+
try {
|
|
156
|
+
catalog = options?.priceCatalog
|
|
157
|
+
? parsePriceCatalog(JSON.stringify(options.priceCatalog))
|
|
158
|
+
: loadPriceCatalog(options?.projectRoot ?? process.cwd());
|
|
159
|
+
} catch {
|
|
160
|
+
return { catalog: undefined, unavailable: true, stale: false };
|
|
161
|
+
}
|
|
162
|
+
// Without a freshness-aware vendor feed, don't silently quote an older
|
|
163
|
+
// local snapshot. Even today's hash-verified snapshot is only an estimate.
|
|
164
|
+
if (catalog && catalog.date !== new Date().toISOString().slice(0, 10)) {
|
|
165
|
+
return { catalog: undefined, unavailable: false, stale: true };
|
|
166
|
+
}
|
|
167
|
+
return { catalog, unavailable: false, stale: false };
|
|
168
|
+
}
|
|
169
|
+
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./vnext-harness.ts";
|
|
16
16
|
import {
|
|
17
17
|
calculateModelCost,
|
|
18
|
-
|
|
18
|
+
loadPriceCatalogForEstimate,
|
|
19
19
|
type PriceCatalog,
|
|
20
20
|
} from "./prices.ts";
|
|
21
21
|
|
|
@@ -566,12 +566,17 @@ export function createVnextPiProducer(options: VnextPiProducerOptions = {}): Vne
|
|
|
566
566
|
const cacheWriteTokens = typeof usage?.cacheWrite === "number" ? usage.cacheWrite : null;
|
|
567
567
|
const contextTokens = typeof usage?.contextUsage?.tokens === "number" ? usage.contextUsage.tokens : tokensIn;
|
|
568
568
|
|
|
569
|
-
//
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
569
|
+
// Catalog errors must not discard observed usage or crash settlement.
|
|
570
|
+
const providerMetadata: Record<string, string | number | boolean> = {};
|
|
571
|
+
const loaded = loadPriceCatalogForEstimate({
|
|
572
|
+
priceCatalog: options.priceCatalog,
|
|
573
|
+
projectRoot: options.projectRoot,
|
|
574
|
+
});
|
|
575
|
+
if (loaded.unavailable) providerMetadata.priceCatalogUnavailable = true;
|
|
576
|
+
if (loaded.stale) providerMetadata.priceCatalogStale = true;
|
|
577
|
+
const catalog = loaded.catalog;
|
|
578
|
+
const costBasis = "unknown" as const;
|
|
579
|
+
const costUsd = null;
|
|
575
580
|
if (catalog) {
|
|
576
581
|
const calculated = calculateModelCost(catalog, {
|
|
577
582
|
model: resolved.model,
|
|
@@ -582,10 +587,10 @@ export function createVnextPiProducer(options: VnextPiProducerOptions = {}): Vne
|
|
|
582
587
|
cacheWriteTokens,
|
|
583
588
|
contextTokens,
|
|
584
589
|
});
|
|
585
|
-
if (calculated) {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
590
|
+
if (calculated && Number.isFinite(calculated.costUsd)) {
|
|
591
|
+
providerMetadata.listCostUsd = calculated.costUsd;
|
|
592
|
+
providerMetadata.listPriceRef = calculated.priceRef;
|
|
593
|
+
providerMetadata.listPriceSha256 = catalog.sha256;
|
|
589
594
|
}
|
|
590
595
|
}
|
|
591
596
|
|
|
@@ -603,9 +608,9 @@ export function createVnextPiProducer(options: VnextPiProducerOptions = {}): Vne
|
|
|
603
608
|
provider: resolved.provider,
|
|
604
609
|
requestedModel: resolved.model,
|
|
605
610
|
effectiveModel: resolved.model,
|
|
611
|
+
providerMetadata,
|
|
606
612
|
...(resolved.thinking !== undefined ? { thinking: resolved.thinking } : {}),
|
|
607
613
|
agentRole: request.agentRole ?? request.agentId,
|
|
608
|
-
...(priceRef !== undefined ? { priceRef } : {}),
|
|
609
614
|
};
|
|
610
615
|
},
|
|
611
616
|
|
|
@@ -16,6 +16,8 @@ export const ERROR_CODES: readonly string[];
|
|
|
16
16
|
export const EFFORT: readonly string[];
|
|
17
17
|
export const NATIVE_PI_BRAKE_PROVIDERS: readonly string[];
|
|
18
18
|
export const PI_ALLOWED_PROVIDERS: readonly string[];
|
|
19
|
+
export const PI_NATIVE_VENDOR_PROVIDERS: Readonly<Record<string, string>>;
|
|
20
|
+
export const PI_ANTIGRAVITY_MODEL_ID: RegExp;
|
|
19
21
|
export const PI_NOUS_PORTAL_HY4: "nous-portal/tencent/hy4-preview";
|
|
20
22
|
export const PI_ADMITTED_WRITER: "openrouter/qwen/qwen3-coder-plus";
|
|
21
23
|
export const ROUTES: Record<string, {
|
|
@@ -27,7 +29,7 @@ export const ROUTES: Record<string, {
|
|
|
27
29
|
auth: { args: readonly string[]; loginHint: string };
|
|
28
30
|
}>;
|
|
29
31
|
|
|
30
|
-
export function clampEffort(harness: string, effort?: string): { effort?: string; clamped?: string };
|
|
32
|
+
export function clampEffort(harness: string, effort?: string, model?: string): { effort?: string; clamped?: string };
|
|
31
33
|
export function parseJson(text: string): unknown;
|
|
32
34
|
export function piProviderOf(model?: string): string | undefined;
|
|
33
35
|
export function piModelId(model?: string): string | undefined;
|
package/scripts/harness-run.mjs
CHANGED
|
@@ -72,8 +72,14 @@ export const NATIVE_PI_BRAKE_PROVIDERS = Object.freeze([
|
|
|
72
72
|
"deepseek",
|
|
73
73
|
]);
|
|
74
74
|
|
|
75
|
-
/** Verified Pi aggregator prefixes. Not a catalog and not a writer grant. */
|
|
76
|
-
export const PI_ALLOWED_PROVIDERS = Object.freeze(["openrouter", "nous-portal"]);
|
|
75
|
+
/** Verified Pi aggregator prefixes and native-vendor Pi providers. Not a catalog and not a writer grant. */
|
|
76
|
+
export const PI_ALLOWED_PROVIDERS = Object.freeze(["openrouter", "nous-portal", "antigravity"]);
|
|
77
|
+
|
|
78
|
+
/** Native-vendor Pi providers own one braked vendor. Aggregators are not listed here. */
|
|
79
|
+
export const PI_NATIVE_VENDOR_PROVIDERS = Object.freeze({ antigravity: "google" });
|
|
80
|
+
|
|
81
|
+
/** Gemini kebab ids for antigravity two-segment models (`antigravity/gemini-...`). */
|
|
82
|
+
export const PI_ANTIGRAVITY_MODEL_ID = /^gemini-[a-z0-9.-]+$/;
|
|
77
83
|
|
|
78
84
|
/** Exact helper model string after `@jayteelabs/pi-nous-portal-provider` is installed. */
|
|
79
85
|
export const PI_NOUS_PORTAL_HY4 = "nous-portal/tencent/hy4-preview";
|
|
@@ -171,8 +177,19 @@ export const ROUTES = Object.freeze({
|
|
|
171
177
|
|
|
172
178
|
const UNVERIFIED_HARNESSES = Object.freeze(["kimi", "gemini", "deepseek"]);
|
|
173
179
|
|
|
174
|
-
|
|
175
|
-
|
|
180
|
+
function piNativeVendor(provider) {
|
|
181
|
+
return Object.hasOwn(PI_NATIVE_VENDOR_PROVIDERS, provider)
|
|
182
|
+
? PI_NATIVE_VENDOR_PROVIDERS[provider]
|
|
183
|
+
: undefined;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const PI_NATIVE_VENDOR_EFFORTS = Object.freeze(["low", "medium", "high"]);
|
|
187
|
+
|
|
188
|
+
export function clampEffort(harness, effort, model) {
|
|
189
|
+
const provider = typeof model === "string" ? piProviderOf(model) : undefined;
|
|
190
|
+
const accepted = provider && piNativeVendor(provider)
|
|
191
|
+
? PI_NATIVE_VENDOR_EFFORTS
|
|
192
|
+
: (ROUTES[harness]?.efforts ?? []);
|
|
176
193
|
if (!effort) return { effort: undefined, clamped: undefined };
|
|
177
194
|
if (!EFFORT.includes(effort)) {
|
|
178
195
|
throw failClosed(`unknown effort ${effort}; expected one of ${EFFORT.join(", ")}`);
|
|
@@ -220,6 +237,9 @@ function piLoginHint(provider) {
|
|
|
220
237
|
return "pi install npm:@jayteelabs/pi-nous-portal-provider, then /login → subscription or API key → Nous Research Portal (or NOUS_API_KEY)";
|
|
221
238
|
}
|
|
222
239
|
if (provider === "openrouter") return "pi /login openrouter";
|
|
240
|
+
if (provider === "antigravity") {
|
|
241
|
+
return "pi /login antigravity (Google OAuth, localhost:51121, paste-URL fallback)";
|
|
242
|
+
}
|
|
223
243
|
return ROUTES.pi.auth.loginHint;
|
|
224
244
|
}
|
|
225
245
|
|
|
@@ -245,6 +265,7 @@ export function piModelId(model) {
|
|
|
245
265
|
function piProviderLabel(provider) {
|
|
246
266
|
if (provider === "nous-portal") return "Nous Portal";
|
|
247
267
|
if (provider === "openrouter") return "OpenRouter";
|
|
268
|
+
if (provider === "antigravity") return "Antigravity";
|
|
248
269
|
return "Pi provider";
|
|
249
270
|
}
|
|
250
271
|
|
|
@@ -433,11 +454,13 @@ export function parseAuth(harness, stdio, options = {}) {
|
|
|
433
454
|
const reportedFromJson = typeof payload?.provider === "string"
|
|
434
455
|
? payload.provider.trim().toLowerCase()
|
|
435
456
|
: undefined;
|
|
436
|
-
const reportedFromText = /\
|
|
437
|
-
? "
|
|
438
|
-
: /\
|
|
439
|
-
? "
|
|
440
|
-
:
|
|
457
|
+
const reportedFromText = /\bantigravity\b/i.test(text)
|
|
458
|
+
? "antigravity"
|
|
459
|
+
: /\bnous-portal\b/i.test(text)
|
|
460
|
+
? "nous-portal"
|
|
461
|
+
: /\bopenrouter\b/i.test(text)
|
|
462
|
+
? "openrouter"
|
|
463
|
+
: undefined;
|
|
441
464
|
const reported = reportedFromJson ?? reportedFromText ?? requested;
|
|
442
465
|
const jsonStatus = typeof payload?.status === "string" ? payload.status : undefined;
|
|
443
466
|
if (/not[_ ]ready/i.test(text) || (jsonStatus !== undefined && jsonStatus !== "ready")
|
|
@@ -452,7 +475,7 @@ export function parseAuth(harness, stdio, options = {}) {
|
|
|
452
475
|
}
|
|
453
476
|
if (!PI_ALLOWED_PROVIDERS.includes(reported)) {
|
|
454
477
|
throw failClosed(
|
|
455
|
-
loginHint("pi", `pi helper allows only openrouter
|
|
478
|
+
loginHint("pi", `pi helper allows only openrouter/*, nous-portal/*, or antigravity/*; ${reported} is not allowlisted.`, requested),
|
|
456
479
|
"auth",
|
|
457
480
|
);
|
|
458
481
|
}
|
|
@@ -1510,13 +1533,20 @@ export function preflightRequest(request) {
|
|
|
1510
1533
|
if (harness === "pi") {
|
|
1511
1534
|
const provider = piProviderOf(request.model);
|
|
1512
1535
|
if (!provider) {
|
|
1513
|
-
throw failClosed("pi model must be provider/id (openrouter
|
|
1536
|
+
throw failClosed("pi model must be provider/id (openrouter/*, nous-portal/*, or antigravity/* in this helper)");
|
|
1514
1537
|
}
|
|
1515
1538
|
if (NATIVE_PI_BRAKE_PROVIDERS.includes(provider)) {
|
|
1516
1539
|
throw failClosed(`pi brake: ${provider} has a native harness; refusing Pi impersonation`);
|
|
1517
1540
|
}
|
|
1518
1541
|
if (!PI_ALLOWED_PROVIDERS.includes(provider)) {
|
|
1519
|
-
throw failClosed(`pi helper allows only openrouter
|
|
1542
|
+
throw failClosed(`pi helper allows only openrouter/*, nous-portal/*, or antigravity/*; ${provider} is not a native CLI and is not allowlisted`);
|
|
1543
|
+
}
|
|
1544
|
+
if (piNativeVendor(provider)) {
|
|
1545
|
+
const modelId = piModelId(request.model);
|
|
1546
|
+
const parts = String(request.model).split("/");
|
|
1547
|
+
if (parts.length !== 2 || parts.some((part) => !part) || !modelId || !PI_ANTIGRAVITY_MODEL_ID.test(modelId)) {
|
|
1548
|
+
throw failClosed("pi antigravity models must be exactly two-segment Gemini kebab ids (antigravity/gemini-...)");
|
|
1549
|
+
}
|
|
1520
1550
|
}
|
|
1521
1551
|
if (request.role === "writer" && (request.model !== PI_ADMITTED_WRITER || request.permission !== "edit")) {
|
|
1522
1552
|
throw failClosed("pi writer refuses unsupported route; allows only authenticated openrouter/qwen/qwen3-coder-plus with edit permission; other models need reviewed route admission");
|
|
@@ -1602,7 +1632,7 @@ export async function runHarness(request, deps = {}) {
|
|
|
1602
1632
|
: undefined;
|
|
1603
1633
|
const cwd = request.cwd ?? process.cwd();
|
|
1604
1634
|
const env = deps.env ?? process.env;
|
|
1605
|
-
const { effort, clamped } = clampEffort(request.harness, request.effort);
|
|
1635
|
+
const { effort, clamped } = clampEffort(request.harness, request.effort, request.model);
|
|
1606
1636
|
const prepared = { ...request, effort };
|
|
1607
1637
|
const outputDir = ensureOutputDir(
|
|
1608
1638
|
request.output_dir ?? join(cwd, ".kxm", "logs", `harness-${now()}`),
|
|
@@ -1780,6 +1810,9 @@ export async function runHarness(request, deps = {}) {
|
|
|
1780
1810
|
} else if (request.harness === "agy" && authStatus.method === "antigravity-oauth") {
|
|
1781
1811
|
fields.costBasis = "unmetered";
|
|
1782
1812
|
fields.costUsd = undefined;
|
|
1813
|
+
} else if (request.harness === "pi" && authStatus.method === "antigravity") {
|
|
1814
|
+
fields.costBasis = "unmetered";
|
|
1815
|
+
fields.costUsd = undefined;
|
|
1783
1816
|
} else if (fields.costUsd === undefined && fields.providerReportedCostUsd === undefined) {
|
|
1784
1817
|
fields.costBasis = fields.costBasis ?? "unknown";
|
|
1785
1818
|
}
|
|
@@ -18,3 +18,7 @@ export interface LoadedPolicy { readonly identity: PolicyIdentity; readonly poli
|
|
|
18
18
|
export function loadTrustedRosterPolicy(): LoadedPolicy;
|
|
19
19
|
export function resolveBoundPolicy(identity: PolicyIdentity): LoadedPolicy;
|
|
20
20
|
export function canonicalVendor(value: string): string;
|
|
21
|
+
export function validateRosterDocument(
|
|
22
|
+
policy: RosterPolicy,
|
|
23
|
+
readBlob: (source: string) => string | Uint8Array | null | undefined,
|
|
24
|
+
): RosterPolicy;
|
|
@@ -4,7 +4,7 @@ import { createHash } from 'node:crypto';
|
|
|
4
4
|
import { lstatSync, readFileSync, realpathSync } from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
|
-
import { NATIVE_PI_BRAKE_PROVIDERS, PI_ALLOWED_PROVIDERS, ROUTES } from './harness-run.mjs';
|
|
7
|
+
import { NATIVE_PI_BRAKE_PROVIDERS, PI_ALLOWED_PROVIDERS, PI_ANTIGRAVITY_MODEL_ID, PI_NATIVE_VENDOR_PROVIDERS, ROUTES } from './harness-run.mjs';
|
|
8
8
|
|
|
9
9
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
10
10
|
const POLICY = '.kxm/roster.json';
|
|
@@ -84,19 +84,20 @@ function workingBytes(source) {
|
|
|
84
84
|
}
|
|
85
85
|
return readFileSync(current);
|
|
86
86
|
}
|
|
87
|
-
function
|
|
88
|
-
let policy;
|
|
89
|
-
try { policy = JSON.parse(bytes.toString('utf8')); } catch { refuse('invalid policy JSON'); }
|
|
87
|
+
export function validateRosterDocument(policy, readBlob) {
|
|
90
88
|
keys(policy, ['schema', 'routes', 'lineup', 'required_critics', 'model_origins'], 'policy');
|
|
91
89
|
if (policy.schema !== 'kxm.developer-roster.v1') refuse('unsupported schema');
|
|
92
90
|
record(policy.routes, 'routes'); record(policy.lineup, 'lineup'); record(policy.model_origins, 'model origins');
|
|
93
91
|
if (!Object.keys(policy.routes).length) refuse('empty routes');
|
|
92
|
+
if (typeof readBlob !== 'function') refuse('origin evidence reader required');
|
|
94
93
|
for (const [model, origin] of Object.entries(policy.model_origins)) {
|
|
95
94
|
text(model, 'origin model'); keys(origin, ['vendor', 'evidence'], 'origin');
|
|
96
95
|
text(origin.vendor, 'origin vendor');
|
|
97
96
|
if (PI_ALLOWED_PROVIDERS.includes(canonical(origin.vendor.toLowerCase()))) refuse('origin/vendor must name the model vendor, not billing provider');
|
|
98
97
|
keys(origin.evidence, ['source', 'sha256'], 'origin evidence'); digest(origin.evidence.sha256);
|
|
99
|
-
|
|
98
|
+
sourcePath(origin.evidence.source);
|
|
99
|
+
const bytes = readBlob(origin.evidence.source);
|
|
100
|
+
if (bytes == null || sha256(bytes) !== origin.evidence.sha256) refuse('origin evidence hash mismatch');
|
|
100
101
|
}
|
|
101
102
|
for (const [id, route] of Object.entries(policy.routes)) {
|
|
102
103
|
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(id)) refuse('invalid route id');
|
|
@@ -108,10 +109,26 @@ function validate(bytes, commit) {
|
|
|
108
109
|
if (!['admitted', 'retired'].includes(route.status)) refuse('unsupported status');
|
|
109
110
|
if (route.harness === 'pi') {
|
|
110
111
|
const parts = route.model.split('/');
|
|
111
|
-
|
|
112
|
-
const
|
|
112
|
+
const provider = parts[0];
|
|
113
|
+
const owned = Object.hasOwn(PI_NATIVE_VENDOR_PROVIDERS, provider)
|
|
114
|
+
? canonical(PI_NATIVE_VENDOR_PROVIDERS[provider])
|
|
115
|
+
: '';
|
|
116
|
+
const minParts = owned ? 2 : 3;
|
|
117
|
+
const maxParts = owned ? 2 : Number.POSITIVE_INFINITY;
|
|
118
|
+
if (
|
|
119
|
+
parts.length < minParts
|
|
120
|
+
|| parts.length > maxParts
|
|
121
|
+
|| !PI_ALLOWED_PROVIDERS.includes(provider)
|
|
122
|
+
|| parts.some(part => !part)
|
|
123
|
+
|| (owned && !PI_ANTIGRAVITY_MODEL_ID.test(parts[1]))
|
|
124
|
+
) refuse('unsupported Pi provider/model');
|
|
113
125
|
const vendor = canonical(route.vendor.toLowerCase());
|
|
114
|
-
if (
|
|
126
|
+
if (owned) {
|
|
127
|
+
if (owned !== vendor) refuse('native vendor cannot use Pi');
|
|
128
|
+
} else {
|
|
129
|
+
const prefix = canonical(parts[1].toLowerCase());
|
|
130
|
+
if (NATIVE_PI_BRAKE_PROVIDERS.includes(prefix) || NATIVE_PI_BRAKE_PROVIDERS.includes(vendor)) refuse('native vendor cannot use Pi');
|
|
131
|
+
}
|
|
115
132
|
if (!own(policy.model_origins, route.model)) refuse('missing exact model origin');
|
|
116
133
|
const origin = policy.model_origins[route.model];
|
|
117
134
|
if (canonical(origin.vendor.toLowerCase()) !== vendor || PI_ALLOWED_PROVIDERS.includes(vendor)) refuse('model origin/vendor mismatch');
|
|
@@ -140,6 +157,11 @@ function validate(bytes, commit) {
|
|
|
140
157
|
}
|
|
141
158
|
return policy;
|
|
142
159
|
}
|
|
160
|
+
function validate(bytes, commit) {
|
|
161
|
+
let policy;
|
|
162
|
+
try { policy = JSON.parse(bytes.toString('utf8')); } catch { refuse('invalid policy JSON'); }
|
|
163
|
+
return validateRosterDocument(policy, source => blobAt(commit, source).bytes);
|
|
164
|
+
}
|
|
143
165
|
export function loadTrustedRosterPolicy() {
|
|
144
166
|
const snapshot = control();
|
|
145
167
|
const { blob, bytes } = blobAt(snapshot.head, POLICY);
|