feat: file-backed goal objectives + compaction accounting fixes
Compaction fixes (observed in a real long run): - the summary message's zeroed tokens froze the goal counter at its pre-compaction value; segments now close with the previously displayed total as a continuity floor - audits and continuations after a summary tail now take execution params (provider/model/agent/variant) from the newest non-summary assistant turn instead of inheriting agent 'compaction' and the summarize model File-backed objectives: - the objective text lives in <data-dir>/goals/<sessionId>.md, keyed by session id (one goal per session, a new goal overwrites the file); metadata carries only an objectiveFile flag so session.updated fanout stays light, and never a path — ids are pattern-validated before any filesystem access - limit raised to 5000 chars, no snapshot field: the UI fetches content via PUT/GET/DELETE /api/goals/objective/:sessionId (behind the blanket /api auth gate), writes the file before stamping metadata, and falls back to an inline objective when the write fails - the loop reads the file fresh on every tick, so objectives are live-editable mid-goal; a missing file falls back to the inline text - scheduled goal tasks write the objective file server-side; VS Code degrades to the audit note (route unavailable there by design)
This commit is contained in:
@@ -444,9 +444,22 @@ export const createScheduledTasksRuntime = (deps) => {
|
||||
// from session events like any other goal.
|
||||
const createTaskGoal = async ({ baseUrl, authHeaders, sessionID, projectPath, task }) => {
|
||||
const now = Date.now();
|
||||
// File-backed objective keyed by session id: metadata stays light, the
|
||||
// full expanded prompt lives under the OpenChamber data dir. If the file
|
||||
// write fails, fall back to an inline (clamped) objective.
|
||||
const objectiveText = expandSnippets(task.execution.prompt, projectPath);
|
||||
let objectiveFile = false;
|
||||
try {
|
||||
const { writeObjective } = await import('../session-goal/objectives.js');
|
||||
await writeObjective(sessionID, objectiveText);
|
||||
objectiveFile = true;
|
||||
} catch (error) {
|
||||
console.warn('[scheduled-tasks] goal objective file write failed, falling back to inline:', error?.message || error);
|
||||
}
|
||||
const goal = {
|
||||
id: `${now.toString(36)}${Math.random().toString(36).slice(2, 8)}`,
|
||||
objective: expandSnippets(task.execution.prompt, projectPath).slice(0, 2000),
|
||||
objective: objectiveFile ? '' : objectiveText.slice(0, 5000),
|
||||
objectiveFile,
|
||||
status: 'active',
|
||||
tokenBudget: task.execution.goalTokenBudget || null,
|
||||
tokensUsed: 0,
|
||||
|
||||
Reference in New Issue
Block a user