runbios-mcp 0.2.1-dev.62

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.
Files changed (90) hide show
  1. package/README.md +363 -0
  2. package/dist/api-client.d.ts +147 -0
  3. package/dist/api-client.d.ts.map +1 -0
  4. package/dist/api-client.js +806 -0
  5. package/dist/api-client.js.map +1 -0
  6. package/dist/auth.d.ts +3 -0
  7. package/dist/auth.d.ts.map +1 -0
  8. package/dist/auth.js +11 -0
  9. package/dist/auth.js.map +1 -0
  10. package/dist/config.d.ts +30 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +16 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/deployment-contract.d.ts +78 -0
  15. package/dist/deployment-contract.d.ts.map +1 -0
  16. package/dist/deployment-contract.js +155 -0
  17. package/dist/deployment-contract.js.map +1 -0
  18. package/dist/gpu-priorities.d.ts +25 -0
  19. package/dist/gpu-priorities.d.ts.map +1 -0
  20. package/dist/gpu-priorities.js +61 -0
  21. package/dist/gpu-priorities.js.map +1 -0
  22. package/dist/http/app.d.ts +14 -0
  23. package/dist/http/app.d.ts.map +1 -0
  24. package/dist/http/app.js +140 -0
  25. package/dist/http/app.js.map +1 -0
  26. package/dist/http/audit.d.ts +23 -0
  27. package/dist/http/audit.d.ts.map +1 -0
  28. package/dist/http/audit.js +41 -0
  29. package/dist/http/audit.js.map +1 -0
  30. package/dist/http/config.d.ts +23 -0
  31. package/dist/http/config.d.ts.map +1 -0
  32. package/dist/http/config.js +70 -0
  33. package/dist/http/config.js.map +1 -0
  34. package/dist/http/consent.d.ts +18 -0
  35. package/dist/http/consent.d.ts.map +1 -0
  36. package/dist/http/consent.js +148 -0
  37. package/dist/http/consent.js.map +1 -0
  38. package/dist/http/internal-auth.d.ts +22 -0
  39. package/dist/http/internal-auth.d.ts.map +1 -0
  40. package/dist/http/internal-auth.js +73 -0
  41. package/dist/http/internal-auth.js.map +1 -0
  42. package/dist/http/main.d.ts +3 -0
  43. package/dist/http/main.d.ts.map +1 -0
  44. package/dist/http/main.js +65 -0
  45. package/dist/http/main.js.map +1 -0
  46. package/dist/http/mcp-handler.d.ts +12 -0
  47. package/dist/http/mcp-handler.d.ts.map +1 -0
  48. package/dist/http/mcp-handler.js +103 -0
  49. package/dist/http/mcp-handler.js.map +1 -0
  50. package/dist/http/metadata.d.ts +6 -0
  51. package/dist/http/metadata.d.ts.map +1 -0
  52. package/dist/http/metadata.js +32 -0
  53. package/dist/http/metadata.js.map +1 -0
  54. package/dist/http/oauth.d.ts +56 -0
  55. package/dist/http/oauth.d.ts.map +1 -0
  56. package/dist/http/oauth.js +486 -0
  57. package/dist/http/oauth.js.map +1 -0
  58. package/dist/http/serviceHostGuard.d.ts +31 -0
  59. package/dist/http/serviceHostGuard.d.ts.map +1 -0
  60. package/dist/http/serviceHostGuard.js +68 -0
  61. package/dist/http/serviceHostGuard.js.map +1 -0
  62. package/dist/http/store.d.ts +150 -0
  63. package/dist/http/store.d.ts.map +1 -0
  64. package/dist/http/store.js +366 -0
  65. package/dist/http/store.js.map +1 -0
  66. package/dist/index.d.ts +3 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +79 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/inference-contract.d.ts +29 -0
  71. package/dist/inference-contract.d.ts.map +1 -0
  72. package/dist/inference-contract.js +112 -0
  73. package/dist/inference-contract.js.map +1 -0
  74. package/dist/redaction.d.ts +74 -0
  75. package/dist/redaction.d.ts.map +1 -0
  76. package/dist/redaction.js +316 -0
  77. package/dist/redaction.js.map +1 -0
  78. package/dist/server.d.ts +63 -0
  79. package/dist/server.d.ts.map +1 -0
  80. package/dist/server.js +2282 -0
  81. package/dist/server.js.map +1 -0
  82. package/dist/training-contract.d.ts +107 -0
  83. package/dist/training-contract.d.ts.map +1 -0
  84. package/dist/training-contract.js +141 -0
  85. package/dist/training-contract.js.map +1 -0
  86. package/dist/version.d.ts +2 -0
  87. package/dist/version.d.ts.map +1 -0
  88. package/dist/version.js +2 -0
  89. package/dist/version.js.map +1 -0
  90. package/package.json +47 -0
@@ -0,0 +1,29 @@
1
+ export interface InferenceToolInput {
2
+ messages: Array<Record<string, unknown>>;
3
+ model?: string;
4
+ tools?: Array<Record<string, unknown>>;
5
+ tool_choice?: "none" | "auto" | "required" | Record<string, unknown>;
6
+ max_tokens?: number;
7
+ temperature?: number;
8
+ top_p?: number;
9
+ parallel_tool_calls?: boolean;
10
+ response_format?: Record<string, unknown>;
11
+ reasoning_effort?: "none" | "minimal" | "low" | "medium" | "high" | "max";
12
+ /**
13
+ * Request Server-Sent-Events streaming. The MCP tool consumes the SSE and
14
+ * aggregates content + reasoning_content deltas into one final result, so
15
+ * reasoning surfaces as it was produced. Defaults to false (single JSON).
16
+ */
17
+ stream?: boolean;
18
+ idempotency_key?: string;
19
+ request_id?: string;
20
+ }
21
+ /**
22
+ * Build an OpenAI chat-completions request and reject ambiguous tool histories.
23
+ * `stream` selects SSE (true) vs a single JSON body (false, the default);
24
+ * either way the same request is valid on the unified /v1 endpoint, whose
25
+ * model-ID routing serves dedicated deployments and serverless catalog models
26
+ * alike.
27
+ */
28
+ export declare function buildInferenceBody(input: InferenceToolInput): Record<string, unknown>;
29
+ //# sourceMappingURL=inference-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-contract.d.ts","sourceRoot":"","sources":["../src/inference-contract.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAC1E;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0FrF"}
@@ -0,0 +1,112 @@
1
+ const FUNCTION_NAME = /^[A-Za-z0-9_-]{1,64}$/;
2
+ const ROLES = new Set(["system", "developer", "user", "assistant", "tool", "function"]);
3
+ /**
4
+ * Build an OpenAI chat-completions request and reject ambiguous tool histories.
5
+ * `stream` selects SSE (true) vs a single JSON body (false, the default);
6
+ * either way the same request is valid on the unified /v1 endpoint, whose
7
+ * model-ID routing serves dedicated deployments and serverless catalog models
8
+ * alike.
9
+ */
10
+ export function buildInferenceBody(input) {
11
+ if (!Array.isArray(input.messages) || input.messages.length === 0) {
12
+ throw new Error("messages must be a non-empty array");
13
+ }
14
+ const tools = input.tools ?? [];
15
+ const names = [];
16
+ for (const tool of tools) {
17
+ if (tool.type !== "function" || !tool.function || typeof tool.function !== "object") {
18
+ throw new Error('each tool must have type="function" and a function object');
19
+ }
20
+ const fn = tool.function;
21
+ if (typeof fn.name !== "string" || !FUNCTION_NAME.test(fn.name)) {
22
+ throw new Error("tool function names must be 1-64 safe characters");
23
+ }
24
+ const parameters = fn.parameters;
25
+ if (parameters !== undefined && (!parameters || typeof parameters !== "object" || Array.isArray(parameters)
26
+ || (parameters.type ?? "object") !== "object")) {
27
+ throw new Error("tool parameters must be a JSON Schema object");
28
+ }
29
+ names.push(fn.name);
30
+ }
31
+ if (new Set(names).size !== names.length)
32
+ throw new Error("tool function names must be unique");
33
+ if (input.tool_choice && typeof input.tool_choice === "object") {
34
+ const fn = input.tool_choice.function;
35
+ const selected = fn && typeof fn === "object" ? fn.name : undefined;
36
+ if (typeof selected !== "string" || !names.includes(selected)) {
37
+ throw new Error("tool_choice references an undefined function");
38
+ }
39
+ }
40
+ else if ((input.tool_choice === "auto" || input.tool_choice === "required") && tools.length === 0) {
41
+ throw new Error("tool_choice requires at least one tool");
42
+ }
43
+ const pending = new Set();
44
+ for (const message of input.messages) {
45
+ const role = message.role;
46
+ if (typeof role !== "string" || !ROLES.has(role))
47
+ throw new Error("every message requires a valid role");
48
+ const calls = message.tool_calls;
49
+ if (calls !== undefined && role !== "assistant")
50
+ throw new Error("tool_calls are only valid on assistant messages");
51
+ if (role === "assistant" && Array.isArray(calls) && calls.length > 0) {
52
+ if (pending.size > 0)
53
+ throw new Error("tool calls must be resolved before the next turn");
54
+ for (const rawCall of calls) {
55
+ if (!rawCall || typeof rawCall !== "object")
56
+ throw new Error("assistant tool calls must be objects");
57
+ const call = rawCall;
58
+ const id = call.id;
59
+ const fn = call.function;
60
+ if (typeof id !== "string" || !id || pending.has(id)) {
61
+ throw new Error("assistant tool calls require unique, non-empty ids");
62
+ }
63
+ if (!fn || typeof fn !== "object")
64
+ throw new Error("assistant tool calls require a function");
65
+ const functionCall = fn;
66
+ if (tools.length > 0 && !names.includes(String(functionCall.name ?? ""))) {
67
+ throw new Error("assistant tool call references an undefined function");
68
+ }
69
+ let args = functionCall.arguments;
70
+ if (typeof args === "string") {
71
+ try {
72
+ args = JSON.parse(args);
73
+ }
74
+ catch {
75
+ throw new Error("tool call arguments must be valid JSON");
76
+ }
77
+ }
78
+ if (!args || typeof args !== "object" || Array.isArray(args)) {
79
+ throw new Error("tool call arguments must encode a JSON object");
80
+ }
81
+ pending.add(id);
82
+ }
83
+ }
84
+ else if (role === "tool") {
85
+ const id = message.tool_call_id;
86
+ if (typeof id !== "string" || !pending.delete(id)) {
87
+ throw new Error("tool message references an unknown tool_call_id");
88
+ }
89
+ }
90
+ else if (pending.size > 0) {
91
+ throw new Error("tool calls must be resolved before the next turn");
92
+ }
93
+ }
94
+ if (pending.size > 0)
95
+ throw new Error("assistant tool calls are missing tool response messages");
96
+ const body = { messages: input.messages, stream: input.stream === true };
97
+ // When streaming, ask the endpoint to emit a terminal usage row so the
98
+ // aggregated result can report token counts (streaming charging itself is a
99
+ // server-side concern; the client only requests visibility).
100
+ if (input.stream === true) {
101
+ body.stream_options = { include_usage: true };
102
+ }
103
+ for (const field of [
104
+ "model", "tools", "tool_choice", "max_tokens", "temperature", "top_p",
105
+ "parallel_tool_calls", "response_format", "reasoning_effort",
106
+ ]) {
107
+ if (input[field] !== undefined)
108
+ body[field] = input[field];
109
+ }
110
+ return body;
111
+ }
112
+ //# sourceMappingURL=inference-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-contract.js","sourceRoot":"","sources":["../src/inference-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * An MCP client is an external program the customer runs, so a tool RESULT is a
3
+ * customer-facing response — exactly like an HTTP body the console renders.
4
+ * Several tools hand the upstream payload straight back (`json(data)`), which
5
+ * is how internal build identity reached MCP clients: the architecture registry
6
+ * ships the engine image reference that published each row, and the training
7
+ * contract ships the image version range it was written against.
8
+ *
9
+ * Two facts never leave the platform on a customer surface:
10
+ * 1. any container image name, version, tag, digest or path;
11
+ * 2. the identity of any supplier we buy capacity from.
12
+ *
13
+ * The rule here is CONTENT, not field name. Dropping a known key is defeated
14
+ * the moment the same value appears somewhere else — the architecture registry
15
+ * bakes the tag into free-text `notes` ("BIOS <tag>: llama, mistral"), so a
16
+ * key-only strip leaves the identical string one field over. What replaces a
17
+ * removed reference is the platform's own name and, at the envelope, the
18
+ * customer-meaningful fact (Run BiOS ran this end to end) — never a blank, and
19
+ * never a marker that advertises the existence of the thing being hidden.
20
+ *
21
+ * ── Why the names below are hashes ──────────────────────────────────────────
22
+ * `npm publish` ships `dist/`, so anything this module states in plaintext is
23
+ * downloadable by every customer. A guard that lists what to hide as literal
24
+ * alternations hands over exactly the roster it exists to protect — strictly
25
+ * worse than the one leak it was written to stop, because it needs no error to
26
+ * occur. So the NAMES are salted FNV-1a hashes matched token by token, and only
27
+ * SHAPES (a digest, an `owner/name:tag` reference, our own product name next to
28
+ * a version) stay readable — a shape discloses nothing.
29
+ *
30
+ * Honest limitation: a hash CONFIRMS a guess. Someone who already suspects a
31
+ * name can hash it and find it here. What they cannot do is ENUMERATE, which is
32
+ * what a plaintext list hands them. The authoritative fix stays upstream, in
33
+ * the services that should not send these fields at all.
34
+ */
35
+ /** What the customer can rely on in place of a build reference. */
36
+ export declare const VERIFIED_ON_RUN_BIOS: string;
37
+ /**
38
+ * Remove internal build identity from one string of platform-authored text.
39
+ * Text with nothing to remove is returned untouched — never reformatted.
40
+ */
41
+ export declare function redactBuildIdentity(value: string): string;
42
+ /** Recursively apply redactBuildIdentity to every string in a JSON value. */
43
+ export declare function redactBuildIdentityDeep<T>(value: T): T;
44
+ /** Drop every build-identity key, at any depth, then redact what remains. */
45
+ export declare function stripBuildIdentity<T>(value: T): T;
46
+ /**
47
+ * Redact build identity inside NAMED free-text fields only, leaving every other
48
+ * value byte-identical.
49
+ *
50
+ * Some upstream contracts store a raw transport error verbatim rather than a
51
+ * curated sentence: the training stop saga persists the Go `*url.Error` from
52
+ * its last request to the machine, and that error's text is the full URL — a
53
+ * host that names the capacity supplier. The deployment side already curates
54
+ * its equivalent field before answering; the training side does not, so the
55
+ * value reaches this process intact and is removed here, at the boundary the
56
+ * MCP client reads. Scoped by key (not applied to the whole payload) because
57
+ * the same object carries model ids and config values, which have the same
58
+ * `owner/name:value` shape as a build reference and must survive untouched.
59
+ */
60
+ export declare function redactFreeTextFields<T>(value: T, keys: readonly string[]): T;
61
+ /**
62
+ * The architecture registry answer, with the build identity of the manifest
63
+ * that published each row removed.
64
+ *
65
+ * Every row records image_tag / bios_version / manifest_sha256 from the engine
66
+ * build whose capability manifest last published it, and the supported-row
67
+ * `notes` repeat the same tag as prose. None of that is a customer fact: the
68
+ * customer cannot choose a build, and the support decision is authoritative
69
+ * regardless (the deploy and training gates read these same rows). So the rows
70
+ * are preserved in full minus their build identity, and the response states
71
+ * what the customer can actually rely on.
72
+ */
73
+ export declare function sanitizeArchitectureRegistry(data: unknown): unknown;
74
+ //# sourceMappingURL=redaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAyCH,mEAAmE;AACnE,eAAO,MAAM,oBAAoB,QAEwE,CAAC;AAoH1G;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAsBzD;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAWtD;AAuBD,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAWjD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,CAc5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAOnE"}
@@ -0,0 +1,316 @@
1
+ /**
2
+ * An MCP client is an external program the customer runs, so a tool RESULT is a
3
+ * customer-facing response — exactly like an HTTP body the console renders.
4
+ * Several tools hand the upstream payload straight back (`json(data)`), which
5
+ * is how internal build identity reached MCP clients: the architecture registry
6
+ * ships the engine image reference that published each row, and the training
7
+ * contract ships the image version range it was written against.
8
+ *
9
+ * Two facts never leave the platform on a customer surface:
10
+ * 1. any container image name, version, tag, digest or path;
11
+ * 2. the identity of any supplier we buy capacity from.
12
+ *
13
+ * The rule here is CONTENT, not field name. Dropping a known key is defeated
14
+ * the moment the same value appears somewhere else — the architecture registry
15
+ * bakes the tag into free-text `notes` ("BIOS <tag>: llama, mistral"), so a
16
+ * key-only strip leaves the identical string one field over. What replaces a
17
+ * removed reference is the platform's own name and, at the envelope, the
18
+ * customer-meaningful fact (Run BiOS ran this end to end) — never a blank, and
19
+ * never a marker that advertises the existence of the thing being hidden.
20
+ *
21
+ * ── Why the names below are hashes ──────────────────────────────────────────
22
+ * `npm publish` ships `dist/`, so anything this module states in plaintext is
23
+ * downloadable by every customer. A guard that lists what to hide as literal
24
+ * alternations hands over exactly the roster it exists to protect — strictly
25
+ * worse than the one leak it was written to stop, because it needs no error to
26
+ * occur. So the NAMES are salted FNV-1a hashes matched token by token, and only
27
+ * SHAPES (a digest, an `owner/name:tag` reference, our own product name next to
28
+ * a version) stay readable — a shape discloses nothing.
29
+ *
30
+ * Honest limitation: a hash CONFIRMS a guess. Someone who already suspects a
31
+ * name can hash it and find it here. What they cannot do is ENUMERATE, which is
32
+ * what a plaintext list hands them. The authoritative fix stays upstream, in
33
+ * the services that should not send these fields at all.
34
+ */
35
+ const HASH_SALT = "bios-mcp/redaction/v1:";
36
+ /** FNV-1a (32-bit), base-36. Not a security hash — an anti-enumeration one. */
37
+ function fingerprint(normalized) {
38
+ let h = 0x811c9dc5;
39
+ for (let i = 0; i < normalized.length; i += 1) {
40
+ h ^= normalized.charCodeAt(i);
41
+ h = Math.imul(h, 0x01000193) >>> 0;
42
+ }
43
+ return h.toString(36);
44
+ }
45
+ /**
46
+ * Fingerprints of the engine/image repositories Run BiOS builds and runs, our
47
+ * storage namespaces, the serving and training engines behind them, and the
48
+ * capacity suppliers we buy from. Separators are normalized away before
49
+ * hashing, so a hyphenated, dotted, spaced or run-together spelling of the same
50
+ * name all collapse onto one entry.
51
+ *
52
+ * A name that is also ordinary English or ML vocabulary is deliberately NOT a
53
+ * single-token entry — blanking those words would corrupt legitimate platform
54
+ * text — and is covered only in its unambiguous two-word form.
55
+ *
56
+ * The plaintext inputs live in test/build-identity-leak.test.ts, which asserts
57
+ * that every one of them still redacts. Tests are not published.
58
+ */
59
+ const INTERNAL_NAME_FINGERPRINTS = new Set([
60
+ "10x0xbx", "12wy7fm", "13xtaj5", "1810k1x", "18usfr7", "199flq2", "1a1qwfu",
61
+ "1a7nk5a", "1bk01j6", "1dihvvx", "1etj9sp", "1f8y85q", "1fg3w0r", "1g76afq",
62
+ "1ij8vte", "1k55s00", "1l27e3z", "1o62s5m", "1spctel", "1wkeshf", "4q2wdq",
63
+ "8an6wv", "adgu8j", "bdgi9y", "d32wt5", "dl793q", "jrv624", "pr8tmh",
64
+ "pvzflf", "uwkhbj", "vdixvx", "yj2u8f",
65
+ ]);
66
+ /** How many adjacent word-parts are joined when testing a candidate name. */
67
+ const MAX_NAME_PARTS = 2;
68
+ const REPLACEMENT = "Run BiOS";
69
+ /** What the customer can rely on in place of a build reference. */
70
+ export const VERIFIED_ON_RUN_BIOS = "Every architecture listed here has been run end to end on Run BiOS and confirmed to load and serve; "
71
+ + "the enabled flags are authoritative because the deployment and training gates read these same rows.";
72
+ /**
73
+ * Platform-authored sentences that FRAME a build reference. Rewriting the whole
74
+ * sentence keeps the note readable, instead of leaving the punctuation that
75
+ * wrapped the reference stranded around a hole. These are shapes and our own
76
+ * product name, so they are safe to state plainly.
77
+ */
78
+ const BUILD_SENTENCE_REWRITES = [
79
+ // "Not supported by the training engine (BIOS <tag>)."
80
+ {
81
+ pattern: /\bnot supported by (?:the )?(?:training|serving|inference) engine\s*\([^)]*\)\.?/gi,
82
+ replacement: "Not supported on Run BiOS today.",
83
+ },
84
+ // "Dropped by training engine <tag>."
85
+ {
86
+ pattern: /\bdropped by (?:the )?(?:training|serving|inference) engine\b[^.;\n]*\.?/gi,
87
+ replacement: "No longer supported on Run BiOS.",
88
+ },
89
+ // "BIOS <tag>: llama, mistral" — the supported-row note prefix. The version
90
+ // goes; the platform name and the model types the note carries stay. The
91
+ // optional "Run " prefix consumes the two-word form whole, so a note already
92
+ // written "Run BiOS <tag>" collapses to one brand mention, not "Run Run
93
+ // BiOS".
94
+ {
95
+ pattern: /(^|[\s(])(?:Run[\s@]+)?BIOS[\s@:]+v?\d[\w.\-]*(?::[\w.\-]+)?(?:@sha256:[0-9a-fA-F]+)?/gi,
96
+ replacement: `$1${REPLACEMENT}`,
97
+ },
98
+ ];
99
+ /**
100
+ * Build references matched by SHAPE. Path-segment repetition is bounded: an OCI
101
+ * reference is never many segments deep, and an unbounded `*` over free text
102
+ * the platform does not control is a backtracking liability.
103
+ */
104
+ const BUILD_SHAPE_PATTERNS = [
105
+ // Any digest-pinned OCI reference, whatever the registry:
106
+ // `[host[:port]/]repo[/path]@sha256:<hex>`. A catalog model id pins a 40-hex
107
+ // GIT commit and never uses `@sha256:`, so this cannot eat one.
108
+ /(?:[A-Za-z0-9][\w.-]*(?::\d+)?\/)?[A-Za-z0-9][\w.-]*(?:\/[A-Za-z0-9][\w.-]*){0,6}@sha256:[0-9a-fA-F]{16,}/g,
109
+ // A bare digest left on its own.
110
+ /\bsha256:[0-9a-fA-F]{16,}/g,
111
+ // A TAGGED image reference: `[host/]owner/name:tag`, at least one slash and a
112
+ // trailing `:tag`. A catalog model id is `owner/name` with no tag and pins a
113
+ // revision with `@<40-hex>`, so it can never take this shape. An all-digit
114
+ // suffix is excluded so a `path/file.py:88` line reference in a log survives.
115
+ /\b[A-Za-z0-9][\w.-]*(?:\/[A-Za-z0-9][\w.-]*){1,6}:(?![0-9]+(?![\w.-]))[A-Za-z0-9][\w.-]{0,60}\b/g,
116
+ ];
117
+ /** Lower-case alphanumeric runs — the units a name is tested against. */
118
+ function wordParts(token) {
119
+ return token.toLowerCase().match(/[a-z0-9]+/g) ?? [];
120
+ }
121
+ /** Does this token (or a run of its parts) fingerprint to an internal name? */
122
+ function namesInternalThing(token) {
123
+ const parts = wordParts(token);
124
+ for (let i = 0; i < parts.length; i += 1) {
125
+ for (let len = 1; len <= MAX_NAME_PARTS && i + len <= parts.length; len += 1) {
126
+ const candidate = parts.slice(i, i + len).join("");
127
+ if (candidate.length < 4)
128
+ continue; // too short to be a name; avoids noise
129
+ if (INTERNAL_NAME_FINGERPRINTS.has(fingerprint(HASH_SALT + candidate)))
130
+ return true;
131
+ }
132
+ }
133
+ return false;
134
+ }
135
+ /** Replace one word-part inside a token, keeping the punctuation around it. */
136
+ function replacePart(token, part, replacement, fromEnd) {
137
+ const matcher = new RegExp(part, "i");
138
+ if (!fromEnd)
139
+ return token.replace(matcher, replacement);
140
+ const index = token.toLowerCase().lastIndexOf(part);
141
+ if (index < 0)
142
+ return token;
143
+ return token.slice(0, index) + replacement + token.slice(index + part.length);
144
+ }
145
+ /**
146
+ * Replace any whitespace-delimited token that names an internal thing. Adjacent
147
+ * tokens are also tested joined, so a two-word name is caught
148
+ * without either half being blocked on its own.
149
+ */
150
+ function redactInternalNames(value) {
151
+ const tokens = value.split(/(\s+)/);
152
+ let changed = false;
153
+ for (let i = 0; i < tokens.length; i += 1) {
154
+ const token = tokens[i];
155
+ if (!token || /^\s+$/.test(token))
156
+ continue;
157
+ if (namesInternalThing(token)) {
158
+ tokens[i] = REPLACEMENT;
159
+ changed = true;
160
+ continue;
161
+ }
162
+ // Two-word name split across the space. Machine-generated text almost never
163
+ // presents the halves as two bare words — it glues the first half to the
164
+ // key, bracket or quote in front of it (`key="<first> <second>"`,
165
+ // `rank1(<first> <second>)`), so requiring both tokens to be a single
166
+ // word-part let every realistic shape through. Pair the LAST word-part of
167
+ // this token with the FIRST of the next, and blank only those two parts so
168
+ // the surrounding key/punctuation the caller needs survives.
169
+ const nextIndex = i + 2;
170
+ const next = tokens[nextIndex];
171
+ if (!next || /^\s+$/.test(next))
172
+ continue;
173
+ const leadParts = wordParts(token);
174
+ const tailParts = wordParts(next);
175
+ const lead = leadParts[leadParts.length - 1];
176
+ const tail = tailParts[0];
177
+ if (lead && tail && namesInternalThing(lead + tail)) {
178
+ tokens[i] = replacePart(token, lead, REPLACEMENT, true);
179
+ tokens[i + 1] = "";
180
+ tokens[nextIndex] = replacePart(next, tail, "", false);
181
+ changed = true;
182
+ }
183
+ }
184
+ return changed ? tokens.join("") : value;
185
+ }
186
+ /**
187
+ * Remove internal build identity from one string of platform-authored text.
188
+ * Text with nothing to remove is returned untouched — never reformatted.
189
+ */
190
+ export function redactBuildIdentity(value) {
191
+ // Order matters: references go first, so the sentence rules then see a clean
192
+ // "…engine BiOS." and can rewrite the whole sentence. Reversing it leaves the
193
+ // tail of a version string ("…on BiOS.51.") behind.
194
+ let out = value;
195
+ for (const pattern of BUILD_SHAPE_PATTERNS) {
196
+ out = out.replace(pattern, REPLACEMENT);
197
+ }
198
+ out = redactInternalNames(out);
199
+ for (const { pattern, replacement } of BUILD_SENTENCE_REWRITES) {
200
+ out = out.replace(pattern, replacement);
201
+ }
202
+ if (out === value)
203
+ return value;
204
+ return out
205
+ // Two removals in a row, or our own name left in front of one — matched in
206
+ // both the legacy one-word and the current two-word brand forms.
207
+ .replace(/\b(?:Run BiOS|BIOS|BiOS)(?:[\s@:]+(?:Run BiOS|BiOS))+\b/g, REPLACEMENT)
208
+ // A removal can strand the punctuation that framed the reference.
209
+ .replace(/\s+([:.,;])/g, "$1")
210
+ .replace(/\(\s*\)/g, "")
211
+ .replace(/\s{2,}/g, " ")
212
+ .trim();
213
+ }
214
+ /** Recursively apply redactBuildIdentity to every string in a JSON value. */
215
+ export function redactBuildIdentityDeep(value) {
216
+ if (typeof value === "string")
217
+ return redactBuildIdentity(value);
218
+ if (Array.isArray(value))
219
+ return value.map((entry) => redactBuildIdentityDeep(entry));
220
+ if (value && typeof value === "object") {
221
+ const out = {};
222
+ for (const [key, entry] of Object.entries(value)) {
223
+ out[key] = redactBuildIdentityDeep(entry);
224
+ }
225
+ return out;
226
+ }
227
+ return value;
228
+ }
229
+ /**
230
+ * Keys that carry build identity outright. They are dropped wherever they
231
+ * appear in a platform-authored payload; the content rules above then catch the
232
+ * same value when it also lives in free text.
233
+ *
234
+ * Applied ONLY to platform-authored payloads (the architecture registry, the
235
+ * training contract) — never to customer data such as a dataset preview or a
236
+ * model completion, where a key like `image` means the customer's own content.
237
+ */
238
+ const BUILD_IDENTITY_KEYS = new Set([
239
+ "image_tag",
240
+ "imageTag",
241
+ "bios_version",
242
+ "biosVersion",
243
+ "manifest_sha256",
244
+ "manifestSha256",
245
+ "image_compatibility",
246
+ "engine_image",
247
+ "base_image",
248
+ ]);
249
+ /** Drop every build-identity key, at any depth, then redact what remains. */
250
+ export function stripBuildIdentity(value) {
251
+ if (Array.isArray(value))
252
+ return value.map((entry) => stripBuildIdentity(entry));
253
+ if (value && typeof value === "object") {
254
+ const out = {};
255
+ for (const [key, entry] of Object.entries(value)) {
256
+ if (BUILD_IDENTITY_KEYS.has(key))
257
+ continue;
258
+ out[key] = stripBuildIdentity(entry);
259
+ }
260
+ return out;
261
+ }
262
+ return redactBuildIdentityDeep(value);
263
+ }
264
+ /**
265
+ * Redact build identity inside NAMED free-text fields only, leaving every other
266
+ * value byte-identical.
267
+ *
268
+ * Some upstream contracts store a raw transport error verbatim rather than a
269
+ * curated sentence: the training stop saga persists the Go `*url.Error` from
270
+ * its last request to the machine, and that error's text is the full URL — a
271
+ * host that names the capacity supplier. The deployment side already curates
272
+ * its equivalent field before answering; the training side does not, so the
273
+ * value reaches this process intact and is removed here, at the boundary the
274
+ * MCP client reads. Scoped by key (not applied to the whole payload) because
275
+ * the same object carries model ids and config values, which have the same
276
+ * `owner/name:value` shape as a build reference and must survive untouched.
277
+ */
278
+ export function redactFreeTextFields(value, keys) {
279
+ const named = new Set(keys);
280
+ const walk = (node) => {
281
+ if (Array.isArray(node))
282
+ return node.map(walk);
283
+ if (node && typeof node === "object") {
284
+ const out = {};
285
+ for (const [key, entry] of Object.entries(node)) {
286
+ out[key] = named.has(key) && typeof entry === "string" ? redactBuildIdentity(entry) : walk(entry);
287
+ }
288
+ return out;
289
+ }
290
+ return node;
291
+ };
292
+ return walk(value);
293
+ }
294
+ /**
295
+ * The architecture registry answer, with the build identity of the manifest
296
+ * that published each row removed.
297
+ *
298
+ * Every row records image_tag / bios_version / manifest_sha256 from the engine
299
+ * build whose capability manifest last published it, and the supported-row
300
+ * `notes` repeat the same tag as prose. None of that is a customer fact: the
301
+ * customer cannot choose a build, and the support decision is authoritative
302
+ * regardless (the deploy and training gates read these same rows). So the rows
303
+ * are preserved in full minus their build identity, and the response states
304
+ * what the customer can actually rely on.
305
+ */
306
+ export function sanitizeArchitectureRegistry(data) {
307
+ if (!data || typeof data !== "object" || Array.isArray(data))
308
+ return stripBuildIdentity(data);
309
+ const payload = data;
310
+ if (!Array.isArray(payload.architectures))
311
+ return stripBuildIdentity(data);
312
+ const clean = stripBuildIdentity(payload);
313
+ clean.verification = VERIFIED_ON_RUN_BIOS;
314
+ return clean;
315
+ }
316
+ //# sourceMappingURL=redaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redaction.js","sourceRoot":"","sources":["../src/redaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { BiosClient } from "./api-client.js";
3
+ import { type LaunchGates } from "./config.js";
4
+ import { VERSION } from "./version.js";
5
+ export { VERSION };
6
+ export interface ToolCallInfo {
7
+ tool: string;
8
+ ok: boolean;
9
+ ms: number;
10
+ error?: string;
11
+ }
12
+ export interface ServerHooks {
13
+ onToolCall?: (info: ToolCallInfo) => void;
14
+ }
15
+ export interface DeploymentCapabilities {
16
+ supportsImages?: boolean;
17
+ supportsTools?: boolean;
18
+ }
19
+ /**
20
+ * Label the architecture registry's provenance instead of shipping it bare.
21
+ *
22
+ * Each row in the registry TABLE records image_tag/bios_version/manifest_sha256
23
+ * from the serving image whose capability manifest last published it. That is
24
+ * REGISTRY PROVENANCE, not the image the platform is running now, and the two
25
+ * drift apart whenever a newer image has not re-published the manifest. An
26
+ * agent that reads a build reference next to a support list concludes "the
27
+ * platform runs this build" and tells the user a stale version — a wrong action
28
+ * caused purely by presentation. The support decision itself IS authoritative
29
+ * (the deploy gate reads these same rows), so the rows are preserved; the
30
+ * internal image reference is removed by CONTENT from every field of every
31
+ * scope (see redactBuildReferences) and replaced with an explicit provenance
32
+ * block. Fixing the underlying manifest staleness is a control-plane concern
33
+ * and is deliberately NOT duplicated here.
34
+ *
35
+ * Those three columns no longer REACH this function: the public endpoint
36
+ * projects them away before the response leaves the control plane. What arrives
37
+ * here is the customer projection, and this block must describe that.
38
+ *
39
+ * The block itself only asserts what the rows actually carry, and since the
40
+ * control plane started projecting this endpoint that is LESS than it once was:
41
+ * image_tag, bios_version and manifest_sha256 are dropped at the boundary now
42
+ * (publicArchRow in deployment-service), so no response can still see them.
43
+ * Counting them here would therefore report 0 forever and drive the block to
44
+ * announce "no row records a build version" about a registry whose rows do —
45
+ * narrating a field that is empty on every row is the same defect one level up,
46
+ * and asserting a fact about rows this layer can no longer inspect is worse.
47
+ * `source` is the discriminator that survives the projection, so it is the one
48
+ * this block counts on.
49
+ */
50
+ export declare function annotateArchitectureProvenance(data: unknown): unknown;
51
+ /**
52
+ * Summarize what a deployment detail payload ACTUALLY proves about the GPU and
53
+ * the lifecycle phase.
54
+ *
55
+ * The detail response is wide and reports several things as null until a pod
56
+ * callback lands, which reads to an agent as "no GPU" and "no phase" on a
57
+ * deployment that is demonstrably provisioning on a known SKU. Everything here
58
+ * is derived from fields the same payload returned — nothing is invented, and a
59
+ * value that cannot be derived stays "unknown" instead of being guessed.
60
+ */
61
+ export declare function summarizeInferenceStatus(data: unknown): unknown;
62
+ export declare function createBiosMcpServer(client: BiosClient, hooks?: ServerHooks, deploymentCaps?: DeploymentCapabilities, launchGates?: LaunchGates): McpServer;
63
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkDpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CAC3C;AAUD,MAAM,WAAW,sBAAsB;IAErC,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAkYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAkDrE;AA0BD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAiD/D;AAID,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,KAAK,CAAC,EAAE,WAAW,EACnB,cAAc,CAAC,EAAE,sBAAsB,EAOvC,WAAW,GAAE,WAAkC,GAC9C,SAAS,CAghEX"}