@map-audio/pam-mcp-server 1.27.0 → 1.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/README.md +31 -10
- package/dist/bridge.d.ts +5 -1
- package/dist/bridge.js +41 -40
- package/dist/bridge.js.map +1 -1
- package/dist/daemon.d.ts +32 -0
- package/dist/daemon.js +871 -0
- package/dist/daemon.js.map +7 -0
- package/dist/drumSynth.d.ts +12 -0
- package/dist/drumSynth.js +14 -2
- package/dist/drumSynth.js.map +1 -1
- package/dist/drumSynthEngines.json +9 -1
- package/dist/{fgemma-format.d.ts → functiongemma-format.d.ts} +25 -7
- package/dist/{fgemma-format.js → functiongemma-format.js} +34 -11
- package/dist/functiongemma-format.js.map +1 -0
- package/dist/functiongemma-grammar.d.ts +14 -0
- package/dist/functiongemma-grammar.js +140 -0
- package/dist/functiongemma-grammar.js.map +1 -0
- package/dist/functiongemma-params.d.ts +33 -0
- package/dist/functiongemma-params.js +128 -0
- package/dist/functiongemma-params.js.map +1 -0
- package/dist/{fgemma-runner.d.ts → functiongemma-runner.d.ts} +8 -5
- package/dist/{fgemma-runner.js → functiongemma-runner.js} +87 -21
- package/dist/functiongemma-runner.js.map +1 -0
- package/dist/generativePlayerPresets.json +9 -0
- package/dist/generativePlayers.json +14 -0
- package/dist/launcher.d.ts +2 -0
- package/dist/launcher.js +36 -0
- package/dist/launcher.js.map +1 -0
- package/dist/manifest-mfx.json +12920 -277
- package/dist/manifest-msq.json +1989 -107
- package/dist/manifest.d.ts +2 -0
- package/dist/manifest.js +7 -27
- package/dist/manifest.js.map +1 -1
- package/dist/manifest.json +24194 -345
- package/dist/mfxCombos.d.ts +2 -0
- package/dist/mfxCombos.js +179 -56
- package/dist/mfxCombos.js.map +1 -1
- package/dist/midiFile.d.ts +19 -5
- package/dist/midiFile.js +21 -13
- package/dist/midiFile.js.map +1 -1
- package/dist/mixAssist.js +3 -2
- package/dist/mixAssist.js.map +1 -1
- package/dist/players.d.ts +22 -0
- package/dist/players.js +70 -0
- package/dist/players.js.map +1 -1
- package/dist/productProfile.d.ts +4 -4
- package/dist/productProfile.js +10 -1
- package/dist/productProfile.js.map +1 -1
- package/dist/qwen-format.d.ts +85 -0
- package/dist/qwen-format.js +355 -0
- package/dist/qwen-format.js.map +1 -0
- package/dist/registration.mjs +41 -0
- package/dist/server.js +1309 -187
- package/dist/server.js.map +1 -1
- package/dist/variationSessionKeys.json +6 -4
- package/package.json +13 -7
- package/dist/fgemma-format.js.map +0 -1
- package/dist/fgemma-runner.js.map +0 -1
- package/dist/manifest-cell1.json +0 -12968
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// GBNF from a toolpack: declared tools, keys in renderValue's dictsort order, schema-typed values.
|
|
2
|
+
// "lazy" roots at the call token (llama-server trigger); "full" also admits call-free text (wllama).
|
|
3
|
+
import { byKeyDictsort, renderNumber } from "./functiongemma-format.js";
|
|
4
|
+
export const CALL_TRIGGER = "<start_function_call>";
|
|
5
|
+
export const DEFAULT_MAX_CALLS = 12;
|
|
6
|
+
const PRIMITIVES = [
|
|
7
|
+
'string ::= <escape> [^<]* <escape>',
|
|
8
|
+
'integer ::= "-"? ([0-9] | [1-9] [0-9]{1,15})',
|
|
9
|
+
'number ::= "-"? ([0-9] | [1-9] [0-9]{1,15}) ("." [0-9]{1,16})? ([eE] [-+]? [0-9]{1,3})?',
|
|
10
|
+
'boolean ::= "true" | "false"',
|
|
11
|
+
'any-value ::= string | number | boolean | "null" | any-array | any-object',
|
|
12
|
+
'any-array ::= "[" (any-value ("," any-value)*)? "]"',
|
|
13
|
+
'any-object ::= "{" (any-key ":" any-value ("," any-key ":" any-value)*)? "}"',
|
|
14
|
+
'any-key ::= [A-Za-z_] [A-Za-z0-9_]*',
|
|
15
|
+
];
|
|
16
|
+
export function gbnfLiteral(text) {
|
|
17
|
+
const body = [...text]
|
|
18
|
+
.map((ch) => {
|
|
19
|
+
if (ch === '"' || ch === "\\")
|
|
20
|
+
return `\\${ch}`;
|
|
21
|
+
if (ch === "\n")
|
|
22
|
+
return "\\n";
|
|
23
|
+
if (ch === "\t")
|
|
24
|
+
return "\\t";
|
|
25
|
+
if (ch === "\r")
|
|
26
|
+
return "\\r";
|
|
27
|
+
const cp = ch.codePointAt(0);
|
|
28
|
+
return cp < 0x20 ? `\\x${cp.toString(16).padStart(2, "0")}` : ch;
|
|
29
|
+
})
|
|
30
|
+
.join("");
|
|
31
|
+
return `"${body}"`;
|
|
32
|
+
}
|
|
33
|
+
function enumLiteral(value) {
|
|
34
|
+
if (typeof value === "string")
|
|
35
|
+
return `<escape> ${gbnfLiteral(value)} <escape>`;
|
|
36
|
+
if (typeof value === "number")
|
|
37
|
+
return gbnfLiteral(renderNumber(value));
|
|
38
|
+
if (typeof value === "boolean" || value === null)
|
|
39
|
+
return gbnfLiteral(String(value));
|
|
40
|
+
throw new Error(`unsupported enum value in FunctionGemma grammar: ${JSON.stringify(value)}`);
|
|
41
|
+
}
|
|
42
|
+
class RuleSet {
|
|
43
|
+
rules = [];
|
|
44
|
+
names = new Set(PRIMITIVES.map((r) => r.split(" ::= ")[0]));
|
|
45
|
+
name(base) {
|
|
46
|
+
const stem = base.replace(/[^A-Za-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "rule";
|
|
47
|
+
let name = stem;
|
|
48
|
+
for (let i = 2; this.names.has(name); i++)
|
|
49
|
+
name = `${stem}-${i}`;
|
|
50
|
+
this.names.add(name);
|
|
51
|
+
return name;
|
|
52
|
+
}
|
|
53
|
+
add(name, body) {
|
|
54
|
+
this.rules.push(`${name} ::= ${body}`);
|
|
55
|
+
return name;
|
|
56
|
+
}
|
|
57
|
+
/** The rule (or inline expression) matching one value of `schema`. */
|
|
58
|
+
value(schema, base) {
|
|
59
|
+
if (Array.isArray(schema.enum) && schema.enum.length > 0) {
|
|
60
|
+
return this.add(this.name(base), schema.enum.map(enumLiteral).join(" | "));
|
|
61
|
+
}
|
|
62
|
+
const types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : [];
|
|
63
|
+
if (types.length === 0)
|
|
64
|
+
return "any-value";
|
|
65
|
+
const alts = types.map((type) => {
|
|
66
|
+
switch (type) {
|
|
67
|
+
case "string":
|
|
68
|
+
case "integer":
|
|
69
|
+
case "number":
|
|
70
|
+
case "boolean":
|
|
71
|
+
return type;
|
|
72
|
+
case "null":
|
|
73
|
+
return '"null"';
|
|
74
|
+
case "array": {
|
|
75
|
+
const item = schema.items ? this.value(schema.items, `${base}-item`) : "any-value";
|
|
76
|
+
return this.add(this.name(`${base}-array`), `"[" (${item} ("," ${item})*)? "]"`);
|
|
77
|
+
}
|
|
78
|
+
case "object":
|
|
79
|
+
return schema.properties ? this.object(schema, base) : "any-object";
|
|
80
|
+
default:
|
|
81
|
+
throw new Error(`unsupported schema type in FunctionGemma grammar: ${type}`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return alts.length === 1 ? alts[0] : `(${alts.join(" | ")})`;
|
|
85
|
+
}
|
|
86
|
+
/** Declared keys in renderValue order; each optional key may be skipped, every required one appears. */
|
|
87
|
+
object(schema, base) {
|
|
88
|
+
const name = this.name(base);
|
|
89
|
+
const required = new Set(schema.required ?? []);
|
|
90
|
+
const keys = Object.entries(schema.properties ?? {}).sort(byKeyDictsort);
|
|
91
|
+
if (keys.length === 0)
|
|
92
|
+
return this.add(name, '"{" "}"');
|
|
93
|
+
const pairs = keys.map(([key, sub]) => `${gbnfLiteral(`${key}:`)} ${this.value(sub, `${base}-${key}`)}`);
|
|
94
|
+
// after[i]: the rest of the object once some earlier key was written.
|
|
95
|
+
const after = new Array(keys.length + 1).fill("");
|
|
96
|
+
for (let i = keys.length - 1; i >= 1; i--) {
|
|
97
|
+
const item = required.has(keys[i][0]) ? `"," ${pairs[i]}` : `("," ${pairs[i]})?`;
|
|
98
|
+
after[i] = this.add(this.name(`${base}-after-${keys[i][0]}`), `${item}${after[i + 1] ? ` ${after[i + 1]}` : ""}`);
|
|
99
|
+
}
|
|
100
|
+
const firstRequired = keys.findIndex(([key]) => required.has(key));
|
|
101
|
+
const heads = keys
|
|
102
|
+
.slice(0, firstRequired === -1 ? keys.length : firstRequired + 1)
|
|
103
|
+
.map((_, i) => `${pairs[i]}${after[i + 1] ? ` ${after[i + 1]}` : ""}`);
|
|
104
|
+
const optional = firstRequired === -1;
|
|
105
|
+
const body = heads.length === 1 && !optional ? heads[0] : `(${heads.join(" | ")})${optional ? "?" : ""}`;
|
|
106
|
+
return this.add(name, `"{" ${body} "}"`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** GBNF for one assistant turn's call blocks, generated from the toolpack the model is prompted with. */
|
|
110
|
+
export function buildToolGrammar(tools, opts = {}) {
|
|
111
|
+
const mode = opts.mode ?? "lazy";
|
|
112
|
+
const maxCalls = opts.maxCalls ?? DEFAULT_MAX_CALLS;
|
|
113
|
+
if (!Number.isInteger(maxCalls) || maxCalls < 1)
|
|
114
|
+
throw new Error(`maxCalls must be a positive integer: ${maxCalls}`);
|
|
115
|
+
if (tools.length === 0)
|
|
116
|
+
throw new Error("FunctionGemma grammar needs at least one tool");
|
|
117
|
+
const set = new RuleSet();
|
|
118
|
+
const toolRules = tools.map((tool) => {
|
|
119
|
+
const args = set.object((tool.parameters ?? { type: "object", properties: {} }), `${tool.name}-args`);
|
|
120
|
+
return set.add(set.name(`tool-${tool.name}`), `${gbnfLiteral(tool.name)} ${args}`);
|
|
121
|
+
});
|
|
122
|
+
const calls = `call-block{1,${maxCalls}} <start_function_response>?`;
|
|
123
|
+
const header = [
|
|
124
|
+
`root ::= ${mode === "full" ? `${calls} | free-text` : calls}`,
|
|
125
|
+
"call-block ::= <start_function_call> \"call:\" call-body <end_function_call>",
|
|
126
|
+
`call-body ::= ${toolRules.join(" | ")}`,
|
|
127
|
+
...(mode === "full" ? ["free-text ::= (!<start_function_call>)*"] : []),
|
|
128
|
+
];
|
|
129
|
+
return [...header, ...set.rules, ...PRIMITIVES].join("\n") + "\n";
|
|
130
|
+
}
|
|
131
|
+
/** llama-server request fields that apply `grammar` lazily from the first call token. */
|
|
132
|
+
export function lazyGrammarRequest(grammar) {
|
|
133
|
+
return {
|
|
134
|
+
grammar,
|
|
135
|
+
grammar_lazy: true,
|
|
136
|
+
grammar_triggers: [{ type: 1, value: CALL_TRIGGER }],
|
|
137
|
+
preserved_tokens: [CALL_TRIGGER],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=functiongemma-grammar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functiongemma-grammar.js","sourceRoot":"","sources":["../src/functiongemma-grammar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface ParamKind {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
words: string[];
|
|
5
|
+
phrases: string[];
|
|
6
|
+
scope: "cell" | "lfo" | "looper" | "master" | "global";
|
|
7
|
+
unit?: string;
|
|
8
|
+
text: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ParamIndex {
|
|
11
|
+
stopwords: string[];
|
|
12
|
+
synonyms: Record<string, string[]>;
|
|
13
|
+
idf: Record<string, number>;
|
|
14
|
+
kinds: ParamKind[];
|
|
15
|
+
}
|
|
16
|
+
export declare const PARAMS_MAX_ENTRIES = 6;
|
|
17
|
+
export declare const PARAMS_MAX_CHARS = 700;
|
|
18
|
+
export declare const UNIT_FILL = 3;
|
|
19
|
+
export declare function queryTokens(text: string, index: ParamIndex): string[];
|
|
20
|
+
export declare function rankKinds(text: string, index: ParamIndex, sel?: number | null): ParamKind[];
|
|
21
|
+
export declare function unitWord(text: string): string | null;
|
|
22
|
+
/** The stated unit's kinds: the previous turn's first, then the generic ones (volume / cutoff). */
|
|
23
|
+
export declare function unitFill(text: string, index: ParamIndex, opts?: {
|
|
24
|
+
sel?: number | null;
|
|
25
|
+
previous?: string | null;
|
|
26
|
+
}): {
|
|
27
|
+
unit: string | null;
|
|
28
|
+
fill: ParamKind[];
|
|
29
|
+
};
|
|
30
|
+
export declare function renderParamsLine(text: string, index: ParamIndex, opts?: {
|
|
31
|
+
sel?: number | null;
|
|
32
|
+
previous?: string | null;
|
|
33
|
+
}): string;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
export const PARAMS_MAX_ENTRIES = 6;
|
|
2
|
+
export const PARAMS_MAX_CHARS = 700;
|
|
3
|
+
const SPLIT = /[^a-z0-9]+/;
|
|
4
|
+
const CELL = /\bcell\s*\d/;
|
|
5
|
+
const LFO = /\blfo\s*\d/;
|
|
6
|
+
const TRACK = /\btrack\s*\d/;
|
|
7
|
+
// When the best name match has a different unit, include up to UNIT_FILL matches for the stated unit.
|
|
8
|
+
const UNITS = [
|
|
9
|
+
[/[0-9] *db(?![a-z0-9])/i, "db", "volume"],
|
|
10
|
+
[/[0-9] *k?hz(?![a-z0-9])/i, "hz", "cutoff"],
|
|
11
|
+
];
|
|
12
|
+
const UNIT_STRIP = /([0-9]) *(?:db|k?hz)(?![a-z0-9])/gi;
|
|
13
|
+
export const UNIT_FILL = 3;
|
|
14
|
+
const stem = (w) => (w.length > 3 && w.endsWith("s") && !w.endsWith("ss") ? w.slice(0, -1) : w);
|
|
15
|
+
const prepared = new WeakMap();
|
|
16
|
+
function prep(index) {
|
|
17
|
+
let p = prepared.get(index);
|
|
18
|
+
if (!p) {
|
|
19
|
+
const stop = new Set(index.stopwords);
|
|
20
|
+
const words = index.kinds.map((k) => new Set(k.words));
|
|
21
|
+
const labelWords = index.kinds.map((k) => {
|
|
22
|
+
const out = [];
|
|
23
|
+
for (const raw of k.label.toLowerCase().split(SPLIT)) {
|
|
24
|
+
if (!raw || /^\d+$/.test(raw))
|
|
25
|
+
continue;
|
|
26
|
+
const ws = stem(raw);
|
|
27
|
+
if (!stop.has(ws))
|
|
28
|
+
out.push(ws);
|
|
29
|
+
}
|
|
30
|
+
return out;
|
|
31
|
+
});
|
|
32
|
+
p = { stop, words, labelWords };
|
|
33
|
+
prepared.set(index, p);
|
|
34
|
+
}
|
|
35
|
+
return p;
|
|
36
|
+
}
|
|
37
|
+
export function queryTokens(text, index) {
|
|
38
|
+
const { stop } = prep(index);
|
|
39
|
+
const out = [];
|
|
40
|
+
const camelSplit = String(text).replace(/([a-z0-9])([A-Z])/g, "$1 $2");
|
|
41
|
+
for (const raw of camelSplit.toLowerCase().split(SPLIT)) {
|
|
42
|
+
if (!raw || /^\d+$/.test(raw))
|
|
43
|
+
continue;
|
|
44
|
+
const w = stem(raw);
|
|
45
|
+
if (stop.has(w))
|
|
46
|
+
continue;
|
|
47
|
+
const synonyms = Object.hasOwn(index.synonyms, w) ? index.synonyms[w] : [];
|
|
48
|
+
for (const t of [w, ...synonyms])
|
|
49
|
+
if (!out.includes(t))
|
|
50
|
+
out.push(t);
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
function scopeOf(text, sel) {
|
|
55
|
+
const low = String(text).toLowerCase();
|
|
56
|
+
const words = new Set(low.split(SPLIT));
|
|
57
|
+
if (words.has("master"))
|
|
58
|
+
return "master";
|
|
59
|
+
if (LFO.test(low))
|
|
60
|
+
return "lfo";
|
|
61
|
+
if (words.has("looper") || TRACK.test(low))
|
|
62
|
+
return "looper";
|
|
63
|
+
if (CELL.test(low) || sel)
|
|
64
|
+
return "cell";
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
export function rankKinds(text, index, sel) {
|
|
68
|
+
const { words, labelWords } = prep(index);
|
|
69
|
+
const tokens = queryTokens(text, index);
|
|
70
|
+
const joined = ` ${tokens.join(" ")} `;
|
|
71
|
+
const scope = scopeOf(text, sel);
|
|
72
|
+
const tokenSet = new Set(tokens);
|
|
73
|
+
const scored = [];
|
|
74
|
+
index.kinds.forEach((kind, pos) => {
|
|
75
|
+
let s = 0;
|
|
76
|
+
for (const w of tokens)
|
|
77
|
+
if (words[pos].has(w))
|
|
78
|
+
s += index.idf[w];
|
|
79
|
+
for (const phrase of kind.phrases)
|
|
80
|
+
if (joined.includes(` ${phrase} `))
|
|
81
|
+
s += 1.0;
|
|
82
|
+
if (s > 0 && labelWords[pos].length && labelWords[pos].every((lw) => tokenSet.has(lw)))
|
|
83
|
+
s += 1.0;
|
|
84
|
+
if (s > 0 && kind.scope === scope)
|
|
85
|
+
s += 0.5;
|
|
86
|
+
if (s > 0)
|
|
87
|
+
scored.push([-s, pos, kind]);
|
|
88
|
+
});
|
|
89
|
+
scored.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
|
90
|
+
return scored.slice(0, PARAMS_MAX_ENTRIES).map(([, , k]) => k);
|
|
91
|
+
}
|
|
92
|
+
export function unitWord(text) {
|
|
93
|
+
return UNITS.find(([re]) => re.test(String(text)))?.[2] ?? null;
|
|
94
|
+
}
|
|
95
|
+
/** The stated unit's kinds: the previous turn's first, then the generic ones (volume / cutoff). */
|
|
96
|
+
export function unitFill(text, index, opts = {}) {
|
|
97
|
+
const stated = UNITS.find(([re]) => re.test(String(text)));
|
|
98
|
+
if (!stated)
|
|
99
|
+
return { unit: null, fill: [] };
|
|
100
|
+
const [, unit, word] = stated;
|
|
101
|
+
const strip = (t) => String(t).replace(UNIT_STRIP, "$1 ");
|
|
102
|
+
const fill = opts.previous ? rankKinds(strip(opts.previous), index, opts.sel).filter((k) => k.unit === unit) : [];
|
|
103
|
+
const bare = strip(text);
|
|
104
|
+
for (const k of rankKinds(`${bare} ${word}`, index, opts.sel))
|
|
105
|
+
if (k.unit === unit && !fill.includes(k))
|
|
106
|
+
fill.push(k);
|
|
107
|
+
return { unit, fill: fill.slice(0, UNIT_FILL) };
|
|
108
|
+
}
|
|
109
|
+
export function renderParamsLine(text, index, opts = {}) {
|
|
110
|
+
const { unit, fill } = unitFill(text, index, opts);
|
|
111
|
+
// The unit token is not a parameter word ("db" would rank retriggerDecayDb), so rank without it.
|
|
112
|
+
let kinds = rankKinds(unit ? String(text).replace(UNIT_STRIP, "$1 ") : text, index, opts.sel);
|
|
113
|
+
if (unit && kinds[0]?.unit !== unit) {
|
|
114
|
+
const head = kinds.slice(0, PARAMS_MAX_ENTRIES - fill.length);
|
|
115
|
+
kinds = [...head, ...fill.filter((kind) => !head.includes(kind))];
|
|
116
|
+
}
|
|
117
|
+
if (!kinds.length && opts.previous)
|
|
118
|
+
kinds = rankKinds(opts.previous, index, opts.sel);
|
|
119
|
+
const head = "[params] ";
|
|
120
|
+
const parts = [];
|
|
121
|
+
for (const kind of kinds) {
|
|
122
|
+
if ((head + [...parts, kind.text].join(" | ")).length > PARAMS_MAX_CHARS)
|
|
123
|
+
break;
|
|
124
|
+
parts.push(kind.text);
|
|
125
|
+
}
|
|
126
|
+
return head + (parts.length ? parts.join(" | ") : "none");
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=functiongemma-params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functiongemma-params.js","sourceRoot":"","sources":["../src/functiongemma-params.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* PAM FunctionGemma runner — drives a (fine-tuned) FunctionGemma model against
|
|
4
|
-
* the PAM MCP server using the model's native wire format (
|
|
4
|
+
* the PAM MCP server using the model's native wire format (functiongemma-format.ts),
|
|
5
5
|
* NOT the OpenAI chat+tools API: raw /completions + our own renderer/parser is
|
|
6
6
|
* deterministic and byte-matches training (agent.ts remains the big-model
|
|
7
7
|
* OpenAI-style baseline harness).
|
|
8
8
|
*
|
|
9
9
|
* Modes:
|
|
10
|
-
* REPL (default) npx tsx src/
|
|
11
|
-
* Offline eval ... --eval ../
|
|
12
|
-
* Live e2e ... --live ../
|
|
10
|
+
* REPL (default) npx tsx src/functiongemma-runner.ts [--url http://localhost:1234/v1] [--model id]
|
|
11
|
+
* Offline eval ... --eval ../ml-research/out/dev.jsonl --out ../ml-research/out/predictions.jsonl
|
|
12
|
+
* Live e2e ... --live ../ml-research/data/seeds/live_scenarios.jsonl [--gold]
|
|
13
13
|
*
|
|
14
14
|
* Flags: --toolpack <path> --bos text|none (default none; use text if the
|
|
15
15
|
* serving layer does NOT add BOS itself) --max-tokens N --final (generate a
|
|
16
16
|
* model NL summary after write-tool calls; read-tools always continue)
|
|
17
17
|
* --no-ctx (skip the live [ctx] session line).
|
|
18
|
+
* --grammar [--grammar-mode lazy|full] constrains calls to the toolpack's GBNF (functiongemma-grammar.ts);
|
|
19
|
+
* --probs [K] records P(first token = <start_function_call>) per eval row from a one-token probe;
|
|
20
|
+
* --token-probs streams the main request and records each generated token's [id, logprob, text].
|
|
18
21
|
*
|
|
19
22
|
* Session context (dataset v3): each command's user turn is prefixed with the
|
|
20
23
|
* [ctx] state line built live from the bridge (get_transport +
|
|
@@ -22,6 +25,6 @@
|
|
|
22
25
|
* additionally threads the last completed exchanges as history — the same
|
|
23
26
|
* shapes the in-plugin executor produces. Within one command the runner does
|
|
24
27
|
* up to MAX_ROUNDS call→response continuations inside the same model turn
|
|
25
|
-
* (the trained repair/
|
|
28
|
+
* (the trained repair/state_read pattern).
|
|
26
29
|
*/
|
|
27
30
|
export {};
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* PAM FunctionGemma runner — drives a (fine-tuned) FunctionGemma model against
|
|
4
|
-
* the PAM MCP server using the model's native wire format (
|
|
4
|
+
* the PAM MCP server using the model's native wire format (functiongemma-format.ts),
|
|
5
5
|
* NOT the OpenAI chat+tools API: raw /completions + our own renderer/parser is
|
|
6
6
|
* deterministic and byte-matches training (agent.ts remains the big-model
|
|
7
7
|
* OpenAI-style baseline harness).
|
|
8
8
|
*
|
|
9
9
|
* Modes:
|
|
10
|
-
* REPL (default) npx tsx src/
|
|
11
|
-
* Offline eval ... --eval ../
|
|
12
|
-
* Live e2e ... --live ../
|
|
10
|
+
* REPL (default) npx tsx src/functiongemma-runner.ts [--url http://localhost:1234/v1] [--model id]
|
|
11
|
+
* Offline eval ... --eval ../ml-research/out/dev.jsonl --out ../ml-research/out/predictions.jsonl
|
|
12
|
+
* Live e2e ... --live ../ml-research/data/seeds/live_scenarios.jsonl [--gold]
|
|
13
13
|
*
|
|
14
14
|
* Flags: --toolpack <path> --bos text|none (default none; use text if the
|
|
15
15
|
* serving layer does NOT add BOS itself) --max-tokens N --final (generate a
|
|
16
16
|
* model NL summary after write-tool calls; read-tools always continue)
|
|
17
17
|
* --no-ctx (skip the live [ctx] session line).
|
|
18
|
+
* --grammar [--grammar-mode lazy|full] constrains calls to the toolpack's GBNF (functiongemma-grammar.ts);
|
|
19
|
+
* --probs [K] records P(first token = <start_function_call>) per eval row from a one-token probe;
|
|
20
|
+
* --token-probs streams the main request and records each generated token's [id, logprob, text].
|
|
18
21
|
*
|
|
19
22
|
* Session context (dataset v3): each command's user turn is prefixed with the
|
|
20
23
|
* [ctx] state line built live from the bridge (get_transport +
|
|
@@ -22,7 +25,7 @@
|
|
|
22
25
|
* additionally threads the last completed exchanges as history — the same
|
|
23
26
|
* shapes the in-plugin executor produces. Within one command the runner does
|
|
24
27
|
* up to MAX_ROUNDS call→response continuations inside the same model turn
|
|
25
|
-
* (the trained repair/
|
|
28
|
+
* (the trained repair/state_read pattern).
|
|
26
29
|
*/
|
|
27
30
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
28
31
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
@@ -30,9 +33,10 @@ import { createInterface } from "node:readline";
|
|
|
30
33
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
31
34
|
import { resolve, dirname } from "node:path";
|
|
32
35
|
import { fileURLToPath } from "node:url";
|
|
33
|
-
import { STOP_SEQUENCES, buildGenerationPrompt, renderFunctionCall, renderFunctionResponse, parseFunctionCalls, truncateAtFabricatedResponse, withContext, } from "./
|
|
36
|
+
import { STOP_SEQUENCES, buildGenerationPrompt, renderFunctionCall, renderFunctionResponse, parseFunctionCalls, truncateAtFabricatedResponse, withContext, } from "./functiongemma-format.js";
|
|
37
|
+
import { CALL_TRIGGER, buildToolGrammar, lazyGrammarRequest } from "./functiongemma-grammar.js";
|
|
34
38
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
35
|
-
const DEFAULT_TOOLPACK = resolve(__dirname, "../../
|
|
39
|
+
const DEFAULT_TOOLPACK = resolve(__dirname, "../../ml-research/out/toolpack.json");
|
|
36
40
|
const MAX_ROUNDS = 3;
|
|
37
41
|
const RESULT_TRUNC = 400; // chars of tool-result JSON fed back as function response
|
|
38
42
|
function parseArgs() {
|
|
@@ -53,6 +57,9 @@ function parseArgs() {
|
|
|
53
57
|
outPath: get("--out"),
|
|
54
58
|
livePath: get("--live"),
|
|
55
59
|
gold: a.includes("--gold"),
|
|
60
|
+
grammar: a.includes("--grammar") ? (get("--grammar-mode") || "lazy") : null,
|
|
61
|
+
probs: a.includes("--probs") ? Number(/^\d+$/.test(get("--probs") ?? "") ? get("--probs") : 20) : 0,
|
|
62
|
+
tokenProbs: a.includes("--token-probs"),
|
|
56
63
|
};
|
|
57
64
|
}
|
|
58
65
|
const config = parseArgs();
|
|
@@ -73,8 +80,10 @@ function resolveAlias(call, pack) {
|
|
|
73
80
|
}
|
|
74
81
|
const READ_TOOL_RE = /^(get_|list_|connection_status)/;
|
|
75
82
|
// --- generation ----------------------------------------------------------
|
|
83
|
+
let grammarFields = {};
|
|
76
84
|
async function complete(prompt) {
|
|
77
85
|
const t0 = Date.now();
|
|
86
|
+
const stream = config.tokenProbs;
|
|
78
87
|
const resp = await fetch(`${config.url}/completions`, {
|
|
79
88
|
method: "POST",
|
|
80
89
|
headers: { "Content-Type": "application/json" },
|
|
@@ -84,13 +93,58 @@ async function complete(prompt) {
|
|
|
84
93
|
max_tokens: config.maxTokens,
|
|
85
94
|
temperature: 0,
|
|
86
95
|
stop: STOP_SEQUENCES,
|
|
87
|
-
stream
|
|
96
|
+
stream,
|
|
97
|
+
...(stream ? { n_probs: 1 } : {}),
|
|
98
|
+
...grammarFields,
|
|
88
99
|
}),
|
|
89
100
|
});
|
|
101
|
+
if (!resp.ok)
|
|
102
|
+
throw new Error(`LLM API error ${resp.status}: ${await resp.text()}`);
|
|
103
|
+
if (!stream) {
|
|
104
|
+
const data = (await resp.json());
|
|
105
|
+
return { text: data.choices[0].text, ms: Date.now() - t0 };
|
|
106
|
+
}
|
|
107
|
+
// Streamed chunks carry every token's probability; the final non-streamed response trims them by the stop word.
|
|
108
|
+
let text = "";
|
|
109
|
+
let buffer = "";
|
|
110
|
+
const tokens = [];
|
|
111
|
+
const decoder = new TextDecoder();
|
|
112
|
+
for await (const chunk of resp.body) {
|
|
113
|
+
buffer += decoder.decode(chunk, { stream: true });
|
|
114
|
+
for (let nl = buffer.indexOf("\n"); nl >= 0; nl = buffer.indexOf("\n")) {
|
|
115
|
+
const line = buffer.slice(0, nl).trim();
|
|
116
|
+
buffer = buffer.slice(nl + 1);
|
|
117
|
+
if (!line.startsWith("data:") || line.endsWith("[DONE]"))
|
|
118
|
+
continue;
|
|
119
|
+
const choice = JSON.parse(line.slice(5)).choices?.[0];
|
|
120
|
+
text += choice?.text ?? "";
|
|
121
|
+
for (const t of choice?.logprobs?.content ?? []) {
|
|
122
|
+
tokens.push([t.id, Math.round(t.logprob * 1e4) / 1e4, t.top_logprobs?.[0]?.id === t.id ? t.top_logprobs[0].token : t.token]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { text, ms: Date.now() - t0, tokens };
|
|
127
|
+
}
|
|
128
|
+
/** The unconstrained first-token distribution; a separate request because llama-server trims
|
|
129
|
+
* final-response probs by the stop word's text tokenization, which can eat a short call's first token. */
|
|
130
|
+
async function probeFirstToken(prompt) {
|
|
131
|
+
const t0 = Date.now();
|
|
132
|
+
const resp = await fetch(`${config.url}/completions`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: { "Content-Type": "application/json" },
|
|
135
|
+
body: JSON.stringify({ model: config.model, prompt, max_tokens: 1, temperature: 0, n_probs: config.probs, stream: false }),
|
|
136
|
+
});
|
|
90
137
|
if (!resp.ok)
|
|
91
138
|
throw new Error(`LLM API error ${resp.status}: ${await resp.text()}`);
|
|
92
139
|
const data = (await resp.json());
|
|
93
|
-
|
|
140
|
+
const top = (data.choices[0].logprobs?.content?.[0]?.top_logprobs ?? []).map((t) => ({
|
|
141
|
+
token: t.token,
|
|
142
|
+
p: Math.exp(t.logprob),
|
|
143
|
+
}));
|
|
144
|
+
if (top.length === 0)
|
|
145
|
+
throw new Error("probe returned no top_logprobs (server too old, or n_probs ignored)");
|
|
146
|
+
const call = top.find((t) => t.token === CALL_TRIGGER);
|
|
147
|
+
return { p_call: call?.p ?? 0, top: top.slice(0, 5), probe_ms: Date.now() - t0 };
|
|
94
148
|
}
|
|
95
149
|
// --- MCP -----------------------------------------------------------------
|
|
96
150
|
async function createMcpClient() {
|
|
@@ -99,7 +153,7 @@ async function createMcpClient() {
|
|
|
99
153
|
args: ["tsx", resolve(__dirname, "server.ts")],
|
|
100
154
|
stderr: "inherit",
|
|
101
155
|
});
|
|
102
|
-
const client = new Client({ name: "pam-
|
|
156
|
+
const client = new Client({ name: "pam-functiongemma-runner", version: "1.0.0" });
|
|
103
157
|
await client.connect(transport);
|
|
104
158
|
return client;
|
|
105
159
|
}
|
|
@@ -191,7 +245,7 @@ async function runCommandExec(userText, tools, client, log, opts = {}) {
|
|
|
191
245
|
const { text: rawFull, ms } = await complete(prompt);
|
|
192
246
|
const raw = truncateAtFabricatedResponse(rawFull);
|
|
193
247
|
if (raw !== rawFull) {
|
|
194
|
-
trace.
|
|
248
|
+
trace.droppedHistory = true;
|
|
195
249
|
log(" (dropped fabricated function-response continuation)");
|
|
196
250
|
}
|
|
197
251
|
const calls = parseFunctionCalls(raw);
|
|
@@ -203,7 +257,7 @@ async function runCommandExec(userText, tools, client, log, opts = {}) {
|
|
|
203
257
|
}
|
|
204
258
|
const unknown = calls.filter((c) => !declared.has(c.name));
|
|
205
259
|
if (unknown.length) {
|
|
206
|
-
trace.
|
|
260
|
+
trace.droppedHistory = true;
|
|
207
261
|
log(` refusing undeclared tool(s): ${unknown.map((c) => c.name).join(", ")}`);
|
|
208
262
|
return trace;
|
|
209
263
|
}
|
|
@@ -213,7 +267,7 @@ async function runCommandExec(userText, tools, client, log, opts = {}) {
|
|
|
213
267
|
for (const call of calls) {
|
|
214
268
|
const signature = `${call.name} ${JSON.stringify(call.arguments)}`;
|
|
215
269
|
if (failedCalls.has(signature)) {
|
|
216
|
-
trace.
|
|
270
|
+
trace.droppedHistory = true;
|
|
217
271
|
log(` stopped — the model repeated a call that already failed (${call.name}).`);
|
|
218
272
|
return trace;
|
|
219
273
|
}
|
|
@@ -221,7 +275,7 @@ async function runCommandExec(userText, tools, client, log, opts = {}) {
|
|
|
221
275
|
const { text, isError } = await execCall(client, call, tools);
|
|
222
276
|
if (isError) {
|
|
223
277
|
failedCalls.add(signature);
|
|
224
|
-
trace.
|
|
278
|
+
trace.droppedHistory = true;
|
|
225
279
|
}
|
|
226
280
|
trace.executed.push({ call, resultText: text, isError });
|
|
227
281
|
log(` → ${text.length > 200 ? text.slice(0, 200) + "…" : text || "(ok)"}`);
|
|
@@ -307,7 +361,7 @@ async function runEval(tools) {
|
|
|
307
361
|
const utterance = String(user?.content ?? "");
|
|
308
362
|
const gold = firstAssistant?.tool_calls
|
|
309
363
|
? firstAssistant.tool_calls.map((tc) => ({ name: tc.function.name, arguments: tc.function.arguments }))
|
|
310
|
-
: null; // null =
|
|
364
|
+
: null; // null = an irrelevance row: no call expected
|
|
311
365
|
// Protocol: always generate against the FULL toolpack (deployment prompt),
|
|
312
366
|
// regardless of the subset recorded in the row.
|
|
313
367
|
const prompt = buildGenerationPrompt(tools, utterance, {
|
|
@@ -316,25 +370,33 @@ async function runEval(tools) {
|
|
|
316
370
|
});
|
|
317
371
|
let raw = "";
|
|
318
372
|
let ms = -1;
|
|
373
|
+
let probs = {};
|
|
374
|
+
let tokenLp = {};
|
|
319
375
|
try {
|
|
320
376
|
const r = await complete(prompt);
|
|
321
377
|
raw = r.text;
|
|
322
378
|
ms = r.ms;
|
|
323
379
|
latencies.push(ms);
|
|
380
|
+
if (r.tokens)
|
|
381
|
+
tokenLp = { token_lp: r.tokens };
|
|
382
|
+
if (config.probs > 0)
|
|
383
|
+
probs = await probeFirstToken(prompt);
|
|
324
384
|
}
|
|
325
385
|
catch (e) {
|
|
326
386
|
raw = `__GENERATION_ERROR__ ${e.message}`;
|
|
327
387
|
}
|
|
328
388
|
const calls = parseFunctionCalls(raw);
|
|
329
|
-
out.push(JSON.stringify({ idx: i, meta: row._meta, utterance, gold, raw, calls, ms }));
|
|
389
|
+
out.push(JSON.stringify({ idx: i, meta: row._meta, utterance, gold, raw, calls, ms, ...probs, ...tokenLp }));
|
|
330
390
|
if ((i + 1) % 25 === 0)
|
|
331
391
|
console.error(`eval ${i + 1}/${rows.length}`);
|
|
332
392
|
}
|
|
333
393
|
writeFileSync(outPath, out.join("\n") + "\n");
|
|
334
394
|
latencies.sort((a, b) => a - b);
|
|
335
395
|
const p = (q) => latencies[Math.min(latencies.length - 1, Math.floor(q * latencies.length))] ?? -1;
|
|
336
|
-
|
|
337
|
-
console.log(
|
|
396
|
+
const total = latencies.reduce((sum, ms) => sum + ms, 0);
|
|
397
|
+
console.log(`wrote ${out.length} predictions -> ${outPath}\nlatency ms p50=${p(0.5)} p95=${p(0.95)} total=${total} (n=${latencies.length})` +
|
|
398
|
+
(config.grammar ? ` grammar=${config.grammar}` : ""));
|
|
399
|
+
console.log("score with: uv run --project packages/ml-research pam-ml scoring calls " + outPath);
|
|
338
400
|
}
|
|
339
401
|
function callMatches(call, tool, argsSubset) {
|
|
340
402
|
if (call.name !== tool)
|
|
@@ -378,7 +440,7 @@ async function runLive(tools) {
|
|
|
378
440
|
let this_ok = false;
|
|
379
441
|
let detail = "";
|
|
380
442
|
const allCalls = trace.rounds.flatMap((r) => r.calls);
|
|
381
|
-
if (ex.kind === "
|
|
443
|
+
if (ex.kind === "irrelevance") {
|
|
382
444
|
this_ok = allCalls.length === 0;
|
|
383
445
|
detail = this_ok ? "" : `emitted ${allCalls.map((c) => c.name).join(",")}`;
|
|
384
446
|
}
|
|
@@ -453,7 +515,7 @@ async function runRepl(tools) {
|
|
|
453
515
|
history: history.slice(-HISTORY_MAX_EXCHANGES),
|
|
454
516
|
failedCalls,
|
|
455
517
|
});
|
|
456
|
-
if (!trace.
|
|
518
|
+
if (!trace.droppedHistory && trace.modelTurn && trace.modelTurn.length <= HISTORY_TURN_MAX_CHARS) {
|
|
457
519
|
history.push({ user: input, model: trace.modelTurn });
|
|
458
520
|
}
|
|
459
521
|
if (trace.finalText)
|
|
@@ -478,6 +540,10 @@ async function runRepl(tools) {
|
|
|
478
540
|
}
|
|
479
541
|
async function main() {
|
|
480
542
|
const tools = loadToolpack();
|
|
543
|
+
if (config.grammar) {
|
|
544
|
+
const grammar = buildToolGrammar(tools, { mode: config.grammar });
|
|
545
|
+
grammarFields = config.grammar === "lazy" ? lazyGrammarRequest(grammar) : { grammar };
|
|
546
|
+
}
|
|
481
547
|
if (config.evalPath)
|
|
482
548
|
return runEval(tools);
|
|
483
549
|
if (config.livePath)
|
|
@@ -488,4 +554,4 @@ main().catch((e) => {
|
|
|
488
554
|
console.error("Fatal:", e.message);
|
|
489
555
|
process.exit(1);
|
|
490
556
|
});
|
|
491
|
-
//# sourceMappingURL=
|
|
557
|
+
//# sourceMappingURL=functiongemma-runner.js.map
|