@hmharness/evolution 0.14.0 → 0.14.4
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/bench.d.ts +6 -0
- package/dist/bench.js +16 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/skillpayload.d.ts +1 -0
- package/dist/skillpayload.js +28 -0
- package/package.json +1 -1
package/dist/bench.d.ts
CHANGED
|
@@ -24,6 +24,12 @@ export interface BenchResult {
|
|
|
24
24
|
detail: string;
|
|
25
25
|
}
|
|
26
26
|
export declare function matchExpect(output: string, expect: string[]): boolean;
|
|
27
|
+
/** Fence convention: when the reply is a fenced block, assertions test the
|
|
28
|
+
* fence INNER content (day-55 finding: models preserve literals verbatim
|
|
29
|
+
* inside code fences while normalizing them in prose - the fence is the
|
|
30
|
+
* reply convention that makes exactness attainable for habit-prone models).
|
|
31
|
+
* Tolerates a trailing space after the opening fence markers. */
|
|
32
|
+
export declare function fenceInner(output: string): string;
|
|
27
33
|
/** Full structured assertion: every declared mode must hold. */
|
|
28
34
|
export declare function matchCase(output: string, c: Pick<BenchCase, 'expect' | 'expectExact' | 'expectRegex' | 'expectNone' | 'expectAny'>): {
|
|
29
35
|
pass: boolean;
|
package/dist/bench.js
CHANGED
|
@@ -24,27 +24,37 @@ export function matchExpect(output, expect) {
|
|
|
24
24
|
const lower = output.toLowerCase();
|
|
25
25
|
return expect.every((e) => lower.includes(e.toLowerCase()));
|
|
26
26
|
}
|
|
27
|
+
/** Fence convention: when the reply is a fenced block, assertions test the
|
|
28
|
+
* fence INNER content (day-55 finding: models preserve literals verbatim
|
|
29
|
+
* inside code fences while normalizing them in prose - the fence is the
|
|
30
|
+
* reply convention that makes exactness attainable for habit-prone models).
|
|
31
|
+
* Tolerates a trailing space after the opening fence markers. */
|
|
32
|
+
export function fenceInner(output) {
|
|
33
|
+
const m = output.match(/```[a-zA-Z]*[ \t]*\r?\n([\s\S]*?)(?:\r?\n)?```/);
|
|
34
|
+
return m ? m[1] : output;
|
|
35
|
+
}
|
|
27
36
|
/** Full structured assertion: every declared mode must hold. */
|
|
28
37
|
export function matchCase(output, c) {
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
const body = fenceInner(output);
|
|
39
|
+
if (c.expectExact !== undefined && body.trim() !== c.expectExact.trim()) {
|
|
40
|
+
return { pass: false, detail: `exact mismatch: got "${body.trim().slice(0, 80)}"` };
|
|
31
41
|
}
|
|
32
42
|
if (c.expectRegex !== undefined) {
|
|
33
43
|
try {
|
|
34
|
-
if (!new RegExp(c.expectRegex).test(
|
|
44
|
+
if (!new RegExp(c.expectRegex).test(body))
|
|
35
45
|
return { pass: false, detail: `regex mismatch: /${c.expectRegex.slice(0, 60)}/` };
|
|
36
46
|
}
|
|
37
47
|
catch {
|
|
38
48
|
return { pass: false, detail: `invalid regex in case: ${c.expectRegex.slice(0, 40)}` };
|
|
39
49
|
}
|
|
40
50
|
}
|
|
41
|
-
if (c.expectNone && c.expectNone.some((e) =>
|
|
51
|
+
if (c.expectNone && c.expectNone.some((e) => body.toLowerCase().includes(e.toLowerCase()))) {
|
|
42
52
|
return { pass: false, detail: `forbidden marker present: ${c.expectNone.join(' && ')}` };
|
|
43
53
|
}
|
|
44
|
-
if (c.expectAny && !c.expectAny.some((e) =>
|
|
54
|
+
if (c.expectAny && !c.expectAny.some((e) => body.toLowerCase().includes(e.toLowerCase()))) {
|
|
45
55
|
return { pass: false, detail: `none of the allowed markers found: ${c.expectAny.join(' || ')}` };
|
|
46
56
|
}
|
|
47
|
-
if (!matchExpect(
|
|
57
|
+
if (!matchExpect(body, c.expect)) {
|
|
48
58
|
return { pass: false, detail: `missing "${c.expect.join('" && "')}" in output` };
|
|
49
59
|
}
|
|
50
60
|
return { pass: true, detail: 'ok' };
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function loadSkillPayload(home: string, payload: string): Promise<string>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a treatment-arm skills prompt for a skill-target candidate: the
|
|
3
|
+
* payload names the skill; the arm must inject the skill's CONTENT (draft
|
|
4
|
+
* first, promoted second), never the bare name string. (Day-49 SELFFEED:
|
|
5
|
+
* the first real experiment injected "+34 tokens" of name - it measured the
|
|
6
|
+
* instrument, not the skill.)
|
|
7
|
+
*/
|
|
8
|
+
import { readFile } from 'node:fs/promises';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
export async function loadSkillPayload(home, payload) {
|
|
11
|
+
const name = payload.trim();
|
|
12
|
+
if (!name)
|
|
13
|
+
return '';
|
|
14
|
+
const candidates = [
|
|
15
|
+
join(home, 'skills', 'drafts', `${name}.md`),
|
|
16
|
+
join(home, 'skills', `${name}.md`),
|
|
17
|
+
];
|
|
18
|
+
for (const f of candidates) {
|
|
19
|
+
try {
|
|
20
|
+
const md = await readFile(f, 'utf8');
|
|
21
|
+
if (md.trim())
|
|
22
|
+
return md.trim().slice(0, 4000);
|
|
23
|
+
}
|
|
24
|
+
catch { /* next */ }
|
|
25
|
+
}
|
|
26
|
+
// no file found: fall back to the raw string so the arm still runs
|
|
27
|
+
return name;
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hmharness/evolution",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.4",
|
|
4
4
|
"description": "hmharness evolution subsystem: persistent memory, insight capture, skill library, and the bench that gives evolution its fitness signal. First-class kernel citizen, not a plugin.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|