snipara-companion 3.1.0 → 3.1.1
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 +4 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +68 -0
- package/docs/FULL_REFERENCE.md +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,8 +94,10 @@ sample from `sample_unreviewed` to `sample_reviewed` or `sample_rejected`.
|
|
|
94
94
|
For conversational human review, run `workflow producer-triage` to create a
|
|
95
95
|
batched Decision Request V0 artifact, `workflow decisions --json` to give the
|
|
96
96
|
LLM client the exact question/evidence/options to ask, and `workflow decide`
|
|
97
|
-
only after the human answers.
|
|
98
|
-
|
|
97
|
+
only after the human answers. Batched requests include readable evidence items
|
|
98
|
+
with artifact summaries, statuses, file hints, and metadata instead of only
|
|
99
|
+
opaque refs. Decision requests never resolve by timeout or default, and only
|
|
100
|
+
`workflow decide` applies the existing `producer-review` path.
|
|
99
101
|
Other producers such as `outcome-capture preview --emit-decisions`,
|
|
100
102
|
`workflow decision-producer memory`, and `workflow decision-producer context-risk`
|
|
101
103
|
emit requests with their existing apply paths declared; they do not write
|
package/dist/index.d.ts
CHANGED
|
@@ -2814,7 +2814,9 @@ interface ProducerLoopArtifactReportSummary {
|
|
|
2814
2814
|
producerKind: ProducerLoopProducerKind;
|
|
2815
2815
|
workflowId?: string;
|
|
2816
2816
|
phaseId?: string;
|
|
2817
|
+
phaseTitle?: string;
|
|
2817
2818
|
outcome?: TaskCommitOutcome;
|
|
2819
|
+
summary?: string;
|
|
2818
2820
|
path: string;
|
|
2819
2821
|
relativePath: string;
|
|
2820
2822
|
artifactHash: string;
|
package/dist/index.js
CHANGED
|
@@ -12533,6 +12533,7 @@ function buildDecisionRequest(input) {
|
|
|
12533
12533
|
evidence: {
|
|
12534
12534
|
summary: input.evidence.summary,
|
|
12535
12535
|
refs: uniqueStrings8(input.evidence.refs),
|
|
12536
|
+
...input.evidence.items ? { items: normalizeEvidenceItems(input.evidence.items) } : {},
|
|
12536
12537
|
reasonCodes: uniqueStrings8(input.evidence.reasonCodes),
|
|
12537
12538
|
...input.evidence.files ? { files: uniqueStrings8(input.evidence.files) } : {},
|
|
12538
12539
|
...input.evidence.applyPath ? { applyPath: input.evidence.applyPath } : {},
|
|
@@ -12595,6 +12596,30 @@ function uniqueStrings8(values) {
|
|
|
12595
12596
|
}
|
|
12596
12597
|
return result;
|
|
12597
12598
|
}
|
|
12599
|
+
function normalizeEvidenceItems(items) {
|
|
12600
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12601
|
+
const normalized = [];
|
|
12602
|
+
for (const item of items) {
|
|
12603
|
+
const ref = item.ref.trim();
|
|
12604
|
+
if (!ref || seen.has(ref)) continue;
|
|
12605
|
+
seen.add(ref);
|
|
12606
|
+
normalized.push({
|
|
12607
|
+
ref,
|
|
12608
|
+
...normalizeOptionalString(item.title) ? { title: normalizeOptionalString(item.title) } : {},
|
|
12609
|
+
...normalizeOptionalString(item.summary) ? { summary: normalizeOptionalString(item.summary) } : {},
|
|
12610
|
+
...normalizeOptionalString(item.kind) ? { kind: normalizeOptionalString(item.kind) } : {},
|
|
12611
|
+
...normalizeOptionalString(item.status) ? { status: normalizeOptionalString(item.status) } : {},
|
|
12612
|
+
...item.files ? { files: uniqueStrings8(item.files) } : {},
|
|
12613
|
+
...item.metadata ? { metadata: normalizeMetadata(item.metadata) } : {}
|
|
12614
|
+
});
|
|
12615
|
+
}
|
|
12616
|
+
return normalized;
|
|
12617
|
+
}
|
|
12618
|
+
function normalizeMetadata(metadata) {
|
|
12619
|
+
return Object.fromEntries(
|
|
12620
|
+
Object.entries(metadata).filter(([, value]) => value !== void 0).sort(([left], [right]) => left.localeCompare(right))
|
|
12621
|
+
);
|
|
12622
|
+
}
|
|
12598
12623
|
function isRecord6(value) {
|
|
12599
12624
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
12600
12625
|
}
|
|
@@ -16025,6 +16050,7 @@ function summarizeProducerLoopArtifactFile(filePath, cwd) {
|
|
|
16025
16050
|
);
|
|
16026
16051
|
}
|
|
16027
16052
|
const producer = isRecord8(parsed.producer) ? parsed.producer : void 0;
|
|
16053
|
+
const source2 = isRecord8(parsed.source) ? parsed.source : void 0;
|
|
16028
16054
|
const ledger = isRecord8(parsed.ledger) ? parsed.ledger : void 0;
|
|
16029
16055
|
const calibration = isRecord8(parsed.calibration) ? parsed.calibration : void 0;
|
|
16030
16056
|
const review = isRecord8(parsed.review) ? parsed.review : void 0;
|
|
@@ -16051,7 +16077,9 @@ function summarizeProducerLoopArtifactFile(filePath, cwd) {
|
|
|
16051
16077
|
producerKind,
|
|
16052
16078
|
workflowId: stringValue5(producer.workflowId),
|
|
16053
16079
|
phaseId: stringValue5(producer.phaseId),
|
|
16080
|
+
phaseTitle: stringValue5(producer.phaseTitle),
|
|
16054
16081
|
outcome: isTaskCommitOutcome(outcome) ? outcome : void 0,
|
|
16082
|
+
summary: stringValue5(source2?.summary),
|
|
16055
16083
|
path: filePath,
|
|
16056
16084
|
relativePath: relativePath2,
|
|
16057
16085
|
artifactHash: `sha256:${hashContent(content)}`,
|
|
@@ -16422,6 +16450,23 @@ function printDecisionRequests(entries) {
|
|
|
16422
16450
|
console.log(` recommendation: ${request.recommendation}`);
|
|
16423
16451
|
}
|
|
16424
16452
|
console.log(` evidence: ${request.evidence.summary}`);
|
|
16453
|
+
if (request.evidence.items?.length) {
|
|
16454
|
+
console.log(" items:");
|
|
16455
|
+
for (const item of request.evidence.items) {
|
|
16456
|
+
console.log(` - ${item.ref}${item.title ? `: ${item.title}` : ""}`);
|
|
16457
|
+
if (item.status || item.kind) {
|
|
16458
|
+
console.log(` ${[item.kind, item.status].filter(Boolean).join(" | ")}`);
|
|
16459
|
+
}
|
|
16460
|
+
if (item.summary) {
|
|
16461
|
+
console.log(` ${item.summary}`);
|
|
16462
|
+
}
|
|
16463
|
+
if (item.files?.length) {
|
|
16464
|
+
console.log(
|
|
16465
|
+
` files: ${item.files.slice(0, 5).join(", ")}${item.files.length > 5 ? ` (+${item.files.length - 5})` : ""}`
|
|
16466
|
+
);
|
|
16467
|
+
}
|
|
16468
|
+
}
|
|
16469
|
+
}
|
|
16425
16470
|
if (request.evidence.applyCommand) {
|
|
16426
16471
|
console.log(` apply: ${request.evidence.applyCommand}`);
|
|
16427
16472
|
}
|
|
@@ -16531,6 +16576,23 @@ function buildProducerTriageRequest(report) {
|
|
|
16531
16576
|
return null;
|
|
16532
16577
|
}
|
|
16533
16578
|
const refs = candidates.map((artifact) => artifact.artifactId);
|
|
16579
|
+
const items = candidates.map((artifact) => ({
|
|
16580
|
+
ref: artifact.artifactId,
|
|
16581
|
+
title: producerLoopTriageItemTitle(artifact),
|
|
16582
|
+
summary: artifact.summary ?? `${artifact.producerKind} sample for review.`,
|
|
16583
|
+
kind: artifact.producerKind,
|
|
16584
|
+
status: artifact.reviewStatus,
|
|
16585
|
+
files: artifact.files.slice(0, 12),
|
|
16586
|
+
metadata: {
|
|
16587
|
+
generatedAt: artifact.generatedAt,
|
|
16588
|
+
workflowId: artifact.workflowId ?? null,
|
|
16589
|
+
phaseId: artifact.phaseId ?? null,
|
|
16590
|
+
outcome: artifact.outcome ?? null,
|
|
16591
|
+
artifactHash: artifact.artifactHash,
|
|
16592
|
+
ledgerHash: artifact.ledgerHash ?? null,
|
|
16593
|
+
relativePath: artifact.relativePath
|
|
16594
|
+
}
|
|
16595
|
+
}));
|
|
16534
16596
|
return buildDecisionRequest({
|
|
16535
16597
|
producer: {
|
|
16536
16598
|
kind: "producer_loop_triage",
|
|
@@ -16542,6 +16604,7 @@ function buildProducerTriageRequest(report) {
|
|
|
16542
16604
|
evidence: {
|
|
16543
16605
|
summary: `${candidates.length} unreviewed Producer Loop samples; ${report.invalidArtifacts.length} invalid artifacts; hardGateReady remains false.`,
|
|
16544
16606
|
refs,
|
|
16607
|
+
items,
|
|
16545
16608
|
reasonCodes: uniqueStrings10([
|
|
16546
16609
|
"triage_rules_v0",
|
|
16547
16610
|
"producer_loop_report_valid",
|
|
@@ -16561,6 +16624,11 @@ function buildProducerTriageRequest(report) {
|
|
|
16561
16624
|
]
|
|
16562
16625
|
});
|
|
16563
16626
|
}
|
|
16627
|
+
function producerLoopTriageItemTitle(artifact) {
|
|
16628
|
+
const workflow2 = artifact.workflowId ?? "producer-loop";
|
|
16629
|
+
const phase = artifact.phaseTitle ?? artifact.phaseId;
|
|
16630
|
+
return phase ? `${workflow2} / ${phase}` : workflow2;
|
|
16631
|
+
}
|
|
16564
16632
|
async function workflowProducerTriageCommand(options) {
|
|
16565
16633
|
const report = buildProducerLoopReport({ minReviewSampleSize: options.minReviewSamples });
|
|
16566
16634
|
const request = buildProducerTriageRequest(report);
|
package/docs/FULL_REFERENCE.md
CHANGED
|
@@ -222,7 +222,8 @@ snipara-companion workflow resume --include-session-context
|
|
|
222
222
|
It never marks samples reviewed by itself.
|
|
223
223
|
- `workflow decisions` lists pending decision requests in a compact shape an LLM
|
|
224
224
|
client can render as a human question, including evidence, options,
|
|
225
|
-
recommendation,
|
|
225
|
+
recommendation, declared apply path, and readable evidence items for batched
|
|
226
|
+
decisions.
|
|
226
227
|
- `workflow decide <request-id> --choose <option> --reviewer <name>` writes a
|
|
227
228
|
Decision Response V0 receipt under `.snipara/decisions/resolved/`. For
|
|
228
229
|
Producer Loop triage accept/reject choices, it applies the existing
|