Complete M16 action select circle parity
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-08-20 22:57:59 -04:00
parent fb5abd8e37
commit 6a0b980d75
368 changed files with 17417 additions and 117 deletions

View File

@@ -12,6 +12,9 @@ export const CONTEXT_LIMITS = Object.freeze({
evidenceFiles: 12,
evidenceBytes: 8192,
contextTokens: 3500,
// The printed task bundle is itself part of the model input. Reserve room
// for that envelope instead of spending the entire budget on file content.
contextEnvelopeTokens: 1024,
});
const read = (file) => fs.readFileSync(file, "utf8");
@@ -199,8 +202,9 @@ export function selectInputPaths(candidates, {
const unique = [...new Set((candidates ?? []).filter((candidate) => typeof candidate === "string" && candidate.length > 0))];
const reserved = new Set(reservedPaths.map(normalizedPathKey));
const generated = new Set(generatedPaths.map(normalizedPathKey));
const contextRemainingTokens = Math.max(0, effectiveLimits.contextTokens - sourceTokens);
const contextRemainingBytes = Math.max(0, effectiveLimits.contextTokens * 4 - sourceBytes);
const contentTokenBudget = Math.max(0, effectiveLimits.contextTokens - (effectiveLimits.contextEnvelopeTokens ?? 0));
const contextRemainingTokens = Math.max(0, contentTokenBudget - sourceTokens);
const contextRemainingBytes = Math.max(0, contentTokenBudget * 4 - sourceBytes);
const excluded = [];
const selected = [];
let selectedBytes = 0;
@@ -264,6 +268,45 @@ export function selectInputPaths(candidates, {
};
}
/**
* Public task context is intentionally smaller than the audit bundle. The
* latter is written to task-context.json for governance, while this shape is
* what an execution agent should receive and read.
*/
export function compactTaskContext(context) {
const compactText = (value, limit) => {
if (typeof value !== "string" || value.length <= limit) return value;
return `${value.slice(0, limit - 3)}...`;
};
const excludedReasons = {};
for (const item of context.inputSelection?.excluded ?? []) {
excludedReasons[item.reason] = (excludedReasons[item.reason] ?? 0) + 1;
}
return {
schemaVersion: context.schemaVersion,
task: context.task,
parentTask: context.parentTask,
status: context.status,
goal: compactText(context.goal, 800),
scope: context.scope,
commands: context.commands,
inputPaths: context.inputPaths,
inputSelection: {
selected: context.inputSelection?.selected?.map(({ path, bytes, tokens }) => ({ path, bytes, tokens })) ?? [],
excludedCount: context.inputSelection?.excluded?.length ?? 0,
excludedReasons,
totals: context.inputSelection?.totals ?? { files: 0, bytes: 0, tokens: 0 },
},
exitCriteria: context.exitCriteria,
nextTask: context.nextTask,
sourceDocuments: context.sourceDocuments,
readPolicy: {
required: context.readPolicy.required,
},
parent: { manifest: context.parent.manifest },
};
}
function nextFromPlan(task) {
const index = loadTaskIndex();
if (index?.entries?.[task]) return index.entries[task].next;
@@ -375,5 +418,35 @@ export function contextSizeReport(bundle) {
const evidenceFiles = context?.inputSelection?.totals?.files ?? 0;
const evidenceTokens = context?.inputSelection?.totals?.tokens ?? 0;
const totalTokens = sourceTokens + evidenceTokens;
return { documents: docs, sourceTokens, evidenceFiles, evidenceBytes, evidenceTokens, totalTokens, withinBudget: docs[0].bytes <= CONTEXT_LIMITS.queueBytes && docs[1].bytes <= CONTEXT_LIMITS.taskBytes && docs[2].bytes <= CONTEXT_LIMITS.parentManifestBytes && docs[3].bytes <= CONTEXT_LIMITS.parentStatusBytes && evidenceFiles <= CONTEXT_LIMITS.evidenceFiles && evidenceBytes <= CONTEXT_LIMITS.evidenceBytes && totalTokens <= CONTEXT_LIMITS.contextTokens };
const baseReport = {
documents: docs,
sourceTokens,
evidenceFiles,
evidenceBytes,
evidenceTokens,
totalTokens,
reservedEnvelopeTokens: CONTEXT_LIMITS.contextEnvelopeTokens,
estimatedContextTokens: totalTokens + CONTEXT_LIMITS.contextEnvelopeTokens,
};
// Include the pretty-printed report itself: that is what print-task-context
// puts on stdout and therefore what the execution model actually receives.
let serializedContextTokens = 0;
for (let attempt = 0; attempt < 3; attempt += 1) {
serializedContextTokens = tokenEstimate(JSON.stringify({
...compactTaskContext(context),
size: { ...baseReport, serializedContextTokens },
}, null, 2));
}
return {
...baseReport,
serializedContextTokens,
withinBudget: docs[0].bytes <= CONTEXT_LIMITS.queueBytes
&& docs[1].bytes <= CONTEXT_LIMITS.taskBytes
&& docs[2].bytes <= CONTEXT_LIMITS.parentManifestBytes
&& docs[3].bytes <= CONTEXT_LIMITS.parentStatusBytes
&& evidenceFiles <= CONTEXT_LIMITS.evidenceFiles
&& evidenceBytes <= CONTEXT_LIMITS.evidenceBytes
&& serializedContextTokens <= CONTEXT_LIMITS.contextEnvelopeTokens
&& baseReport.estimatedContextTokens <= CONTEXT_LIMITS.contextTokens,
};
}