Add cross-project pattern registry for retrieval-augmented generalization
- Create patterns/ directory with README, manifest, and 10 initial patterns covering Ollama JSON fallback, API escaping, deprecation, PTY auth, queue-poll, LLM-as-parser, credential rotation, reverse proxy binding, human approval gates, and transient retry. - Wire pattern loading into architecture/pipeline.js based on task tags. - Update architecture/orchestrator.js to load patterns and surface them in the system prompt. - Update MEMORY.md, ARCHITECTURE.md, and CONTEXT.md to document the registry and record the decision.
This commit is contained in:
@@ -14,9 +14,51 @@ class ContextPipeline {
|
||||
this.rules = [];
|
||||
this.preferences = [];
|
||||
this.memory = [];
|
||||
this.patterns = [];
|
||||
this.context = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 3b: Load Relevant Cross-Project Patterns
|
||||
*/
|
||||
async loadPatterns(taskInput) {
|
||||
const manifestPath = path.join('/home/jcbeasley/.openclaw/workspace', 'patterns', 'patterns.json');
|
||||
try {
|
||||
const manifestRaw = fs.readFileSync(manifestPath, 'utf8');
|
||||
const manifest = JSON.parse(manifestRaw);
|
||||
const query = (taskInput || '').toLowerCase();
|
||||
|
||||
for (const pattern of manifest.patterns || []) {
|
||||
const tokens = [
|
||||
...(pattern.tags || []),
|
||||
...(pattern.affected_projects || []),
|
||||
pattern.id,
|
||||
pattern.name
|
||||
].map(t => t.toLowerCase());
|
||||
|
||||
const matched = tokens.some(token => query.includes(token));
|
||||
if (!matched) continue;
|
||||
|
||||
const patternFile = path.join('/home/jcbeasley/.openclaw/workspace', pattern.file);
|
||||
try {
|
||||
const content = fs.readFileSync(patternFile, 'utf8');
|
||||
this.patterns.push({
|
||||
source: pattern.file,
|
||||
content: content,
|
||||
priority: 6,
|
||||
id: pattern.id
|
||||
});
|
||||
} catch (err) {
|
||||
// Pattern file missing; skip
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// Manifest missing or invalid; skip pattern loading
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 1: Load Behavior Rules (always injected)
|
||||
*/
|
||||
@@ -83,7 +125,7 @@ class ContextPipeline {
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 3: Load Relevant Memory
|
||||
* Step 3a: Load Relevant Memory
|
||||
*/
|
||||
async loadRelevantMemory(query, maxResults = 5) {
|
||||
// For now, load recent episodic memories
|
||||
@@ -129,7 +171,8 @@ class ContextPipeline {
|
||||
const allContext = [
|
||||
...this.rules,
|
||||
...this.preferences.sort((a, b) => b.priority - a.priority),
|
||||
...this.memory
|
||||
...this.memory,
|
||||
...this.patterns
|
||||
];
|
||||
|
||||
const packet = {
|
||||
@@ -140,7 +183,8 @@ class ContextPipeline {
|
||||
metadata: {
|
||||
rules_count: this.rules.length,
|
||||
prefs_count: this.preferences.length,
|
||||
memory_count: this.memory.length
|
||||
memory_count: this.memory.length,
|
||||
patterns_count: this.patterns.length
|
||||
}
|
||||
};
|
||||
|
||||
@@ -184,6 +228,7 @@ if (require.main === module) {
|
||||
.loadRules()
|
||||
.then(() => pipeline.loadPreferences())
|
||||
.then(() => pipeline.loadRelevantMemory(process.argv[2] || ''))
|
||||
.then(() => pipeline.loadPatterns(process.argv[2] || ''))
|
||||
.then(() => {
|
||||
const packet = pipeline.buildPacket(process.argv[2] || 'No task specified');
|
||||
console.log(JSON.stringify(packet, null, 2));
|
||||
|
||||
Reference in New Issue
Block a user