bantamkit-mcp 0.27.0 → 0.28.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/cli.js +6 -7
- package/dist/mcp/identity.d.ts +34 -1
- package/dist/mcp/identity.js +32 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -51,12 +51,13 @@
|
|
|
51
51
|
* reaches for is answered on the wire instead, by `build_identity`. `runtime-ts/README.md`
|
|
52
52
|
* and `docs/install.md` carry the same correction in their own words.
|
|
53
53
|
*/
|
|
54
|
-
import { readFileSync
|
|
54
|
+
import { readFileSync } from 'node:fs';
|
|
55
55
|
import { assetsRoot } from './assets.js';
|
|
56
56
|
import { BantamError } from './errors.js';
|
|
57
57
|
import { buildReport, resolveEventLogPath } from './mcpreport.js';
|
|
58
58
|
import { Memory } from './memory/component.js';
|
|
59
59
|
import { DEFAULT_INDEX_BUDGET } from './memory/store.js';
|
|
60
|
+
import { packFileCount } from './mcp/identity.js';
|
|
60
61
|
import { buildServer } from './mcp/server.js';
|
|
61
62
|
import { RawStdioTransport } from './mcp/transport.js';
|
|
62
63
|
import { ArgvError, formatHelp, formatUsageBlock, HelpRequested, helpWidth, parseArgs as parseWithSpec, pyIntStrict, } from './pyargparse.js';
|
|
@@ -207,12 +208,10 @@ async function main(argv) {
|
|
|
207
208
|
const options = parseArgs(argv);
|
|
208
209
|
if (options.assetsRoot) {
|
|
209
210
|
const root = assetsRoot();
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
process.stdout.write(`${root}\n${files} files\n`);
|
|
211
|
+
// `packFileCount`, not a second walk: the count printed here and the count
|
|
212
|
+
// `build_identity` reports must be the same number for the same pack, and on a
|
|
213
|
+
// `pip install` the unfiltered version made one process contradict itself.
|
|
214
|
+
process.stdout.write(`${root}\n${packFileCount(root)} files\n`);
|
|
216
215
|
return 0;
|
|
217
216
|
}
|
|
218
217
|
if (options.mcpReport) {
|
package/dist/mcp/identity.d.ts
CHANGED
|
@@ -10,10 +10,43 @@ export declare const SERVER_NAME = "bantamkit";
|
|
|
10
10
|
* `as_posix()` is why the parts are joined with `/` here and not with `path.sep`: on Windows
|
|
11
11
|
* the walk yields the same components and the digest must not change with the separator.
|
|
12
12
|
*/
|
|
13
|
-
export declare function treeDigest(root: string): {
|
|
13
|
+
export declare function treeDigest(root: string, keep?: (parts: string[]) => boolean): {
|
|
14
14
|
digest: string;
|
|
15
15
|
files: number;
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Fingerprint the asset pack this build would load — every file, not just the loaded ones.
|
|
19
|
+
*
|
|
20
|
+
* `contracts/default.yaml` is the reason: `RB-P84` measured it as the one asset that differed
|
|
21
|
+
* between two live builds while no resource template exposed it, so it was invisible on every
|
|
22
|
+
* probed surface. It is also why N1 ships all 84 files rather than the 20 that are read.
|
|
23
|
+
*
|
|
24
|
+
* EXCEPT bytecode caches, and that exception is the whole point of this field. The pack ships
|
|
25
|
+
* `.py` fixture files, so `pip install` byte-compiles them into `__pycache__` on the way in and
|
|
26
|
+
* the digest of an INSTALLED Python pack stopped matching the digest of the identical npm pack
|
|
27
|
+
* — measured on the published 0.27.0 artifacts, `sha256:fa8372f6…` over 98 files against
|
|
28
|
+
* `sha256:d47dcf4b…` over 87, and deleting `__pycache__` from the wheel's pack reproduced the
|
|
29
|
+
* npm digest byte for byte. `cross_runtime` tells the caller to compare `assets_digest` across
|
|
30
|
+
* runtimes; without this rule that instruction returned a false "different" on every real
|
|
31
|
+
* install. The pack is what was SHIPPED, never what an interpreter later wrote beside it.
|
|
32
|
+
*
|
|
33
|
+
* The rule is spelled identically in `runtime-py`'s `_assets_fingerprint`, and it has to be:
|
|
34
|
+
* this side never creates a `__pycache__`, so a Node-only exclusion would still agree today
|
|
35
|
+
* and diverge again the moment a pack carrying one reached both runtimes.
|
|
36
|
+
*/
|
|
37
|
+
export declare const notBytecodeCache: (parts: string[]) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The pack as SHIPPED, counted — what `--assets-root` prints.
|
|
40
|
+
*
|
|
41
|
+
* Exported so the CLI shares this walk rather than keeping a second one. There are TWO
|
|
42
|
+
* walks over this directory and a rule spelled twice is a rule that gets fixed once: the
|
|
43
|
+
* first version of this fix filtered the digest alone, and a `pip install` then had one
|
|
44
|
+
* process contradicting itself, `build_identity` answering 87 files while `--assets-root`
|
|
45
|
+
* printed 98 for the pack it had just loaded. The CLI's own `readdirSync(recursive)` is
|
|
46
|
+
* gone with it — `walkFiles` is the walk that mirrors CPython's `rglob`, which is what the
|
|
47
|
+
* reference's printer uses and what the conformance case compares the count against.
|
|
48
|
+
*/
|
|
49
|
+
export declare function packFileCount(root: string): number;
|
|
17
50
|
/** `sha256(json.dumps(inputs, sort_keys=True, separators=(",", ":")))` — the identity. */
|
|
18
51
|
export declare function buildIdFor(inputs: Record<string, string>): string;
|
|
19
52
|
/**
|
package/dist/mcp/identity.js
CHANGED
|
@@ -108,8 +108,9 @@ function walkFiles(root) {
|
|
|
108
108
|
* `as_posix()` is why the parts are joined with `/` here and not with `path.sep`: on Windows
|
|
109
109
|
* the walk yields the same components and the digest must not change with the separator.
|
|
110
110
|
*/
|
|
111
|
-
export function treeDigest(root) {
|
|
112
|
-
const
|
|
111
|
+
export function treeDigest(root, keep) {
|
|
112
|
+
const walked = walkFiles(root);
|
|
113
|
+
const files = keep === undefined ? walked : walked.filter(keep);
|
|
113
114
|
const running = createHash('sha256');
|
|
114
115
|
for (const parts of files) {
|
|
115
116
|
const payload = readFileSync(join(root, ...parts));
|
|
@@ -164,7 +165,35 @@ function codeFingerprint() {
|
|
|
164
165
|
* `contracts/default.yaml` is the reason: `RB-P84` measured it as the one asset that differed
|
|
165
166
|
* between two live builds while no resource template exposed it, so it was invisible on every
|
|
166
167
|
* probed surface. It is also why N1 ships all 84 files rather than the 20 that are read.
|
|
168
|
+
*
|
|
169
|
+
* EXCEPT bytecode caches, and that exception is the whole point of this field. The pack ships
|
|
170
|
+
* `.py` fixture files, so `pip install` byte-compiles them into `__pycache__` on the way in and
|
|
171
|
+
* the digest of an INSTALLED Python pack stopped matching the digest of the identical npm pack
|
|
172
|
+
* — measured on the published 0.27.0 artifacts, `sha256:fa8372f6…` over 98 files against
|
|
173
|
+
* `sha256:d47dcf4b…` over 87, and deleting `__pycache__` from the wheel's pack reproduced the
|
|
174
|
+
* npm digest byte for byte. `cross_runtime` tells the caller to compare `assets_digest` across
|
|
175
|
+
* runtimes; without this rule that instruction returned a false "different" on every real
|
|
176
|
+
* install. The pack is what was SHIPPED, never what an interpreter later wrote beside it.
|
|
177
|
+
*
|
|
178
|
+
* The rule is spelled identically in `runtime-py`'s `_assets_fingerprint`, and it has to be:
|
|
179
|
+
* this side never creates a `__pycache__`, so a Node-only exclusion would still agree today
|
|
180
|
+
* and diverge again the moment a pack carrying one reached both runtimes.
|
|
181
|
+
*/
|
|
182
|
+
export const notBytecodeCache = (parts) => !parts.includes('__pycache__');
|
|
183
|
+
/**
|
|
184
|
+
* The pack as SHIPPED, counted — what `--assets-root` prints.
|
|
185
|
+
*
|
|
186
|
+
* Exported so the CLI shares this walk rather than keeping a second one. There are TWO
|
|
187
|
+
* walks over this directory and a rule spelled twice is a rule that gets fixed once: the
|
|
188
|
+
* first version of this fix filtered the digest alone, and a `pip install` then had one
|
|
189
|
+
* process contradicting itself, `build_identity` answering 87 files while `--assets-root`
|
|
190
|
+
* printed 98 for the pack it had just loaded. The CLI's own `readdirSync(recursive)` is
|
|
191
|
+
* gone with it — `walkFiles` is the walk that mirrors CPython's `rglob`, which is what the
|
|
192
|
+
* reference's printer uses and what the conformance case compares the count against.
|
|
167
193
|
*/
|
|
194
|
+
export function packFileCount(root) {
|
|
195
|
+
return walkFiles(root).filter(notBytecodeCache).length;
|
|
196
|
+
}
|
|
168
197
|
function assetsFingerprint() {
|
|
169
198
|
let root;
|
|
170
199
|
try {
|
|
@@ -177,7 +206,7 @@ function assetsFingerprint() {
|
|
|
177
206
|
}
|
|
178
207
|
let walked;
|
|
179
208
|
try {
|
|
180
|
-
walked = treeDigest(root);
|
|
209
|
+
walked = treeDigest(root, notBytecodeCache);
|
|
181
210
|
}
|
|
182
211
|
catch (e) {
|
|
183
212
|
const error = e instanceof PyOSError ? e : asPyOSError(e, root);
|