@inetafrica/open-claudia 2.6.9 → 2.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/core/scheduler.js +4 -1
- package/core/system-prompt.js +7 -23
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v2.6.10
|
|
4
|
+
- **Sessions: wakeups join the live conversation instead of forking it.** A scheduled wakeup/cron captured the channel's `sessionId` at schedule time and resumed that *frozen* id when it fired — but every run writes its result id back to the shared `state.lastSessionId`, and a home-conversation compaction mints a brand-new id. So a pending wakeup carrying a pre-compaction id would yank the channel's live pointer onto a dead thread, and the user's next typed message landed on the stale session. Multiple concurrent wakeups froze different ids and forked the channel into parallel sessions. Fix (`core/scheduler.js`): a wakeup now resumes the channel's live `state.lastSessionId` (already ownership-guarded in the runner); the frozen `job.sessionId` is used only as a cold-start fallback when there is no live pointer. Wakeups scheduled after upgrade join the current context; already-pending wakeups still carry their old id until they fire.
|
|
5
|
+
|
|
3
6
|
## v2.6.8
|
|
4
7
|
- **Tasks: a plan can't be completed while subtasks are still open.** `task done` (and the loopback task-update path) now refuses to flip a parent to completed if any child is not yet completed — it returns a blocked result listing the open children, and the CLI prints a clean "Can't complete <id>: N subtask(s) still open" message instead of silently corrupting the tree. Standalone tasks and completing the last open child (which removes the whole plan) are unchanged. Prevents the inflated-count drift where parents showed done over still-open children.
|
|
5
8
|
|
package/core/scheduler.js
CHANGED
|
@@ -106,7 +106,10 @@ async function fireJob(job, retry = 0) {
|
|
|
106
106
|
|
|
107
107
|
const { runClaude } = require("./runner");
|
|
108
108
|
const runOpts = {};
|
|
109
|
-
|
|
109
|
+
// Join the channel's live conversation. Only fall back to the wakeup's
|
|
110
|
+
// frozen sessionId when there's no live pointer (cold start) — otherwise
|
|
111
|
+
// a stale, compacted-away id would yank the channel onto a dead thread.
|
|
112
|
+
if (!state.lastSessionId && job.sessionId) runOpts.resumeSessionId = job.sessionId;
|
|
110
113
|
try {
|
|
111
114
|
await runClaude(wrappedPrompt, cwd, null, runOpts);
|
|
112
115
|
jobs.update(job.id, { lastFireAt: Date.now(), lastFireOk: true });
|
package/core/system-prompt.js
CHANGED
|
@@ -317,22 +317,6 @@ function formatPackForContext(pack, packsLib) {
|
|
|
317
317
|
return clip(parts.join("\n\n"), PACK_INJECT_MAX_CHARS);
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
// Compact anchor re-injected on later turns of the same session: the full
|
|
321
|
-
// pack was already shown once, but compaction can silently drop it from
|
|
322
|
-
// the rolling context, leaving a recall hole. A short Stance+State+latest
|
|
323
|
-
// reminder keeps the pack "present" without re-paying the full token cost.
|
|
324
|
-
function formatPackCompact(pack) {
|
|
325
|
-
const clip = (s, n) => (s.length > n ? s.slice(0, n) + "\n…[truncated]" : s);
|
|
326
|
-
const parts = [`### Pack: ${pack.name} (${pack.dir}) — recalled (full version shown earlier this session; read PACK.md for detail)`];
|
|
327
|
-
const stance = (pack.sections.Stance || "").trim();
|
|
328
|
-
if (stance) parts.push(`#### Stance\n${stance}`);
|
|
329
|
-
const state = (pack.sections.State || "").trim();
|
|
330
|
-
if (state) parts.push(`#### State\n${state}`);
|
|
331
|
-
const journal = (pack.sections.Journal || "").trim().split("\n").filter(Boolean).slice(-1).join("\n");
|
|
332
|
-
if (journal) parts.push(`#### Journal (latest)\n${journal}`);
|
|
333
|
-
return clip(parts.join("\n\n"), 1200);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
320
|
function buildPackBlock(matches) {
|
|
337
321
|
try {
|
|
338
322
|
const packsLib = require("./packs");
|
|
@@ -349,14 +333,14 @@ function buildPackBlock(matches) {
|
|
|
349
333
|
used.push(m.dir);
|
|
350
334
|
const key = `${adapter?.id || "?"}:${channelId || "?"}:${m.dir}`;
|
|
351
335
|
const stamp = `${sess}:${pack.updated}`;
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
336
|
+
// Inject a pack's full body once per (channel, session, version). A
|
|
337
|
+
// compaction mints a new session id, which changes the stamp and
|
|
338
|
+
// forces a fresh full re-injection on the next turn (same mechanism
|
|
339
|
+
// as the task tree), so the pack survives compaction without paying
|
|
340
|
+
// to re-stamp an anchor on every intervening turn.
|
|
341
|
+
if (packsInjectedFor.get(key) === stamp) continue;
|
|
359
342
|
packsInjectedFor.set(key, stamp);
|
|
343
|
+
lastInjected.packs.push(pack.name || m.dir);
|
|
360
344
|
blocks.push(formatPackForContext(pack, packsLib));
|
|
361
345
|
}
|
|
362
346
|
if (used.length > 0) setImmediate(() => { try { packsLib.touchUsed(used); } catch (e) {} });
|
package/package.json
CHANGED