Merge Scattermind decision context sources

This commit is contained in:
OpenClaw Bot
2026-05-27 00:03:49 +02:00
parent 25c7c08543
commit b556c67a4c
3 changed files with 95 additions and 14 deletions
+53 -12
View File
@@ -462,12 +462,33 @@ function cleanProvenance(input = {}) {
};
}
function firstObject(...values) {
for (const value of values) {
const obj = objectFrom(value);
if (Object.keys(obj).length) return obj;
function lensContent(lens = {}) {
if (Array.isArray(lens)) return lens;
const obj = objectFrom(lens);
return obj.content || obj.text || obj.summary || obj.items || '';
}
function cleanSentenceList(value = '', maxItems = 8, maxText = 180) {
if (Array.isArray(value)) return cleanFlexibleTextList(value, maxItems, maxText);
return contextSentences(value).map(item => cleanText(item, maxText)).filter(Boolean).slice(0, maxItems);
}
function collectContextList(sources = [], aliases = [], maxItems = 8) {
return uniqueList(sources.flatMap(source => {
const obj = objectFrom(source);
return aliases.flatMap(alias => cleanFlexibleTextList(obj[alias], maxItems, 180));
}), maxItems);
}
function firstContextText(sources = [], aliases = []) {
for (const source of sources) {
const obj = objectFrom(source);
for (const alias of aliases) {
const cleaned = cleanText(obj[alias], 180);
if (cleaned) return cleaned;
}
}
return {};
return '';
}
function cleanDecisionContext(input = {}) {
@@ -475,25 +496,45 @@ function cleanDecisionContext(input = {}) {
const artifact = objectFrom(input.artifact || featureSet.artifact);
const conceptMap = objectFrom(input.conceptMap || featureSet.conceptMap || artifact.conceptMap);
const conceptMapLenses = objectFrom(conceptMap.lenses || input.lenses || featureSet.lenses);
const riskLens = objectFrom(conceptMapLenses.risk);
const riskLens = objectFrom(conceptMapLenses.risk || conceptMapLenses.risks || conceptMapLenses.boundaries || conceptMapLenses.notYet);
const audienceLens = objectFrom(conceptMapLenses.audience || conceptMapLenses.who || conceptMapLenses.customer || conceptMapLenses.users);
const constraintsLens = objectFrom(conceptMapLenses.constraints || conceptMapLenses.boundaries || conceptMapLenses.scope);
const assumptionsLens = objectFrom(conceptMapLenses.assumptions || conceptMapLenses.unknowns || conceptMapLenses.openQuestions);
const structuredContext = objectFrom(input.context);
const sourceContext = firstObject(input.decisionContext, featureSet.decisionContext, artifact.decisionContext, conceptMap.decisionContext, structuredContext, conceptMap.context);
const contextSources = [
input.decisionContext,
featureSet.decisionContext,
artifact.decisionContext,
conceptMap.decisionContext,
structuredContext,
conceptMap.context,
featureSet.context,
artifact.context,
];
const textContextGuardrails = guardrailsFromContextText([
typeof input.context === 'string' ? input.context : '',
riskLens.content || riskLens.text || '',
lensContent(riskLens),
lensContent(constraintsLens),
conceptMap.risk || conceptMap.whatNotToBuildYet || conceptMap.notYet || '',
].filter(Boolean).join('\n'));
return {
targetAudience: cleanText(input.targetAudience || featureSet.targetAudience || sourceContext.targetAudience || conceptMap.targetAudience || '', 180),
targetAudience: cleanText(input.targetAudience || featureSet.targetAudience || firstContextText(contextSources, ['targetAudience', 'audience', 'who', 'whoItHelps', 'customer', 'users']) || conceptMap.targetAudience || lensContent(audienceLens), 180),
constraints: uniqueList([
...cleanFlexibleTextList(input.constraints || featureSet.constraints || sourceContext.constraints || conceptMap.constraints, 8, 180),
...cleanFlexibleTextList(input.constraints || featureSet.constraints || conceptMap.constraints, 8, 180),
...collectContextList(contextSources, ['constraints', 'constraint', 'boundaries', 'scope'], 8),
...cleanSentenceList(lensContent(constraintsLens), 8, 180),
...textContextGuardrails.constraints,
], 8),
nonGoals: uniqueList([
...cleanFlexibleTextList(input.nonGoals || input.avoid || featureSet.nonGoals || featureSet.avoid || sourceContext.nonGoals || sourceContext.avoid || conceptMap.nonGoals || conceptMap.avoid, 8, 180),
...cleanFlexibleTextList(input.nonGoals || input.avoid || featureSet.nonGoals || featureSet.avoid || conceptMap.nonGoals || conceptMap.avoid, 8, 180),
...collectContextList(contextSources, ['nonGoals', 'nonGoal', 'avoid', 'notYet', 'doNotBuild'], 8),
...textContextGuardrails.nonGoals,
], 8),
assumptions: cleanFlexibleTextList(input.assumptions || featureSet.assumptions || sourceContext.assumptions || conceptMap.assumptions, 6, 180),
assumptions: uniqueList([
...cleanFlexibleTextList(input.assumptions || featureSet.assumptions || conceptMap.assumptions, 6, 180),
...collectContextList(contextSources, ['assumptions', 'assumption', 'unknowns', 'openQuestions'], 6),
...cleanSentenceList(lensContent(assumptionsLens), 6, 180),
], 6),
};
}