slim the submit schemas: evidence and messages die; stringified-payload heal at the pre-validation seam
OpenRouter log diagnosis (owner, 2026-09-28): extraction time was
dominated by tool-validation retries. The failing call had the whole
propositions array emitted as ONE JSON-STRING ('propositions.0: must
be object'), a truncated placeholder artifact inside it, and
word-salad statements late in the array — payload-size collapse.
Field audit: 'evidence' was never persisted anywhere and its
faithfulness-checking consumer died with the fully-trusted ruling;
'messages' fed messageId granularity that NOTHING downstream reads,
and the model sent [] anyway (chat-level provenance in practice).
'aliases' stays (optional now): the auditor's find tool globs them.
Schema: propositions = {id, name, statement, aliases?}; edges =
{from, to, type}. Prompts lose the evidence/messages doctrine and
[id]-anchor guidance, gain a compact faithfulness line;
transcriptView renders anchorless. The auditor echo instruction
drops the evidence/messages mention, so its payload halves too.
Heal: healStringifiedArrays on the submit tool's prepareArguments
(pi-agent-core's sanctioned pre-TypeBox shim) parses a stringified
propositions/edges back into arrays — the LaTeX-restore doctrine:
heal weak-model wire behavior at the seam. Test drives the real
agent-loop seam with a stringified submit.
This commit is contained in:
+10
-12
@@ -85,16 +85,11 @@ export interface MergeSource {
|
||||
coverage?: CoverageEntry[];
|
||||
}
|
||||
|
||||
/** (chatId, messageIds) → provenance points; order-preserving, deduped. */
|
||||
function pointsOf(chatId: string, messages: string[]): ProvenancePoint[] {
|
||||
const seen = new Set<string>();
|
||||
const out: ProvenancePoint[] = [];
|
||||
for (const messageId of messages) {
|
||||
if (messageId.length === 0 || seen.has(messageId)) continue;
|
||||
seen.add(messageId);
|
||||
out.push({ chatId, messageId });
|
||||
}
|
||||
return out;
|
||||
/** The run's chat-level provenance point (submit-schema slim, 2026-09-28:
|
||||
* propositions no longer carry message ids — the model never reported
|
||||
* them reliably anyway — so every birth from a run shares one point). */
|
||||
function pointOf(chatId: string): ProvenancePoint[] {
|
||||
return [{ chatId, messageId: "" }];
|
||||
}
|
||||
|
||||
const samePoint = (a: ProvenancePoint, b: ProvenancePoint): boolean =>
|
||||
@@ -140,7 +135,7 @@ export function mergeFindings(chatId: string, audit: AuditResult, deps: GraphDep
|
||||
|
||||
for (const p of audit.propositions) {
|
||||
if (mapping.has(p.id)) continue; // already resolved for this chat — idempotent
|
||||
const points = pointsOf(chatId, p.messages);
|
||||
const points = pointOf(chatId);
|
||||
let graphNodeId: string;
|
||||
if (p.linkTo !== undefined && existingIds.has(p.linkTo)) {
|
||||
// Identity verdict: this proposition IS that node. Append a link
|
||||
@@ -206,7 +201,10 @@ export function mergeFindings(chatId: string, audit: AuditResult, deps: GraphDep
|
||||
from,
|
||||
to,
|
||||
type: edge.type,
|
||||
provenance: bridged ? [{ chatId, messageId: "" }] : pointsOf(chatId, edge.messages),
|
||||
// bridged vs transcript edges both carry the run's chat-level
|
||||
// point now; the distinction lives in the endpoint resolution
|
||||
// above (mapping vs existing node id), not in the provenance.
|
||||
provenance: pointOf(chatId),
|
||||
});
|
||||
assertedByChat.add(key);
|
||||
stats.edges++;
|
||||
|
||||
Reference in New Issue
Block a user