fix(sf): implement features hinted by unused-import warnings
- ai-memory-tools.js: use options param for configurable limits in formatAllMemoriesForPrompt - metrics-central.js: enforce MAX_HISTOGRAM_BUCKETS cap on histogram bucket count - reasoning-assist.js: use REASONING_ASSIST_MAX_CHARS to cap prompt length with logWarning - trajectory-recorder.js: add debugLog for failed step recordings Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
parent
f440fbed9c
commit
4601a7d3fb
4 changed files with 89 additions and 18 deletions
|
|
@ -14,7 +14,7 @@
|
|||
* - Returns confirmation to the agent so it knows the memory was recorded
|
||||
*/
|
||||
|
||||
import { storeMemory, MEMORY_TYPES } from "./memory-repository.js";
|
||||
import { MEMORY_TYPES, storeMemory } from "./memory-repository.js";
|
||||
import { getDatabase, isDbAvailable } from "./sf-db.js";
|
||||
import { logWarning } from "./workflow-logger.js";
|
||||
|
||||
|
|
@ -48,7 +48,11 @@ export function emitKeyFact({ content, source = "", sessionId, unitId }) {
|
|||
db,
|
||||
});
|
||||
if (result) {
|
||||
return { ok: true, id: result.id, message: `Key fact recorded (#${result.id})` };
|
||||
return {
|
||||
ok: true,
|
||||
id: result.id,
|
||||
message: `Key fact recorded (#${result.id})`,
|
||||
};
|
||||
}
|
||||
return { ok: false, id: null, message: "Duplicate or failed to store" };
|
||||
} catch (err) {
|
||||
|
|
@ -68,7 +72,13 @@ export function emitKeyFact({ content, source = "", sessionId, unitId }) {
|
|||
* @param {string} [params.unitId] — Unit that discovered this snippet
|
||||
* @returns {{ok: boolean, id: number|null, message: string}}
|
||||
*/
|
||||
export function emitKeySnippet({ content, filePath = "", language = "", sessionId, unitId }) {
|
||||
export function emitKeySnippet({
|
||||
content,
|
||||
filePath = "",
|
||||
language = "",
|
||||
sessionId,
|
||||
unitId,
|
||||
}) {
|
||||
if (!content || content.trim().length === 0) {
|
||||
return { ok: false, id: null, message: "Content is required" };
|
||||
}
|
||||
|
|
@ -92,7 +102,11 @@ export function emitKeySnippet({ content, filePath = "", language = "", sessionI
|
|||
db,
|
||||
});
|
||||
if (result) {
|
||||
return { ok: true, id: result.id, message: `Key snippet recorded (#${result.id})` };
|
||||
return {
|
||||
ok: true,
|
||||
id: result.id,
|
||||
message: `Key snippet recorded (#${result.id})`,
|
||||
};
|
||||
}
|
||||
return { ok: false, id: null, message: "Duplicate or failed to store" };
|
||||
} catch (err) {
|
||||
|
|
@ -134,7 +148,11 @@ export function emitResearchNote({ content, topic = "", sessionId, unitId }) {
|
|||
db,
|
||||
});
|
||||
if (result) {
|
||||
return { ok: true, id: result.id, message: `Research note recorded (#${result.id})` };
|
||||
return {
|
||||
ok: true,
|
||||
id: result.id,
|
||||
message: `Research note recorded (#${result.id})`,
|
||||
};
|
||||
}
|
||||
return { ok: false, id: null, message: "Duplicate or failed to store" };
|
||||
} catch (err) {
|
||||
|
|
@ -153,7 +171,12 @@ export function emitResearchNote({ content, topic = "", sessionId, unitId }) {
|
|||
* @param {string} [params.unitId] — Unit that logged this event
|
||||
* @returns {{ok: boolean, id: number|null, message: string}}
|
||||
*/
|
||||
export function logWorkEvent({ event, eventType = "milestone", sessionId, unitId }) {
|
||||
export function logWorkEvent({
|
||||
event,
|
||||
eventType = "milestone",
|
||||
sessionId,
|
||||
unitId,
|
||||
}) {
|
||||
if (!event || event.trim().length === 0) {
|
||||
return { ok: false, id: null, message: "Event is required" };
|
||||
}
|
||||
|
|
@ -176,7 +199,11 @@ export function logWorkEvent({ event, eventType = "milestone", sessionId, unitId
|
|||
db,
|
||||
});
|
||||
if (result) {
|
||||
return { ok: true, id: result.id, message: `Work event logged (#${result.id})` };
|
||||
return {
|
||||
ok: true,
|
||||
id: result.id,
|
||||
message: `Work event logged (#${result.id})`,
|
||||
};
|
||||
}
|
||||
return { ok: false, id: null, message: "Duplicate or failed to store" };
|
||||
} catch (err) {
|
||||
|
|
@ -193,38 +220,74 @@ export function logWorkEvent({ event, eventType = "milestone", sessionId, unitId
|
|||
* @returns {string} — Formatted memory sections
|
||||
*/
|
||||
export function formatAllMemoriesForPrompt(sessionId, options = {}) {
|
||||
const { getMemories, formatMemoriesForPrompt } = require("./memory-repository.js");
|
||||
const {
|
||||
getMemories,
|
||||
formatMemoriesForPrompt,
|
||||
} = require("./memory-repository.js");
|
||||
const db = isDbAvailable() ? getDatabase() : null;
|
||||
if (!db) return "";
|
||||
|
||||
const sid = sessionId || process.env.SF_SESSION_ID || "default";
|
||||
const sections = [];
|
||||
const maxChars = options.maxChars || 8000;
|
||||
|
||||
// Key facts
|
||||
const facts = getMemories({ sessionId: sid, type: MEMORY_TYPES.KEY_FACT, limit: 30, db });
|
||||
const facts = getMemories({
|
||||
sessionId: sid,
|
||||
type: MEMORY_TYPES.KEY_FACT,
|
||||
limit: options.factLimit ?? 30,
|
||||
db,
|
||||
});
|
||||
if (facts.length > 0) {
|
||||
const formatted = formatMemoriesForPrompt(facts, { header: "Key Facts", maxChars: 2000 });
|
||||
const formatted = formatMemoriesForPrompt(facts, {
|
||||
header: "Key Facts",
|
||||
maxChars: Math.floor(maxChars * 0.3),
|
||||
});
|
||||
if (formatted) sections.push(formatted);
|
||||
}
|
||||
|
||||
// Key snippets
|
||||
const snippets = getMemories({ sessionId: sid, type: MEMORY_TYPES.KEY_SNIPPET, limit: 15, db });
|
||||
const snippets = getMemories({
|
||||
sessionId: sid,
|
||||
type: MEMORY_TYPES.KEY_SNIPPET,
|
||||
limit: options.snippetLimit ?? 15,
|
||||
db,
|
||||
});
|
||||
if (snippets.length > 0) {
|
||||
const formatted = formatMemoriesForPrompt(snippets, { header: "Key Snippets", maxChars: 3000 });
|
||||
const formatted = formatMemoriesForPrompt(snippets, {
|
||||
header: "Key Snippets",
|
||||
maxChars: Math.floor(maxChars * 0.4),
|
||||
});
|
||||
if (formatted) sections.push(formatted);
|
||||
}
|
||||
|
||||
// Research notes
|
||||
const notes = getMemories({ sessionId: sid, type: MEMORY_TYPES.RESEARCH_NOTE, limit: 15, db });
|
||||
const notes = getMemories({
|
||||
sessionId: sid,
|
||||
type: MEMORY_TYPES.RESEARCH_NOTE,
|
||||
limit: options.noteLimit ?? 15,
|
||||
db,
|
||||
});
|
||||
if (notes.length > 0) {
|
||||
const formatted = formatMemoriesForPrompt(notes, { header: "Research Notes", maxChars: 2000 });
|
||||
const formatted = formatMemoriesForPrompt(notes, {
|
||||
header: "Research Notes",
|
||||
maxChars: Math.floor(maxChars * 0.2),
|
||||
});
|
||||
if (formatted) sections.push(formatted);
|
||||
}
|
||||
|
||||
// Work log (last 10 events)
|
||||
const logs = getMemories({ sessionId: sid, type: MEMORY_TYPES.WORK_LOG, limit: 10, db });
|
||||
const logs = getMemories({
|
||||
sessionId: sid,
|
||||
type: MEMORY_TYPES.WORK_LOG,
|
||||
limit: options.logLimit ?? 10,
|
||||
db,
|
||||
});
|
||||
if (logs.length > 0) {
|
||||
const formatted = formatMemoriesForPrompt(logs, { header: "Work Log", maxChars: 1500 });
|
||||
const formatted = formatMemoriesForPrompt(logs, {
|
||||
header: "Work Log",
|
||||
maxChars: Math.floor(maxChars * 0.1),
|
||||
});
|
||||
if (formatted) sections.push(formatted);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,9 @@ class Histogram {
|
|||
) {
|
||||
this.name = name;
|
||||
this.help = help;
|
||||
const capped = [...buckets].sort((a, b) => a - b).slice(0, MAX_HISTOGRAM_BUCKETS);
|
||||
const capped = [...buckets]
|
||||
.sort((a, b) => a - b)
|
||||
.slice(0, MAX_HISTOGRAM_BUCKETS);
|
||||
this.buckets = capped;
|
||||
this.counts = new Map(); // bucket → count
|
||||
this.sum = 0;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,10 @@ export async function buildReasoningAssistPrompt(
|
|||
const result = parts.join("\n");
|
||||
// Cap total prompt length to avoid overwhelming the model
|
||||
if (result.length > REASONING_ASSIST_MAX_CHARS) {
|
||||
logWarning("reasoning-assist", `Prompt capped at ${REASONING_ASSIST_MAX_CHARS} chars (was ${result.length})`);
|
||||
logWarning(
|
||||
"reasoning-assist",
|
||||
`Prompt capped at ${REASONING_ASSIST_MAX_CHARS} chars (was ${result.length})`,
|
||||
);
|
||||
return result.slice(0, REASONING_ASSIST_MAX_CHARS);
|
||||
}
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -190,6 +190,9 @@ export function recordTrajectoryStep({
|
|||
|
||||
return { id: Number(result.lastInsertRowid), stepNumber };
|
||||
} catch (err) {
|
||||
debugLog("trajectory", `record step failed: ${stepType} #${stepNumber}`, {
|
||||
error: String(err),
|
||||
});
|
||||
logWarning("trajectory", "recordTrajectoryStep failed", {
|
||||
error: String(err),
|
||||
sessionId,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue