@namzu/sdk 62.12.0 → 62.14.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/CHANGELOG.md +31 -0
- package/dist/agents/file-definitions.d.ts +7 -0
- package/dist/agents/file-definitions.d.ts.map +1 -1
- package/dist/agents/file-definitions.js +20 -0
- package/dist/agents/file-definitions.js.map +1 -1
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +1 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/bridge/acp/server.d.ts +8 -1
- package/dist/bridge/acp/server.d.ts.map +1 -1
- package/dist/bridge/acp/server.js +12 -0
- package/dist/bridge/acp/server.js.map +1 -1
- package/dist/connector/index.d.ts +1 -1
- package/dist/connector/index.d.ts.map +1 -1
- package/dist/connector/index.js +1 -1
- package/dist/connector/index.js.map +1 -1
- package/dist/connector/mcp/client.d.ts +96 -0
- package/dist/connector/mcp/client.d.ts.map +1 -1
- package/dist/connector/mcp/client.js +488 -13
- package/dist/connector/mcp/client.js.map +1 -1
- package/dist/connector/mcp/index.d.ts +1 -0
- package/dist/connector/mcp/index.d.ts.map +1 -1
- package/dist/connector/mcp/index.js +1 -0
- package/dist/connector/mcp/index.js.map +1 -1
- package/dist/connector/mcp/tasks.d.ts +40 -0
- package/dist/connector/mcp/tasks.d.ts.map +1 -0
- package/dist/connector/mcp/tasks.js +55 -0
- package/dist/connector/mcp/tasks.js.map +1 -0
- package/dist/constants/data-epoch.d.ts +18 -0
- package/dist/constants/data-epoch.d.ts.map +1 -0
- package/dist/constants/data-epoch.js +18 -0
- package/dist/constants/data-epoch.js.map +1 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +1 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/constants/mcp/index.d.ts +1 -1
- package/dist/constants/mcp/index.d.ts.map +1 -1
- package/dist/constants/mcp/index.js +5 -0
- package/dist/constants/mcp/index.js.map +1 -1
- package/dist/constants/telemetry/index.d.ts +12 -0
- package/dist/constants/telemetry/index.d.ts.map +1 -1
- package/dist/constants/telemetry/index.js +12 -0
- package/dist/constants/telemetry/index.js.map +1 -1
- package/dist/eval/bootstrap.d.ts +122 -0
- package/dist/eval/bootstrap.d.ts.map +1 -0
- package/dist/eval/bootstrap.js +227 -0
- package/dist/eval/bootstrap.js.map +1 -0
- package/dist/eval/compare.d.ts +109 -0
- package/dist/eval/compare.d.ts.map +1 -0
- package/dist/eval/compare.js +324 -0
- package/dist/eval/compare.js.map +1 -0
- package/dist/eval/disclosure.d.ts +70 -0
- package/dist/eval/disclosure.d.ts.map +1 -0
- package/dist/eval/disclosure.js +64 -0
- package/dist/eval/disclosure.js.map +1 -0
- package/dist/eval/experiment.d.ts +23 -0
- package/dist/eval/experiment.d.ts.map +1 -1
- package/dist/eval/experiment.js +87 -15
- package/dist/eval/experiment.js.map +1 -1
- package/dist/eval/from-turn.d.ts.map +1 -1
- package/dist/eval/from-turn.js +5 -0
- package/dist/eval/from-turn.js.map +1 -1
- package/dist/eval/index.d.ts +13 -2
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js +6 -1
- package/dist/eval/index.js.map +1 -1
- package/dist/eval/report-stats.d.ts +77 -0
- package/dist/eval/report-stats.d.ts.map +1 -0
- package/dist/eval/report-stats.js +184 -0
- package/dist/eval/report-stats.js.map +1 -0
- package/dist/eval/run-options.d.ts +30 -0
- package/dist/eval/run-options.d.ts.map +1 -0
- package/dist/eval/run-options.js +20 -0
- package/dist/eval/run-options.js.map +1 -0
- package/dist/eval/run-summary.d.ts +36 -0
- package/dist/eval/run-summary.d.ts.map +1 -0
- package/dist/eval/run-summary.js +57 -0
- package/dist/eval/run-summary.js.map +1 -0
- package/dist/eval/scorers.d.ts +32 -0
- package/dist/eval/scorers.d.ts.map +1 -1
- package/dist/eval/scorers.js +77 -0
- package/dist/eval/scorers.js.map +1 -1
- package/dist/eval/types.d.ts +74 -0
- package/dist/eval/types.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts +3 -0
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +18 -2
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -1
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/loader.d.ts +11 -0
- package/dist/plugin/loader.d.ts.map +1 -1
- package/dist/plugin/loader.js +15 -2
- package/dist/plugin/loader.js.map +1 -1
- package/dist/public-runtime.d.ts +10 -6
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +13 -5
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +2 -0
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/command/kernel-commands.d.ts +3 -0
- package/dist/registry/command/kernel-commands.d.ts.map +1 -1
- package/dist/registry/command/kernel-commands.js +76 -5
- package/dist/registry/command/kernel-commands.js.map +1 -1
- package/dist/runtime/query/cancelled-before-start.d.ts.map +1 -1
- package/dist/runtime/query/cancelled-before-start.js +2 -0
- package/dist/runtime/query/cancelled-before-start.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +17 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +18 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +80 -1
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +18 -1
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +5 -0
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/result.d.ts.map +1 -1
- package/dist/runtime/query/result.js +2 -0
- package/dist/runtime/query/result.js.map +1 -1
- package/dist/runtime/query/turn/answer-claims.d.ts +52 -0
- package/dist/runtime/query/turn/answer-claims.d.ts.map +1 -0
- package/dist/runtime/query/turn/answer-claims.js +348 -0
- package/dist/runtime/query/turn/answer-claims.js.map +1 -0
- package/dist/runtime/query/turn/outcome-ledger.d.ts +7 -0
- package/dist/runtime/query/turn/outcome-ledger.d.ts.map +1 -1
- package/dist/runtime/query/turn/outcome-ledger.js +13 -0
- package/dist/runtime/query/turn/outcome-ledger.js.map +1 -1
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/loader.d.ts +15 -1
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +17 -3
- package/dist/skills/loader.js.map +1 -1
- package/dist/store/goal/index.d.ts +3 -1
- package/dist/store/goal/index.d.ts.map +1 -1
- package/dist/store/goal/index.js +6 -0
- package/dist/store/goal/index.js.map +1 -1
- package/dist/telemetry/genai.d.ts +98 -0
- package/dist/telemetry/genai.d.ts.map +1 -0
- package/dist/telemetry/genai.js +189 -0
- package/dist/telemetry/genai.js.map +1 -0
- package/dist/telemetry/runtime-accessors.d.ts +19 -0
- package/dist/telemetry/runtime-accessors.d.ts.map +1 -1
- package/dist/telemetry/runtime-accessors.js +43 -1
- package/dist/telemetry/runtime-accessors.js.map +1 -1
- package/dist/tools/goal/confirmation.d.ts +154 -0
- package/dist/tools/goal/confirmation.d.ts.map +1 -0
- package/dist/tools/goal/confirmation.js +290 -0
- package/dist/tools/goal/confirmation.js.map +1 -0
- package/dist/tools/goal/index.d.ts +4 -1
- package/dist/tools/goal/index.d.ts.map +1 -1
- package/dist/tools/goal/index.js +27 -2
- package/dist/tools/goal/index.js.map +1 -1
- package/dist/tools/hand-back/index.d.ts +48 -0
- package/dist/tools/hand-back/index.d.ts.map +1 -0
- package/dist/tools/hand-back/index.js +129 -0
- package/dist/tools/hand-back/index.js.map +1 -0
- package/dist/tools/schedules/schedule-tool.d.ts.map +1 -1
- package/dist/tools/schedules/schedule-tool.js +15 -1
- package/dist/tools/schedules/schedule-tool.js.map +1 -1
- package/dist/tools/schedules/types.d.ts +10 -0
- package/dist/tools/schedules/types.d.ts.map +1 -1
- package/dist/toolsets/manager.d.ts.map +1 -1
- package/dist/toolsets/manager.js +12 -0
- package/dist/toolsets/manager.js.map +1 -1
- package/dist/types/acp/index.d.ts +18 -0
- package/dist/types/acp/index.d.ts.map +1 -1
- package/dist/types/connector/mcp.d.ts +18 -0
- package/dist/types/connector/mcp.d.ts.map +1 -1
- package/dist/types/goal/index.d.ts +12 -0
- package/dist/types/goal/index.d.ts.map +1 -1
- package/dist/types/session/config.d.ts +8 -0
- package/dist/types/session/config.d.ts.map +1 -1
- package/dist/types/session/hand-back.d.ts +29 -0
- package/dist/types/session/hand-back.d.ts.map +1 -0
- package/dist/types/session/hand-back.js +11 -0
- package/dist/types/session/hand-back.js.map +1 -0
- package/dist/types/session/outcome.d.ts +37 -0
- package/dist/types/session/outcome.d.ts.map +1 -1
- package/dist/types/session/outcome.js.map +1 -1
- package/dist/types/session/turn.d.ts +19 -1
- package/dist/types/session/turn.d.ts.map +1 -1
- package/dist/types/session/turn.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/file-definitions.ts +21 -0
- package/src/agents/index.ts +1 -0
- package/src/bridge/acp/server.ts +20 -0
- package/src/connector/index.ts +1 -0
- package/src/connector/mcp/client.ts +531 -14
- package/src/connector/mcp/index.ts +1 -0
- package/src/connector/mcp/tasks.ts +81 -0
- package/src/constants/data-epoch.ts +17 -0
- package/src/constants/index.ts +1 -0
- package/src/constants/mcp/index.ts +6 -1
- package/src/constants/telemetry/index.ts +13 -0
- package/src/eval/bootstrap.ts +314 -0
- package/src/eval/compare.ts +473 -0
- package/src/eval/disclosure.ts +136 -0
- package/src/eval/experiment.ts +127 -15
- package/src/eval/from-turn.ts +5 -0
- package/src/eval/index.ts +51 -0
- package/src/eval/report-stats.ts +257 -0
- package/src/eval/run-options.ts +49 -0
- package/src/eval/run-summary.ts +104 -0
- package/src/eval/scorers.ts +83 -0
- package/src/eval/types.ts +76 -0
- package/src/manager/session/turn-recorder.ts +23 -2
- package/src/plugin/index.ts +7 -1
- package/src/plugin/loader.ts +16 -2
- package/src/public-runtime.ts +70 -0
- package/src/public-types.ts +9 -0
- package/src/registry/command/kernel-commands.ts +94 -6
- package/src/runtime/query/cancelled-before-start.ts +2 -0
- package/src/runtime/query/index.ts +20 -0
- package/src/runtime/query/iteration/index.ts +85 -1
- package/src/runtime/query/iteration/phases/tool-review.ts +24 -1
- package/src/runtime/query/iteration/stream-turn.ts +10 -0
- package/src/runtime/query/result.ts +2 -0
- package/src/runtime/query/turn/answer-claims.ts +413 -0
- package/src/runtime/query/turn/outcome-ledger.ts +12 -0
- package/src/skills/index.ts +1 -0
- package/src/skills/loader.ts +21 -3
- package/src/store/goal/index.ts +11 -0
- package/src/telemetry/genai.ts +202 -0
- package/src/telemetry/runtime-accessors.ts +40 -1
- package/src/tools/goal/confirmation.ts +375 -0
- package/src/tools/goal/index.ts +37 -1
- package/src/tools/hand-back/index.ts +150 -0
- package/src/tools/schedules/schedule-tool.ts +19 -1
- package/src/tools/schedules/types.ts +10 -0
- package/src/toolsets/manager.ts +22 -0
- package/src/types/acp/index.ts +20 -0
- package/src/types/connector/mcp.ts +18 -0
- package/src/types/goal/index.ts +13 -0
- package/src/types/session/config.ts +8 -0
- package/src/types/session/hand-back.ts +31 -0
- package/src/types/session/outcome.ts +42 -0
- package/src/types/session/turn.ts +19 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { UNKNOWN } from './disclosure.js'
|
|
2
|
+
import type { RunMode } from './disclosure.js'
|
|
3
|
+
import {
|
|
4
|
+
type RunStats,
|
|
5
|
+
describeIntervals,
|
|
6
|
+
describeSplits,
|
|
7
|
+
groupRuns,
|
|
8
|
+
statsOver,
|
|
9
|
+
} from './report-stats.js'
|
|
10
|
+
import type { ExperimentReport } from './types.js'
|
|
11
|
+
|
|
12
|
+
/** What produced a whole run, across every suite in it. */
|
|
13
|
+
export interface RunDisclosure {
|
|
14
|
+
readonly harnessVersion: string
|
|
15
|
+
readonly sdkVersion: string
|
|
16
|
+
readonly generatedAt: string
|
|
17
|
+
readonly commit: string
|
|
18
|
+
readonly seed: number
|
|
19
|
+
/** Repeats per case; the largest across suites when they differ. */
|
|
20
|
+
readonly repeats: number
|
|
21
|
+
readonly suites: number
|
|
22
|
+
readonly cases: number
|
|
23
|
+
readonly runs: number
|
|
24
|
+
/** `mixed` when suites that used a model differ in kind; a suite with no model at all does not count. */
|
|
25
|
+
readonly mode: RunMode | 'mixed'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The numbers for every case of every suite taken together. */
|
|
29
|
+
export interface RunSummary extends Omit<RunStats, 'caseSummaries' | 'reliability'> {
|
|
30
|
+
readonly disclosure: RunDisclosure
|
|
31
|
+
/** Present only when cases were repeated. */
|
|
32
|
+
readonly reliability?: RunStats['reliability']
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function summarizeRun(
|
|
36
|
+
entries: ReadonlyArray<{ suite: string; report: ExperimentReport }>,
|
|
37
|
+
context: {
|
|
38
|
+
seed: number
|
|
39
|
+
harnessVersion: string
|
|
40
|
+
commit: string
|
|
41
|
+
generatedAt: string
|
|
42
|
+
sdkVersion: string
|
|
43
|
+
},
|
|
44
|
+
): RunSummary {
|
|
45
|
+
// A case is named by its suite and its id: two suites may reuse a name.
|
|
46
|
+
const cases = entries.flatMap(({ suite, report }) =>
|
|
47
|
+
groupRuns(report.cases ?? [], (name) => `${suite}\u0000${name}`),
|
|
48
|
+
)
|
|
49
|
+
const { caseSummaries: _perCase, reliability, ...stats } = statsOver(cases, context.seed)
|
|
50
|
+
const repeats = Math.max(1, ...entries.map((e) => e.report.repeats ?? 1))
|
|
51
|
+
// A suite that used no model at all says nothing about whether a model
|
|
52
|
+
// ran, so it does not make a run "mixed" with the suites that did.
|
|
53
|
+
const all = entries.map((e) => e.report.disclosure?.mode ?? UNKNOWN)
|
|
54
|
+
const modes = new Set(all.filter((m) => m !== 'no-model'))
|
|
55
|
+
const mode: RunMode | 'mixed' =
|
|
56
|
+
modes.size === 0
|
|
57
|
+
? all.length === 0
|
|
58
|
+
? UNKNOWN
|
|
59
|
+
: 'no-model'
|
|
60
|
+
: modes.size === 1
|
|
61
|
+
? ([...modes][0] as RunMode)
|
|
62
|
+
: 'mixed'
|
|
63
|
+
return {
|
|
64
|
+
...stats,
|
|
65
|
+
...(repeats > 1 ? { reliability } : {}),
|
|
66
|
+
disclosure: {
|
|
67
|
+
harnessVersion: context.harnessVersion,
|
|
68
|
+
sdkVersion: context.sdkVersion,
|
|
69
|
+
generatedAt: context.generatedAt,
|
|
70
|
+
commit: context.commit,
|
|
71
|
+
seed: context.seed,
|
|
72
|
+
repeats,
|
|
73
|
+
suites: entries.length,
|
|
74
|
+
cases: stats.cases,
|
|
75
|
+
runs: stats.runs,
|
|
76
|
+
mode,
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function formatRunSummary(summary: RunSummary): string {
|
|
82
|
+
const d = summary.disclosure
|
|
83
|
+
const lines = [
|
|
84
|
+
`Whole run: ${summary.passed}/${summary.runs} runs passed across ${d.suites} suite${d.suites === 1 ? '' : 's'}, ${summary.cases} case${summary.cases === 1 ? '' : 's'}${d.repeats > 1 ? ` x ${d.repeats} repeats` : ''}`,
|
|
85
|
+
]
|
|
86
|
+
for (const line of describeIntervals({
|
|
87
|
+
mean: summary.mean,
|
|
88
|
+
passRate: summary.passRate,
|
|
89
|
+
intervals: summary.intervals,
|
|
90
|
+
})) {
|
|
91
|
+
lines.push(` ${line}`)
|
|
92
|
+
}
|
|
93
|
+
if (summary.reliability) {
|
|
94
|
+
const r = summary.reliability
|
|
95
|
+
lines.push(
|
|
96
|
+
` reliability across repeats: ${r.passedEveryRepeat} of ${r.cases} cases passed in every one of ${d.repeats} repeats${r.fraction === null ? '' : ` (${(r.fraction * 100).toFixed(1)}%)`}`,
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
for (const line of describeSplits(summary.splits)) lines.push(` ${line}`)
|
|
100
|
+
lines.push(
|
|
101
|
+
` produced by: namzu eval ${d.harnessVersion}, sdk ${d.sdkVersion}, commit ${d.commit}, ${d.generatedAt}, ${d.mode}`,
|
|
102
|
+
)
|
|
103
|
+
return lines.join('\n')
|
|
104
|
+
}
|
package/src/eval/scorers.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { HandBackKind } from '../types/session/hand-back.js'
|
|
2
|
+
import type { TurnOutcomeVerdict } from '../types/session/outcome.js'
|
|
1
3
|
import type { EvalCase, EvalTurn, Score, Scorer } from './types.js'
|
|
2
4
|
|
|
3
5
|
/**
|
|
@@ -152,6 +154,87 @@ export function containsScorer(...required: string[]): Scorer {
|
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
/**
|
|
158
|
+
* The turn's outcome record has one of the given verdicts.
|
|
159
|
+
*
|
|
160
|
+
* Reads the record the kernel settled from what actually ran, not the answer's
|
|
161
|
+
* words. A turn with no record scores unavailable: there is nothing to read,
|
|
162
|
+
* which is not the same as a wrong verdict.
|
|
163
|
+
*/
|
|
164
|
+
export function outcomeScorer(verdicts: readonly TurnOutcomeVerdict[]): Scorer {
|
|
165
|
+
return {
|
|
166
|
+
name: 'outcome',
|
|
167
|
+
// The record either says one of the verdicts or it does not.
|
|
168
|
+
severity: 'gate',
|
|
169
|
+
score(turn: EvalTurn): Score {
|
|
170
|
+
const outcome = turn.outcome
|
|
171
|
+
if (!outcome) {
|
|
172
|
+
return { score: 0, unavailable: true, reason: 'the turn has no outcome record' }
|
|
173
|
+
}
|
|
174
|
+
const ok = verdicts.includes(outcome.verdict)
|
|
175
|
+
return {
|
|
176
|
+
score: ok ? 1 : 0,
|
|
177
|
+
reason: ok
|
|
178
|
+
? `verdict ${outcome.verdict}`
|
|
179
|
+
: `verdict ${outcome.verdict}, expected one of ${verdicts.join(', ')}`,
|
|
180
|
+
details: { verdict: outcome.verdict, expected: verdicts },
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Whether the answer's plain check claims agree with the turn's outcome
|
|
188
|
+
* record: 1 when `compareAnswerToOutcome` found no mismatch, 0 when it found
|
|
189
|
+
* one, with the claim and what the record holds in the detail.
|
|
190
|
+
*
|
|
191
|
+
* Pass `{ expectMismatch: true }` for a case that is built to contradict
|
|
192
|
+
* itself, so the suite proves the comparison fires as well as that it stays
|
|
193
|
+
* silent.
|
|
194
|
+
*/
|
|
195
|
+
export function claimMismatchScorer(opts: { expectMismatch?: boolean } = {}): Scorer {
|
|
196
|
+
const expectMismatch = opts.expectMismatch === true
|
|
197
|
+
return {
|
|
198
|
+
name: 'claim-mismatch',
|
|
199
|
+
severity: 'gate',
|
|
200
|
+
score(turn: EvalTurn): Score {
|
|
201
|
+
const found = turn.claimMismatch
|
|
202
|
+
const ok = expectMismatch ? found !== undefined : found === undefined
|
|
203
|
+
return {
|
|
204
|
+
score: ok ? 1 : 0,
|
|
205
|
+
reason: found
|
|
206
|
+
? `${found.said}, but the record: ${found.recordSays}`
|
|
207
|
+
: 'no claim in the answer contradicts the record',
|
|
208
|
+
details: { claimMismatch: found ?? null, expectMismatch },
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Score whether the turn was handed back to a person.
|
|
216
|
+
*
|
|
217
|
+
* Pass `{ expectKind }` for a case built so the model hands the task back, and
|
|
218
|
+
* the scorer checks it did, and for that kind; with nothing it checks the turn
|
|
219
|
+
* was not handed back. A gate: a scripted suite pins the kernel's side of it.
|
|
220
|
+
*/
|
|
221
|
+
export function handedBackScorer(opts: { expectKind?: HandBackKind } = {}): Scorer {
|
|
222
|
+
return {
|
|
223
|
+
name: 'handed-back',
|
|
224
|
+
severity: 'gate',
|
|
225
|
+
score(turn: EvalTurn): Score {
|
|
226
|
+
const found = turn.handedBack
|
|
227
|
+
const ok =
|
|
228
|
+
opts.expectKind === undefined ? found === undefined : found?.kind === opts.expectKind
|
|
229
|
+
return {
|
|
230
|
+
score: ok ? 1 : 0,
|
|
231
|
+
reason: found ? `handed back (${found.kind}): ${found.blocker}` : 'not handed back',
|
|
232
|
+
details: { handedBack: found ?? null, expectKind: opts.expectKind ?? null },
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
155
238
|
/**
|
|
156
239
|
* Judge the turn with a caller-supplied predicate.
|
|
157
240
|
*
|
package/src/eval/types.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
+
import type { AnswerClaimMismatch, TurnOutcome } from '../types/session/outcome.js'
|
|
1
2
|
import type { StepResult } from '../types/session/step.js'
|
|
3
|
+
import type { CaseIntervals } from './bootstrap.js'
|
|
4
|
+
import type { ReportDisclosure } from './disclosure.js'
|
|
5
|
+
import type { RepeatReliability, SplitSummary } from './report-stats.js'
|
|
2
6
|
import type { ScoreUncertainty } from './uncertainty.js'
|
|
3
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Which part of a suite a case belongs to.
|
|
10
|
+
*
|
|
11
|
+
* `development` cases are the ones the harness was shaped against; a number
|
|
12
|
+
* measured on them says how well it fits them. `held-out` cases were not
|
|
13
|
+
* looked at while it was shaped, and only they say how it does on cases it
|
|
14
|
+
* has not seen.
|
|
15
|
+
*/
|
|
16
|
+
export type EvalSplit = 'development' | 'held-out'
|
|
17
|
+
|
|
4
18
|
/**
|
|
5
19
|
* One case in a dataset: an input, and what a good run looks like.
|
|
6
20
|
*
|
|
@@ -19,6 +33,11 @@ export interface EvalCase<TInput = unknown> {
|
|
|
19
33
|
expectedTools?: readonly string[]
|
|
20
34
|
/** Per-case scorer overrides; falls back to the dataset's scorers. */
|
|
21
35
|
scorers?: readonly Scorer[]
|
|
36
|
+
/**
|
|
37
|
+
* `development` or `held-out`. Left out, the case is reported as
|
|
38
|
+
* unassigned. See {@link EvalSplit}.
|
|
39
|
+
*/
|
|
40
|
+
split?: EvalSplit
|
|
22
41
|
}
|
|
23
42
|
|
|
24
43
|
/** What actually happened, handed to every scorer. */
|
|
@@ -36,6 +55,18 @@ export interface EvalTurn {
|
|
|
36
55
|
durationMs: number
|
|
37
56
|
/** Set when the turn threw rather than settling. */
|
|
38
57
|
error?: string
|
|
58
|
+
/**
|
|
59
|
+
* What the turn changed and what checked it, from the kernel's own record of
|
|
60
|
+
* its tool calls. Absent for a turn that never ran the loop.
|
|
61
|
+
*/
|
|
62
|
+
outcome?: TurnOutcome
|
|
63
|
+
/**
|
|
64
|
+
* A plain claim in the answer that the outcome record contradicts, found by
|
|
65
|
+
* `compareAnswerToOutcome`. Absent when there is none.
|
|
66
|
+
*/
|
|
67
|
+
claimMismatch?: AnswerClaimMismatch
|
|
68
|
+
/** The model handed the task back to a person and the turn ended there. Absent otherwise. */
|
|
69
|
+
handedBack?: import('../types/session/hand-back.js').HandBack
|
|
39
70
|
}
|
|
40
71
|
|
|
41
72
|
/**
|
|
@@ -143,6 +174,10 @@ export interface CaseResult {
|
|
|
143
174
|
* mattered. Absent when no gate missed.
|
|
144
175
|
*/
|
|
145
176
|
failedGates?: readonly string[]
|
|
177
|
+
/** Which run of this case this is, from 1. Set on every run of a report that has `repeats`. */
|
|
178
|
+
repeat?: number
|
|
179
|
+
/** The case's declared split, copied here so a report can be cut by it. */
|
|
180
|
+
split?: EvalSplit
|
|
146
181
|
}
|
|
147
182
|
|
|
148
183
|
export interface ExperimentReport {
|
|
@@ -177,4 +212,45 @@ export interface ExperimentReport {
|
|
|
177
212
|
*/
|
|
178
213
|
byScorer: Record<string, number>
|
|
179
214
|
durationMs: number
|
|
215
|
+
/**
|
|
216
|
+
* Times each case ran. When it is above 1, `cases` holds every run of
|
|
217
|
+
* every case, in case order, each marked with its `repeat`, and `passed`,
|
|
218
|
+
* `failed` and `inconclusive` count runs. Absent in a report written before
|
|
219
|
+
* repeats existed, which is read as 1.
|
|
220
|
+
*/
|
|
221
|
+
repeats?: number
|
|
222
|
+
/** Seed of the bootstrap behind {@link intervals}. */
|
|
223
|
+
seed?: number
|
|
224
|
+
/**
|
|
225
|
+
* Passed runs over judged runs. An inconclusive run is in neither number,
|
|
226
|
+
* so it cannot pull the rate either way.
|
|
227
|
+
*/
|
|
228
|
+
passRate?: number
|
|
229
|
+
/**
|
|
230
|
+
* 95% intervals for {@link mean} and {@link passRate}, by a bootstrap over
|
|
231
|
+
* cases. Absent from a report that predates it.
|
|
232
|
+
*/
|
|
233
|
+
intervals?: CaseIntervals
|
|
234
|
+
/** Per case: how many of its repeats passed. Present when `repeats` is above 1. */
|
|
235
|
+
caseSummaries?: readonly CaseRepeatSummary[]
|
|
236
|
+
/** Reliability across repeats. Present when `repeats` is above 1. */
|
|
237
|
+
reliability?: RepeatReliability
|
|
238
|
+
/** Numbers per split. Keys appear only for splits that have cases. */
|
|
239
|
+
splits?: Partial<Record<EvalSplit | 'unassigned', SplitSummary>>
|
|
240
|
+
/** What produced this report. */
|
|
241
|
+
disclosure?: ReportDisclosure
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** How the repeats of one case went. */
|
|
245
|
+
export interface CaseRepeatSummary {
|
|
246
|
+
case: string
|
|
247
|
+
split?: EvalSplit
|
|
248
|
+
repeats: number
|
|
249
|
+
passed: number
|
|
250
|
+
failed: number
|
|
251
|
+
inconclusive: number
|
|
252
|
+
/** Mean score over the judged repeats; null when none was judged. */
|
|
253
|
+
mean: number | null
|
|
254
|
+
/** Every repeat passed. An inconclusive repeat means this is false. */
|
|
255
|
+
passedEveryRepeat: boolean
|
|
180
256
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import { EMPTY_TOKEN_USAGE } from '../../constants/limits.js'
|
|
7
7
|
import { NAMZU } from '../../constants/telemetry/index.js'
|
|
8
8
|
import { resolveModelPricing } from '../../pricing/index.js'
|
|
9
|
+
import { compareAnswerToOutcome } from '../../runtime/query/turn/answer-claims.js'
|
|
9
10
|
import type { SessionTokenBudget } from '../../store/budget/index.js'
|
|
10
11
|
import type { SessionCheckpointStore } from '../../store/checkpoint/index.js'
|
|
11
12
|
import { foldSessionLog } from '../../store/session-log/incremental.js'
|
|
@@ -40,6 +41,7 @@ import {
|
|
|
40
41
|
type SessionEventType,
|
|
41
42
|
isEphemeralEvent,
|
|
42
43
|
} from '../../types/session/events.js'
|
|
44
|
+
import type { HandBack } from '../../types/session/hand-back.js'
|
|
43
45
|
import type { ProjectId, TopicId } from '../../types/session/ids.js'
|
|
44
46
|
import type { TurnOutcome } from '../../types/session/outcome.js'
|
|
45
47
|
import type { SessionRecord } from '../../types/session/records.js'
|
|
@@ -516,6 +518,12 @@ export class TurnRecorder {
|
|
|
516
518
|
else this.#turn.outcome = outcome
|
|
517
519
|
}
|
|
518
520
|
|
|
521
|
+
/** The model handed the task back; set once, as the turn ends. */
|
|
522
|
+
setHandedBack(handBack: HandBack | undefined): void {
|
|
523
|
+
if (handBack === undefined) delete this.#turn.handedBack
|
|
524
|
+
else this.#turn.handedBack = handBack
|
|
525
|
+
}
|
|
526
|
+
|
|
519
527
|
setSteps(steps: readonly StepResult[]): void {
|
|
520
528
|
this.#turn.steps = steps
|
|
521
529
|
}
|
|
@@ -612,6 +620,11 @@ export class TurnRecorder {
|
|
|
612
620
|
settlement(status: TurnSettlement['status']): LiveTurnSettlement {
|
|
613
621
|
const turn = this.getTurn()
|
|
614
622
|
const resultMessageId = this.#lastAssistantEntry()?.id
|
|
623
|
+
// A task handed back says what blocks it in the model's words; those are not
|
|
624
|
+
// an answer to read claims out of.
|
|
625
|
+
const claimMismatch = turn.handedBack
|
|
626
|
+
? undefined
|
|
627
|
+
: compareAnswerToOutcome(turn.result, turn.outcome)
|
|
615
628
|
return {
|
|
616
629
|
status,
|
|
617
630
|
iterations: turn.currentIteration,
|
|
@@ -625,6 +638,8 @@ export class TurnRecorder {
|
|
|
625
638
|
abandonedTaskIds: [...(turn.abandonedTaskIds ?? [])],
|
|
626
639
|
abandonedJobIds: [...(turn.abandonedJobIds ?? [])],
|
|
627
640
|
...(turn.outcome ? { outcome: turn.outcome } : {}),
|
|
641
|
+
...(claimMismatch ? { claimMismatch } : {}),
|
|
642
|
+
...(turn.handedBack ? { handedBack: turn.handedBack } : {}),
|
|
628
643
|
}
|
|
629
644
|
}
|
|
630
645
|
|
|
@@ -1560,9 +1575,15 @@ export function eventDraft(
|
|
|
1560
1575
|
...payload
|
|
1561
1576
|
} = event as SessionEvent & Record<string, unknown>
|
|
1562
1577
|
const draft = JSON.parse(JSON.stringify(payload)) as Record<string, unknown>
|
|
1563
|
-
// The outcome
|
|
1578
|
+
// The outcome, the claim mismatch and the hand-back ride the live settlement
|
|
1579
|
+
// only; the log keeps the outcome in its own record, the other two nowhere.
|
|
1564
1580
|
if (draft.settlement !== undefined && typeof draft.settlement === 'object') {
|
|
1565
|
-
const {
|
|
1581
|
+
const {
|
|
1582
|
+
outcome: _outcome,
|
|
1583
|
+
claimMismatch: _claimMismatch,
|
|
1584
|
+
handedBack: _handedBack,
|
|
1585
|
+
...settlement
|
|
1586
|
+
} = draft.settlement as Record<string, unknown>
|
|
1566
1587
|
draft.settlement = settlement
|
|
1567
1588
|
}
|
|
1568
1589
|
return { ...draft, ...(turnId ? { turnId } : {}) } as Parameters<SessionLog['append']>[1]
|
package/src/plugin/index.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
assertEnableable,
|
|
3
|
+
discoverPlugins,
|
|
4
|
+
loadPluginManifest,
|
|
5
|
+
discoverAllPluginDirs,
|
|
6
|
+
parsePluginManifestText,
|
|
7
|
+
} from './loader.js'
|
|
2
8
|
export { definePlugin } from './define.js'
|
|
3
9
|
export type { DefinedPlugin, DefinePluginOptions } from './define.js'
|
|
4
10
|
export type { PluginDiscoveryOptions, PluginEnablementCapabilities } from './loader.js'
|
package/src/plugin/loader.ts
CHANGED
|
@@ -97,12 +97,26 @@ export async function loadPluginManifest(
|
|
|
97
97
|
throw new Error(`Plugin manifest must be a regular file, not a symlink: ${manifestPath}`)
|
|
98
98
|
}
|
|
99
99
|
const raw = await readFile(manifestPath, 'utf-8')
|
|
100
|
-
const
|
|
101
|
-
const manifest = PluginManifestSchema.parse(parsed)
|
|
100
|
+
const manifest = parsePluginManifestText(raw)
|
|
102
101
|
assertEnableable(manifest, capabilities)
|
|
103
102
|
return manifest
|
|
104
103
|
}
|
|
105
104
|
|
|
105
|
+
/**
|
|
106
|
+
* A manifest's text to a validated manifest, or a thrown reason: a
|
|
107
|
+
* `SyntaxError` for text that is not JSON, a zod error (with its `issues`)
|
|
108
|
+
* for JSON that is not a manifest.
|
|
109
|
+
*
|
|
110
|
+
* The first two of the loader's three steps on the manifest text (parse,
|
|
111
|
+
* schema; {@link assertEnableable} is the third). `loadPluginManifest` calls
|
|
112
|
+
* it, and so does a host that checks a manifest without loading the plugin,
|
|
113
|
+
* so the rules live once.
|
|
114
|
+
*/
|
|
115
|
+
export function parsePluginManifestText(raw: string): PluginManifest {
|
|
116
|
+
const parsed: unknown = JSON.parse(raw)
|
|
117
|
+
return PluginManifestSchema.parse(parsed)
|
|
118
|
+
}
|
|
119
|
+
|
|
106
120
|
async function discoverScopedPlugins(
|
|
107
121
|
authorityRoot: string,
|
|
108
122
|
relativePluginDir: string,
|
package/src/public-runtime.ts
CHANGED
|
@@ -283,6 +283,14 @@ export {
|
|
|
283
283
|
SESSION_GOAL_TOOL_NAMES,
|
|
284
284
|
buildSessionGoalTools,
|
|
285
285
|
} from './tools/goal/index.js'
|
|
286
|
+
export {
|
|
287
|
+
DEFAULT_GOAL_REFUSALS,
|
|
288
|
+
GoalConfirmation,
|
|
289
|
+
NO_CHECK_REASON_CODE,
|
|
290
|
+
decideGoalConfirmation,
|
|
291
|
+
describeGoalEnding,
|
|
292
|
+
recordSentence,
|
|
293
|
+
} from './tools/goal/confirmation.js'
|
|
286
294
|
export { SessionGoalActivation } from './manager/goal/activation.js'
|
|
287
295
|
export { buildToolResultHashes, hashToolResult } from './utils/hash.js'
|
|
288
296
|
export {
|
|
@@ -508,6 +516,7 @@ export {
|
|
|
508
516
|
export {
|
|
509
517
|
discoverSkills,
|
|
510
518
|
loadSkill,
|
|
519
|
+
parseSkillMarkdown,
|
|
511
520
|
resolveSkillChain,
|
|
512
521
|
SKILL_FRONTMATTER_KEYS,
|
|
513
522
|
SKILL_FRONTMATTER_TOLERATED_KEYS,
|
|
@@ -568,6 +577,7 @@ export {
|
|
|
568
577
|
EXPLORE_AGENT_DESCRIPTION,
|
|
569
578
|
EXPLORE_AGENT_ID,
|
|
570
579
|
EXPLORE_AGENT_PROMPT,
|
|
580
|
+
AGENT_FILE_KEYS,
|
|
571
581
|
MAX_AGENT_FILE_CHARS,
|
|
572
582
|
PLAN_AGENT_DESCRIPTION,
|
|
573
583
|
PLAN_AGENT_ID,
|
|
@@ -692,7 +702,9 @@ export {
|
|
|
692
702
|
definePlugin,
|
|
693
703
|
discoverAllPluginDirs,
|
|
694
704
|
discoverPlugins,
|
|
705
|
+
assertEnableable,
|
|
695
706
|
loadPluginManifest,
|
|
707
|
+
parsePluginManifestText,
|
|
696
708
|
MAX_SHELL_HOOK_TIMEOUT_MS,
|
|
697
709
|
PluginLifecycleManager,
|
|
698
710
|
PluginResolver,
|
|
@@ -902,6 +914,7 @@ export {
|
|
|
902
914
|
isRecognizedModernError,
|
|
903
915
|
isResourceNotFoundError,
|
|
904
916
|
isUnsupportedProtocolVersionError,
|
|
917
|
+
MCP_TASKS_EXTENSION,
|
|
905
918
|
LocalExecutionContext,
|
|
906
919
|
mcpEraCacheKey,
|
|
907
920
|
MCPHttpStatusError,
|
|
@@ -1022,6 +1035,8 @@ export type {
|
|
|
1022
1035
|
AcpClientCapabilities,
|
|
1023
1036
|
AcpInitializeParams,
|
|
1024
1037
|
AcpInitializeResult,
|
|
1038
|
+
AcpKernelFacts,
|
|
1039
|
+
AcpHostKernelFacts,
|
|
1025
1040
|
AcpSessionCancelParams,
|
|
1026
1041
|
AcpSessionNewParams,
|
|
1027
1042
|
AcpSessionNewResult,
|
|
@@ -1399,11 +1414,28 @@ export { anyOf, hasToolCall, stepCountIs } from './types/session/step.js'
|
|
|
1399
1414
|
// ─── evaluation harness ──────────────────────────────────────────────────
|
|
1400
1415
|
|
|
1401
1416
|
export {
|
|
1417
|
+
BOOTSTRAP_RESAMPLES,
|
|
1418
|
+
DEFAULT_EVAL_SEED,
|
|
1419
|
+
EvalUsageError,
|
|
1420
|
+
MIN_CASES_FOR_INTERVAL,
|
|
1421
|
+
bootstrapCases,
|
|
1422
|
+
bootstrapPairedDifference,
|
|
1423
|
+
compareEvalReports,
|
|
1424
|
+
exactSignTestP,
|
|
1425
|
+
formatEvalComparison,
|
|
1426
|
+
formatRunSummary,
|
|
1427
|
+
isEvalUsageError,
|
|
1428
|
+
loadEvalReportFile,
|
|
1429
|
+
summarizeRun,
|
|
1430
|
+
withEvalRunOptions,
|
|
1402
1431
|
compareHarnessTrials,
|
|
1403
1432
|
reviewHarnessCandidate,
|
|
1433
|
+
claimMismatchScorer,
|
|
1434
|
+
handedBackScorer,
|
|
1404
1435
|
completionScorer,
|
|
1405
1436
|
containsScorer,
|
|
1406
1437
|
customScorer,
|
|
1438
|
+
outcomeScorer,
|
|
1407
1439
|
evalTurnFromQuery,
|
|
1408
1440
|
evalTurnFromTurn,
|
|
1409
1441
|
formatReport,
|
|
@@ -1413,6 +1445,33 @@ export {
|
|
|
1413
1445
|
trajectoryScorer,
|
|
1414
1446
|
} from './eval/index.js'
|
|
1415
1447
|
|
|
1448
|
+
// ─── answer against record ───────────────────────────────────────────────
|
|
1449
|
+
|
|
1450
|
+
export {
|
|
1451
|
+
ANSWER_CLAIM_MAX_CHARS,
|
|
1452
|
+
ANSWER_CLAIM_MAX_QUOTE_CHARS,
|
|
1453
|
+
compareAnswerToOutcome,
|
|
1454
|
+
describeAnswerClaimMismatch,
|
|
1455
|
+
} from './runtime/query/turn/answer-claims.js'
|
|
1456
|
+
|
|
1457
|
+
// ─── handing the task back ───────────────────────────────────────────────
|
|
1458
|
+
|
|
1459
|
+
export {
|
|
1460
|
+
HAND_BACK_GUIDANCE,
|
|
1461
|
+
HAND_BACK_GUIDANCE_CONTRIBUTION_ID,
|
|
1462
|
+
HAND_BACK_MAX_CHARS,
|
|
1463
|
+
HAND_BACK_RECEIPT,
|
|
1464
|
+
HAND_BACK_SIBLING_REFUSAL,
|
|
1465
|
+
HAND_BACK_TOOL_NAME,
|
|
1466
|
+
HandBackInputSchema,
|
|
1467
|
+
buildHandBackTool,
|
|
1468
|
+
describeHandBack,
|
|
1469
|
+
handBackKindSentence,
|
|
1470
|
+
handBackModelLines,
|
|
1471
|
+
handBackReason,
|
|
1472
|
+
parseHandBack,
|
|
1473
|
+
} from './tools/hand-back/index.js'
|
|
1474
|
+
|
|
1416
1475
|
// ─── metrics ─────────────────────────────────────────────────────────────
|
|
1417
1476
|
//
|
|
1418
1477
|
// Exported so a host can record its own measurements onto the same series
|
|
@@ -1428,6 +1487,17 @@ export {
|
|
|
1428
1487
|
} from './telemetry/metrics.js'
|
|
1429
1488
|
export type { TokenUsageSample } from './telemetry/metrics.js'
|
|
1430
1489
|
|
|
1490
|
+
// The GenAI convention names on spans: the pinned version, the switch, the
|
|
1491
|
+
// list a test holds emitted names against. See docs/sdk/telemetry-genai.md.
|
|
1492
|
+
export {
|
|
1493
|
+
GENAI_NON_CONVENTION_NAMES,
|
|
1494
|
+
GENAI_SEMCONV_ATTRIBUTES,
|
|
1495
|
+
GENAI_SEMCONV_SCHEMA_URL,
|
|
1496
|
+
GENAI_SEMCONV_VERSION,
|
|
1497
|
+
genAiConventionsEnabled,
|
|
1498
|
+
setGenAiConventions,
|
|
1499
|
+
} from './telemetry/genai.js'
|
|
1500
|
+
|
|
1431
1501
|
// ─── guardrails ──────────────────────────────────────────────────────────
|
|
1432
1502
|
|
|
1433
1503
|
export {
|
package/src/public-types.ts
CHANGED
|
@@ -406,7 +406,16 @@ export type {
|
|
|
406
406
|
SessionGoalStore,
|
|
407
407
|
} from './store/goal/index.js'
|
|
408
408
|
export type { ResolveGoalRoundAuthority } from './tools/goal/index.js'
|
|
409
|
+
export type {
|
|
410
|
+
GoalConfirmationOptions,
|
|
411
|
+
GoalDecision,
|
|
412
|
+
GoalDecisionInput,
|
|
413
|
+
GoalEnding,
|
|
414
|
+
GoalEndingReport,
|
|
415
|
+
GoalStatement,
|
|
416
|
+
} from './tools/goal/confirmation.js'
|
|
409
417
|
export type { ActiveSessionGoal } from './manager/goal/activation.js'
|
|
418
|
+
export type { HandBack, HandBackKind } from './types/session/hand-back.js'
|
|
410
419
|
|
|
411
420
|
export type {
|
|
412
421
|
AgentHandle,
|