toolnexus 0.25.0 → 0.26.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/README.md +35 -0
- package/dist/classifier.d.ts +189 -31
- package/dist/classifier.js +589 -30
- package/dist/client.d.ts +6 -0
- package/dist/judge.d.ts +6 -3
- package/dist/judge.js +13 -1
- package/dist/serve.js +7 -0
- package/package.json +2 -2
- package/src/classifier.ts +677 -46
- package/src/client.ts +6 -0
- package/src/judge.ts +19 -4
- package/src/serve.ts +7 -0
package/dist/client.d.ts
CHANGED
|
@@ -208,6 +208,12 @@ export type MetricEvent = {
|
|
|
208
208
|
promptTokens: number;
|
|
209
209
|
completionTokens: number;
|
|
210
210
|
error?: string;
|
|
211
|
+
/** L1: how many questions were asked. */
|
|
212
|
+
questions: number;
|
|
213
|
+
/** L1: sha256 hex of `canonicalRequest(model, questions)` ("" when unencodable). */
|
|
214
|
+
questionsHash: string;
|
|
215
|
+
/** True when the decision came from the classifier cache and no request was sent. */
|
|
216
|
+
cached: boolean;
|
|
211
217
|
} | {
|
|
212
218
|
event: "classifier.warning";
|
|
213
219
|
question: string;
|
package/dist/judge.d.ts
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
*
|
|
8
8
|
* A gate never authorises; it only declines to decide.
|
|
9
9
|
*/
|
|
10
|
-
import { Classifier, Decision, type DecisionAnswer, type NoulCriteria, type
|
|
10
|
+
import { Classifier, Decision, type DecisionAnswer, type NoulCriteria, type AnyQuestion, type RecordedDecision } from "./classifier.js";
|
|
11
11
|
import type { Request } from "./types.js";
|
|
12
12
|
/** One named question of an ordered question list. */
|
|
13
13
|
export interface NamedQuestion {
|
|
14
14
|
name: string;
|
|
15
|
-
question:
|
|
15
|
+
question: AnyQuestion;
|
|
16
16
|
}
|
|
17
17
|
/** `noul` question with a name. Name the state field it judges in `instructions`. */
|
|
18
18
|
export declare function noul(name: string, instructions: string, criteria?: NoulCriteria): NamedQuestion;
|
|
@@ -20,8 +20,11 @@ export declare function noul(name: string, instructions: string, criteria?: Noul
|
|
|
20
20
|
export declare function choice(name: string, instructions: string, options: Record<string, string>): NamedQuestion;
|
|
21
21
|
/** `score` question with a name; `levels` is the ordered rubric. */
|
|
22
22
|
export declare function score(name: string, instructions: string, levels: string[]): NamedQuestion;
|
|
23
|
+
/** A raw question with a name: a System One type the library does not model (e.g. `box`), sent
|
|
24
|
+
* as written. Its answer decodes to a raw answer `{type, value}`. */
|
|
25
|
+
export declare function raw(name: string, type: string, instructions: string, criteria?: unknown): NamedQuestion;
|
|
23
26
|
/** Ordered list -> the §8B questions map. A duplicate name is an error naming it. */
|
|
24
|
-
export declare function questionMap(questions: readonly NamedQuestion[]): Record<string,
|
|
27
|
+
export declare function questionMap(questions: readonly NamedQuestion[]): Record<string, AnyQuestion>;
|
|
25
28
|
/** `role` next to the data's fields; a non-object value goes under `data`. */
|
|
26
29
|
export declare function State(role: string, data: unknown): Record<string, unknown>;
|
|
27
30
|
/** Sugar: `{context, message, ...extra}`. */
|
package/dist/judge.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* A gate never authorises; it only declines to decide.
|
|
9
9
|
*/
|
|
10
|
-
import { Classifier, noul as noulQ, choice as choiceQ, score as scoreQ, } from "./classifier.js";
|
|
10
|
+
import { Classifier, isRawAnswer, raw as rawQ, noul as noulQ, choice as choiceQ, score as scoreQ, } from "./classifier.js";
|
|
11
11
|
/** `noul` question with a name. Name the state field it judges in `instructions`. */
|
|
12
12
|
export function noul(name, instructions, criteria) {
|
|
13
13
|
return { name, question: noulQ(instructions, criteria) };
|
|
@@ -20,6 +20,11 @@ export function choice(name, instructions, options) {
|
|
|
20
20
|
export function score(name, instructions, levels) {
|
|
21
21
|
return { name, question: scoreQ(instructions, levels) };
|
|
22
22
|
}
|
|
23
|
+
/** A raw question with a name: a System One type the library does not model (e.g. `box`), sent
|
|
24
|
+
* as written. Its answer decodes to a raw answer `{type, value}`. */
|
|
25
|
+
export function raw(name, type, instructions, criteria) {
|
|
26
|
+
return { name, question: rawQ(type, instructions, criteria) };
|
|
27
|
+
}
|
|
23
28
|
/** Ordered list -> the §8B questions map. A duplicate name is an error naming it. */
|
|
24
29
|
export function questionMap(questions) {
|
|
25
30
|
const out = {};
|
|
@@ -47,6 +52,13 @@ function noulBand(p, b) {
|
|
|
47
52
|
return p < b.low ? "no" : p > b.high ? "yes" : "uncertain";
|
|
48
53
|
}
|
|
49
54
|
function wrap(a, b) {
|
|
55
|
+
if (isRawAnswer(a)) {
|
|
56
|
+
// An unmodelled answer type is never sure: there is no number to band.
|
|
57
|
+
const out = { ...a, sure: false };
|
|
58
|
+
Object.defineProperty(out, "value", { value: () => 0, enumerable: false });
|
|
59
|
+
Object.defineProperty(out, "pick", { value: () => "", enumerable: false });
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
50
62
|
const extra = a.type === "noul"
|
|
51
63
|
? { band: noulBand(a.noul, b) }
|
|
52
64
|
: { sure: a.confidence > b.high && !(a.type === "choice" && a.nearUniform) };
|
package/dist/serve.js
CHANGED
|
@@ -153,6 +153,13 @@ export async function startA2AServer(opts) {
|
|
|
153
153
|
// per request (stateless — sessionIdGenerator undefined). Checked first so
|
|
154
154
|
// `/mcp` is never shadowed by the A2A POST handler.
|
|
155
155
|
if (mcp && req.url && (req.url === "/mcp" || req.url.startsWith("/mcp?"))) {
|
|
156
|
+
// Stateless profile: no server-initiated SSE stream exists, so only POST is
|
|
157
|
+
// served. Refuse anything else at once (§7C) instead of holding a GET open.
|
|
158
|
+
if (req.method !== "POST") {
|
|
159
|
+
res.writeHead(405, { Allow: "POST" });
|
|
160
|
+
res.end();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
156
163
|
void (async () => {
|
|
157
164
|
const body = req.method === "POST" ? await readBody(req) : "";
|
|
158
165
|
const parsed = body ? safeJson(body) : undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolnexus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Dynamic MCP servers + agent skills as uniform tools for any LLM (opencode-style).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc -p tsconfig.json",
|
|
20
|
-
"test": "npm run build && node --experimental-strip-types --test test/unit.test.ts test/agents.test.ts test/agent-hooks.test.ts test/agent-inprocess.test.ts test/home.test.ts test/compaction.test.ts test/loop.test.ts test/in-process.test.ts test/translate.test.ts test/multimodal.test.ts test/classifier.test.ts test/acp.test.ts test/acp-client.test.ts test/issues.test.ts test/host-boundary.test.ts test/judge.test.ts test/batteries.test.ts test/host-engine.test.ts test/host-turn-durability.test.ts test/host-engine-asks.test.ts test/tool-concurrency.test.ts test/media.test.ts test/examples.test.ts test/mcphandler.test.ts test/mcphandler-conformance.test.ts test/mcp2026.test.ts",
|
|
20
|
+
"test": "npm run build && node --experimental-strip-types --test test/unit.test.ts test/agents.test.ts test/agent-hooks.test.ts test/agent-inprocess.test.ts test/home.test.ts test/compaction.test.ts test/loop.test.ts test/in-process.test.ts test/translate.test.ts test/multimodal.test.ts test/classifier.test.ts test/classifier-backends.test.ts test/acp.test.ts test/acp-client.test.ts test/issues.test.ts test/host-boundary.test.ts test/judge.test.ts test/batteries.test.ts test/host-engine.test.ts test/host-turn-durability.test.ts test/host-engine-asks.test.ts test/tool-concurrency.test.ts test/media.test.ts test/examples.test.ts test/mcphandler.test.ts test/mcphandler-conformance.test.ts test/mcp2026.test.ts test/serve-mcp-conformance.test.ts",
|
|
21
21
|
"example": "node --experimental-strip-types examples/basic.ts",
|
|
22
22
|
"example:judge": "node --experimental-strip-types examples/judge.ts",
|
|
23
23
|
"example:multimodal": "node --experimental-strip-types examples/multimodal.ts",
|