@themoltnet/pi-extension 0.31.2 → 0.32.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/dist/index.js +118 -5
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14226,6 +14226,86 @@ var PRODUCER_TASK_TYPES = new Set([
|
|
|
14226
14226
|
"render_pack",
|
|
14227
14227
|
"run_eval"
|
|
14228
14228
|
]);
|
|
14229
|
+
function isNonEmptyString(value) {
|
|
14230
|
+
return typeof value === "string" && value.length > 0;
|
|
14231
|
+
}
|
|
14232
|
+
function criterionWeight(criterion, index) {
|
|
14233
|
+
if (typeof criterion.weight === "number") return criterion.weight;
|
|
14234
|
+
if (typeof criterion.max_score === "number") return criterion.max_score / 100;
|
|
14235
|
+
if (typeof criterion.maxScore === "number") return criterion.maxScore / 100;
|
|
14236
|
+
throw new TaskBuildError([{
|
|
14237
|
+
field: `successCriteria/rubric/criteria/${index}/weight`,
|
|
14238
|
+
message: "criterion is missing weight or max_score"
|
|
14239
|
+
}]);
|
|
14240
|
+
}
|
|
14241
|
+
/**
|
|
14242
|
+
* Normalize authoring-time rubric criteria to canonical MoltNet rubric
|
|
14243
|
+
* criteria. Accepts `{id,title,description,weight}` and
|
|
14244
|
+
* `{name,description,max_score}` style inputs, strips authoring-only fields,
|
|
14245
|
+
* and fills a default scoring mode.
|
|
14246
|
+
*/
|
|
14247
|
+
function normalizeRubricCriteria(criteria, options) {
|
|
14248
|
+
const errors = [];
|
|
14249
|
+
const normalized = criteria.map((criterion, index) => {
|
|
14250
|
+
const id = criterion.id ?? criterion.name;
|
|
14251
|
+
const description = criterion.description ?? criterion.title;
|
|
14252
|
+
if (!isNonEmptyString(id)) errors.push({
|
|
14253
|
+
field: `successCriteria/rubric/criteria/${index}/id`,
|
|
14254
|
+
message: "criterion is missing id or name"
|
|
14255
|
+
});
|
|
14256
|
+
if (!isNonEmptyString(description)) errors.push({
|
|
14257
|
+
field: `successCriteria/rubric/criteria/${index}/description`,
|
|
14258
|
+
message: "criterion is missing description or title"
|
|
14259
|
+
});
|
|
14260
|
+
return {
|
|
14261
|
+
id: id ?? "",
|
|
14262
|
+
description: description ?? "",
|
|
14263
|
+
weight: criterionWeight(criterion, index),
|
|
14264
|
+
scoring: criterion.scoring ?? options?.scoring ?? "llm_score"
|
|
14265
|
+
};
|
|
14266
|
+
});
|
|
14267
|
+
if (errors.length > 0) throw new TaskBuildError(errors);
|
|
14268
|
+
return normalized;
|
|
14269
|
+
}
|
|
14270
|
+
/**
|
|
14271
|
+
* Build a canonical `SuccessCriteria` envelope from rubric/checklist-style
|
|
14272
|
+
* criteria. This keeps rubrics readable at the authoring boundary while
|
|
14273
|
+
* preserving the strict task schema on the wire.
|
|
14274
|
+
*/
|
|
14275
|
+
function buildRubricSuccessCriteria(options) {
|
|
14276
|
+
const rubric = {
|
|
14277
|
+
rubricId: options.rubricId,
|
|
14278
|
+
version: options.version ?? "v1",
|
|
14279
|
+
criteria: normalizeRubricCriteria(options.criteria, { scoring: options.scoring }),
|
|
14280
|
+
...options.contentHash ? { contentHash: options.contentHash } : {},
|
|
14281
|
+
...options.preamble ? { preamble: options.preamble } : {},
|
|
14282
|
+
...options.scope ? { scope: options.scope } : {}
|
|
14283
|
+
};
|
|
14284
|
+
const weightError = validateRubricWeights(rubric);
|
|
14285
|
+
if (weightError) throw new TaskBuildError([{
|
|
14286
|
+
field: "successCriteria/rubric/criteria",
|
|
14287
|
+
message: weightError
|
|
14288
|
+
}]);
|
|
14289
|
+
return {
|
|
14290
|
+
version: 1,
|
|
14291
|
+
rubric
|
|
14292
|
+
};
|
|
14293
|
+
}
|
|
14294
|
+
function resolveJudgeEvalAttemptTarget(target) {
|
|
14295
|
+
if ("judgeEvalTarget" in target && typeof target.judgeEvalTarget === "function") return target.judgeEvalTarget();
|
|
14296
|
+
if ("targetTaskId" in target) return {
|
|
14297
|
+
targetTaskId: target.targetTaskId,
|
|
14298
|
+
targetAttemptN: target.targetAttemptN
|
|
14299
|
+
};
|
|
14300
|
+
if ("taskId" in target) return {
|
|
14301
|
+
targetTaskId: target.taskId,
|
|
14302
|
+
targetAttemptN: target.accepted?.attemptN ?? target.attemptN ?? 1
|
|
14303
|
+
};
|
|
14304
|
+
throw new TaskBuildError([{
|
|
14305
|
+
field: "target",
|
|
14306
|
+
message: "judge_eval_attempt target is missing task id"
|
|
14307
|
+
}]);
|
|
14308
|
+
}
|
|
14229
14309
|
/**
|
|
14230
14310
|
* Fluent, network-free builder for a `tasks.create` body. Encodes the
|
|
14231
14311
|
* non-obvious task schema (context arrays, success-criteria gates,
|
|
@@ -14676,6 +14756,20 @@ function buildJudgeEvalAttempt(input) {
|
|
|
14676
14756
|
return buildTask("judge_eval_attempt", input);
|
|
14677
14757
|
}
|
|
14678
14758
|
/**
|
|
14759
|
+
* Build a `judge_eval_attempt` task from an accepted `run_eval` result (or a
|
|
14760
|
+
* small target tuple) plus human-friendly rubric criteria.
|
|
14761
|
+
*
|
|
14762
|
+
* @param target - A `TaskResultReader` or `{targetTaskId,targetAttemptN}` tuple.
|
|
14763
|
+
* @param options - Rubric metadata and eval/checklist-style criteria.
|
|
14764
|
+
* @returns A typed {@link TaskBuilder}.
|
|
14765
|
+
*/
|
|
14766
|
+
function buildJudgeEvalAttemptForRunEval(target, options) {
|
|
14767
|
+
return buildJudgeEvalAttempt({
|
|
14768
|
+
...resolveJudgeEvalAttemptTarget(target),
|
|
14769
|
+
successCriteria: buildRubricSuccessCriteria(options)
|
|
14770
|
+
});
|
|
14771
|
+
}
|
|
14772
|
+
/**
|
|
14679
14773
|
* Build a `pr_review` task. Requires `subject` + `successCriteria`. Note the
|
|
14680
14774
|
* rubric criteria must use `boolean` scoring for this task type.
|
|
14681
14775
|
*
|
|
@@ -14713,7 +14807,9 @@ var TaskResultReader = class {
|
|
|
14713
14807
|
accepted;
|
|
14714
14808
|
/** Token / cost usage for the accepted attempt, if reported. */
|
|
14715
14809
|
usage;
|
|
14810
|
+
/** Task id for the task whose accepted attempt is being read. */
|
|
14716
14811
|
taskId;
|
|
14812
|
+
/** CID of the accepted attempt output. */
|
|
14717
14813
|
outputCid;
|
|
14718
14814
|
constructor(task, attempt) {
|
|
14719
14815
|
const errors = [];
|
|
@@ -14806,6 +14902,19 @@ var TaskResultReader = class {
|
|
|
14806
14902
|
};
|
|
14807
14903
|
}
|
|
14808
14904
|
/**
|
|
14905
|
+
* Return the target tuple required by `judge_eval_attempt`.
|
|
14906
|
+
*
|
|
14907
|
+
* This intentionally uses the accepted attempt number, not merely the
|
|
14908
|
+
* attempt object passed to the reader, so a downstream judge is pinned to
|
|
14909
|
+
* the producer output that the task accepted.
|
|
14910
|
+
*/
|
|
14911
|
+
judgeEvalTarget() {
|
|
14912
|
+
return {
|
|
14913
|
+
targetTaskId: this.taskId,
|
|
14914
|
+
targetAttemptN: this.accepted.attemptN
|
|
14915
|
+
};
|
|
14916
|
+
}
|
|
14917
|
+
/**
|
|
14809
14918
|
* Build a `TaskRef` that anchors a downstream task to this accepted output
|
|
14810
14919
|
* and points at one persistent task artifact by CID.
|
|
14811
14920
|
*
|
|
@@ -14943,6 +15052,7 @@ function createTasksNamespace(context) {
|
|
|
14943
15052
|
buildAssessBrief,
|
|
14944
15053
|
buildJudgePack,
|
|
14945
15054
|
buildJudgeEvalAttempt,
|
|
15055
|
+
buildJudgeEvalAttemptForRunEval,
|
|
14946
15056
|
buildPrReview,
|
|
14947
15057
|
async readResult(taskOrId) {
|
|
14948
15058
|
const task = typeof taskOrId === "string" ? unwrapResult(await getTask({
|
|
@@ -26317,7 +26427,8 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
26317
26427
|
const message = err instanceof Error ? err.message : String(err);
|
|
26318
26428
|
reporterError = {
|
|
26319
26429
|
code: "reporter_failed",
|
|
26320
|
-
message
|
|
26430
|
+
message,
|
|
26431
|
+
retryable: true
|
|
26321
26432
|
};
|
|
26322
26433
|
process.stderr.write(`[reporter] ${message}\n`);
|
|
26323
26434
|
}
|
|
@@ -26527,9 +26638,11 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
26527
26638
|
retryable: false
|
|
26528
26639
|
}
|
|
26529
26640
|
};
|
|
26530
|
-
const
|
|
26531
|
-
const
|
|
26532
|
-
const
|
|
26641
|
+
const reporterErrorSnapshot = reporterError;
|
|
26642
|
+
const status = runError || llmAbort || parseError || reporterErrorSnapshot ? "failed" : "completed";
|
|
26643
|
+
const errorCode = runError?.code ?? parseError?.code ?? reporterErrorSnapshot?.code ?? (llmAbort ? "llm_api_error" : void 0);
|
|
26644
|
+
const errorMessage = runError?.message ?? parseError?.message ?? reporterErrorSnapshot?.message ?? (llmAbort ? llmErrorMessage ?? "LLM API error during turn" : void 0);
|
|
26645
|
+
const errorRetryable = reporterErrorSnapshot && errorCode === reporterErrorSnapshot.code && errorMessage === reporterErrorSnapshot.message ? reporterErrorSnapshot.retryable ?? false : false;
|
|
26533
26646
|
return {
|
|
26534
26647
|
taskId: task.id,
|
|
26535
26648
|
attemptN,
|
|
@@ -26541,7 +26654,7 @@ async function executePiTask(claimedTask, reporter, opts) {
|
|
|
26541
26654
|
...errorCode && errorMessage ? { error: {
|
|
26542
26655
|
code: errorCode,
|
|
26543
26656
|
message: errorMessage,
|
|
26544
|
-
retryable:
|
|
26657
|
+
retryable: errorRetryable
|
|
26545
26658
|
} } : {}
|
|
26546
26659
|
};
|
|
26547
26660
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/pi-extension",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MoltNet pi extension — sandboxed tool execution in Gondolin VMs with MoltNet identity and persistent memory",
|
|
6
6
|
"keywords": [
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@earendil-works/gondolin": "^0.9.1",
|
|
37
37
|
"@opentelemetry/api": "^1.9.0",
|
|
38
38
|
"typebox": "^1.2.8",
|
|
39
|
-
"@themoltnet/
|
|
40
|
-
"@themoltnet/
|
|
39
|
+
"@themoltnet/agent-runtime": "0.34.0",
|
|
40
|
+
"@themoltnet/sdk": "0.118.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@earendil-works/pi-coding-agent": ">=0.74.0",
|