Skip to content

feat: confucius-aligned agent stack - #34

Merged
iotserver24 merged 3 commits into
mainfrom
feat/confucius-rebuild
Mar 17, 2026
Merged

feat: confucius-aligned agent stack#34
iotserver24 merged 3 commits into
mainfrom
feat/confucius-rebuild

Conversation

@iotserver24

@iotserver24 iotserver24 commented Mar 15, 2026

Copy link
Copy Markdown
Owner

Implements Confucius/Cooper-aligned architecture: economy mode, security hardening, AX-lite reasoning tiers, session memory, context pruning, meta-tool synthesis, self-correction loop, multi-model routing, CoM-inspired mindsets, and device/ARM/mobile support.

Copilot AI review requested due to automatic review settings March 15, 2026 11:36
@xibe-review

xibe-review Bot commented Mar 15, 2026

Copy link
Copy Markdown

Hey @iotserver24! 👋

I'll go through the changes and help you out with an automated review! 🔍

Starting the review now...

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a “Confucius/Cooper-aligned” agent stack to XibeCode, focusing on cost controls, security hardening, hierarchical execution (plan-first), session memory, context pruning, and a self-correction loop for run-pr.

Changes:

  • Add economy mode configuration + CLI flags, plus multi-model routing (planning vs execution) and optional plan-first behavior.
  • Add session memory persistence and lightweight context pruning to reduce repetition and token usage.
  • Add security utilities for path traversal and URL validation; introduce synthesized session-scoped tools and run-pr self-correction retries; expand docs + CI.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
src/utils/safety.ts Adds sanitizePath / sanitizeUrl for path traversal + SSRF reduction.
src/utils/config.ts Adds economy/context-pruning/multi-model config fields and getters.
src/index.ts Exposes new CLI flags for cost mode, plan-first, and mindset mode.
src/core/tools.ts Adds synthesized tools, path/URL sanitization usage, and fetch URL hardening.
src/core/session-memory.ts Implements persisted session memory (attempts + learnings + summary injection).
src/core/modes.ts Categorizes synthesize_tool for mode permissioning.
src/core/context-pruner.ts Adds keyword-based context pruning with optional code-graph augmentation.
src/core/agent.ts Adds reasoning tiers, plan-first flow, mindset switching, session summary injection, and model routing.
src/commands/run.ts Wires economy mode, session memory, and context pruning into run.
src/commands/run-pr.ts Wires economy mode/session memory/context pruning and adds a self-correction retry loop on test failures.
src/commands/config.ts Adds config setters for cost mode and economy model.
src/commands/chat.ts Adds economy-mode model selection for chat.
SECURITY.md Documents new security posture and features.
README.md Documents platform/device support and economy-mode CLI usage.
DOCS.md Adds economy mode docs, session memory, context pruning, and platform/device matrix.
.github/workflows/ci.yml Adds ARM runner to matrix and a security audit step.
Comments suppressed due to low confidence (1)

src/core/tools.ts:2857

  • fetch_url sanitizes the initial URL, but fetch() will follow redirects by default. A public URL could 30x-redirect to a blocked/private destination (SSRF) after passing sanitizeUrl. Consider setting redirect: 'manual' (or error) and/or re-validating the final response.url after redirects before reading the body.
    const urlResult = sanitizeUrl(url.trim());
    if (!urlResult.ok) {
      return { error: true, success: false, message: urlResult.message };
    }
    try {
      const response = await fetch(urlResult.url, {
        headers: {
          'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
          'Accept': 'text/html,application/xhtml+xml,text/plain,application/json',
        },
        signal: AbortSignal.timeout(15000),
      });

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/utils/safety.ts
Comment on lines +13 to +20
export function sanitizePath(workingDir: string, filePath: string): { ok: true; path: string } | { ok: false; message: string } {
const normalized = path.normalize(filePath).replace(/^(\.\.(\/|\\))+/, '');
const resolved = path.resolve(workingDir, normalized);
const relative = path.relative(workingDir, resolved);
if (relative.startsWith('..') || path.isAbsolute(relative)) {
return { ok: false, message: 'Path escapes working directory and is not allowed' };
}
return { ok: true, path: resolved };
Comment thread src/utils/config.ts
/** Max files to suggest from context pruning; 0 means disabled. */
getMaxContextFiles(): number {
const v = this.get('maxContextFiles');
return v !== undefined && v !== null ? Number(v) : 40;
Comment thread src/core/tools.ts
Comment on lines +348 to 352
try {
if (this.dynamicTools.has(toolName)) {
return this.runDynamicTool(toolName, p);
}
switch (toolName) {
Comment thread src/core/tools.ts
Comment on lines +807 to +812
const reserved = new Set(['read_file', 'write_file', 'run_command', 'synthesize_tool', 'get_context']);
if (reserved.has(name)) {
return { error: true, success: false, message: `Cannot override built-in tool: ${name}` };
}
this.dynamicTools.set(name, { description: description || name, script });
return { success: true, message: `Tool "${name}" registered. You can call it with the same name. Execution is sandboxed.` };
Comment thread src/utils/safety.ts
Comment on lines +13 to +42
export function sanitizePath(workingDir: string, filePath: string): { ok: true; path: string } | { ok: false; message: string } {
const normalized = path.normalize(filePath).replace(/^(\.\.(\/|\\))+/, '');
const resolved = path.resolve(workingDir, normalized);
const relative = path.relative(workingDir, resolved);
if (relative.startsWith('..') || path.isAbsolute(relative)) {
return { ok: false, message: 'Path escapes working directory and is not allowed' };
}
return { ok: true, path: resolved };
}

/**
* Validate URL for fetch_url to reduce SSRF risk: only http/https, no localhost or private IPs by default.
*/
export function sanitizeUrl(url: string, allowLocalhost = false): { ok: true; url: string } | { ok: false; message: string } {
let parsed: URL;
try {
parsed = new URL(url);
} catch {
return { ok: false, message: 'Invalid URL' };
}
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
return { ok: false, message: 'Only http and https URLs are allowed' };
}
if (!allowLocalhost) {
const host = (parsed.hostname || '').toLowerCase();
if (host === 'localhost' || host === '127.0.0.1' || host.startsWith('192.168.') || host.startsWith('10.') || host.endsWith('.local')) {
return { ok: false, message: 'Local or private URLs are not allowed' };
}
}
return { ok: true, url: parsed.toString() };
Comment on lines +66 to +105
export async function pruneContext(
workingDir: string,
task: string,
options: PruneOptions = {}
): Promise<string[]> {
const maxFiles = options.maxFiles ?? DEFAULT_MAX_FILES;
const extensions = options.extensions ?? DEFAULT_EXTENSIONS;
const useContent = options.useContent ?? false;
const usePkgStyleContext = options.usePkgStyleContext ?? false;

const words = taskWords(task);
const patterns = extensions.map(ext => `**/${ext}`);
const ignore = IGNORE_DIRS.map(d => `**/${d}/**`);
const files = words.size > 0
? await glob(patterns, { cwd: workingDir, absolute: false, ignore, onlyFiles: true })
: [];

const scored: { path: string; score: number }[] = [];

for (const rel of files) {
let content: string | null = null;
if (useContent) {
try {
const full = path.join(workingDir, rel);
const buf = await fs.readFile(full, 'utf-8').catch(() => '');
content = buf.slice(0, 500);
} catch {
// skip content
}
}
const score = scorePathAndContent(rel, content, words);
scored.push({ path: rel, score });
}

scored.sort((a, b) => b.score - a.score);

const withScore = scored.filter(s => s.score > 0);
let top = withScore.length > 0
? withScore.slice(0, maxFiles).map(s => s.path)
: scored.slice(0, maxFiles).map(s => s.path);
Comment thread src/utils/safety.ts
Comment on lines +26 to +42
export function sanitizeUrl(url: string, allowLocalhost = false): { ok: true; url: string } | { ok: false; message: string } {
let parsed: URL;
try {
parsed = new URL(url);
} catch {
return { ok: false, message: 'Invalid URL' };
}
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
return { ok: false, message: 'Only http and https URLs are allowed' };
}
if (!allowLocalhost) {
const host = (parsed.hostname || '').toLowerCase();
if (host === 'localhost' || host === '127.0.0.1' || host.startsWith('192.168.') || host.startsWith('10.') || host.endsWith('.local')) {
return { ok: false, message: 'Local or private URLs are not allowed' };
}
}
return { ok: true, url: parsed.toString() };
Comment thread src/core/tools.ts
*/
private async runDynamicTool(toolName: string, _input: any): Promise<any> {
const def = this.dynamicTools.get(toolName);
if (!def) return { error: true, success: false, message: `Dynamic tool "${toolName}" not found` };
Comment thread src/commands/run-pr.ts

// ── Config ───────────────────────────────────────────────────────────────
const model = options.model || config.getModel();
const costMode = (options.costMode || config.getCostMode()) as 'normal' | 'economy';
Comment thread src/core/agent.ts
Comment on lines 660 to 664
const params: any = {
model: this.config.model,
model: this.getModelForTier(),
max_tokens: 8192,
messages: this.messages,
system: this.getSystemPrompt(),
@iotserver24

Copy link
Copy Markdown
Owner Author

@copilot explain whether this makes this ai tool better at coding or not
+
Whether this will save more cost

Copilot AI commented Mar 17, 2026

Copy link
Copy Markdown
Contributor

@iotserver24 I've opened a new pull request, #35, to work on those changes. Once the pull request is ready, I'll request review from you.

@iotserver24

Copy link
Copy Markdown
Owner Author

Xibe
explain whether this makes this ai tool better at coding or not
+
Whether this will save more cost

@xibe-review

xibe-review Bot commented Mar 17, 2026

Copy link
Copy Markdown

Hey @iotserver24! 👋

I'll go through the changes and help you out! 🔍

Starting the review now...

feat: confucius-aligned agent stack — economy mode, session memory, context pruning, self-correction
@iotserver24
iotserver24 merged commit 251c858 into main Mar 17, 2026
1 of 2 checks passed
@iotserver24
iotserver24 deleted the feat/confucius-rebuild branch March 20, 2026 09:33
iotserver24 added a commit that referenced this pull request May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants