portable-agent-layer 0.45.0 → 0.45.1
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/package.json
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-trigger for self-model synthesis — runs daily.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Spawns synthesis as a DETACHED child instead of awaiting it inline. A cold
|
|
5
|
+
* `claude -p` Sonnet spawn routinely exceeds a minute; awaiting it inside the
|
|
6
|
+
* Stop hook forced a tight 30s timeout that killed every synthesis and fell
|
|
7
|
+
* back to a raw data dump. Detaching lets self-model.ts use a real 90s budget
|
|
8
|
+
* without blocking session end. self-model.ts carries its own 24h TTL guard,
|
|
9
|
+
* so this is safe to call every session. Respects dynamicContext.selfModel.
|
|
5
10
|
*/
|
|
6
11
|
|
|
7
|
-
import {
|
|
12
|
+
import { resolve } from "node:path";
|
|
13
|
+
import { spawnDetachedInference } from "../lib/detached-inference";
|
|
8
14
|
import { logDebug } from "../lib/log";
|
|
15
|
+
import { assets } from "../lib/paths";
|
|
9
16
|
import { isEnabled } from "../lib/settings";
|
|
10
17
|
|
|
11
|
-
export
|
|
18
|
+
export function checkSelfModelTrigger(): void {
|
|
12
19
|
if (!isEnabled("selfModel")) {
|
|
13
20
|
logDebug("self-model-trigger", "Disabled in pal-settings.json");
|
|
14
21
|
return;
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (result.skipped) {
|
|
20
|
-
logDebug("self-model-trigger", "Skipped — last synthesis < 24h ago");
|
|
21
|
-
} else {
|
|
22
|
-
logDebug("self-model-trigger", `Self-model written: ${result.path}`);
|
|
23
|
-
}
|
|
24
|
-
} catch {
|
|
25
|
-
// Non-critical — self-model is best-effort
|
|
26
|
-
}
|
|
24
|
+
const scriptPath = resolve(assets.tools(), "self-model.ts");
|
|
25
|
+
spawnDetachedInference(scriptPath, [], "self-model");
|
|
27
26
|
}
|
package/src/hooks/lib/paths.ts
CHANGED
|
@@ -83,5 +83,6 @@ export const assets = {
|
|
|
83
83
|
codexHooksTemplate: () => pkg("assets", "templates", "hooks.codex.json"),
|
|
84
84
|
codexRulesTemplate: () => pkg("assets", "templates", "rules.codex.rules"),
|
|
85
85
|
agentTools: () => pkg("src", "tools", "agent"),
|
|
86
|
+
tools: () => pkg("src", "tools"),
|
|
86
87
|
palDocs: () => pkg("assets", "templates", "PAL"),
|
|
87
88
|
} as const;
|
package/src/hooks/lib/stop.ts
CHANGED
|
@@ -47,11 +47,12 @@ export async function runStopHandlers(
|
|
|
47
47
|
// Detach inference-bearing handlers — claude --print cold-start can exceed
|
|
48
48
|
// any in-hook budget. These spawn detached bun subprocesses that run the
|
|
49
49
|
// inference and write results to disk; they don't block this hook.
|
|
50
|
-
// autoGraduate is idempotent (24h TTL + state-dedup + content-dedup), so
|
|
51
|
-
// concurrent or overlapping detached runs are safe.
|
|
52
50
|
await detachSessionIntelligence(transcript, options.sessionId);
|
|
53
51
|
await detachFailurePrinciple(transcript);
|
|
54
|
-
|
|
52
|
+
// Failure auto-graduation is intentionally NOT wired here: every pattern it
|
|
53
|
+
// ever promoted was a frustration log, not a principle. Wisdom frames are
|
|
54
|
+
// populated by Claude in-conversation (see wisdom.ts header). The handler
|
|
55
|
+
// (handlers/auto-graduate.ts) remains runnable manually via `--run`.
|
|
55
56
|
|
|
56
57
|
// Run remaining (non-inference) handlers concurrently.
|
|
57
58
|
// project-touch only fires when cwd resolves to an active registered project.
|
|
@@ -177,16 +178,6 @@ async function detachSessionIntelligence(
|
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
/** Spawn a detached child to run the full autoGraduate cycle. */
|
|
181
|
-
function detachAutoGraduate(): void {
|
|
182
|
-
try {
|
|
183
|
-
const scriptPath = resolve(assets.hooks(), "handlers", "auto-graduate.ts");
|
|
184
|
-
spawnDetachedInference(scriptPath, ["--run"], "auto-graduate");
|
|
185
|
-
} catch (err) {
|
|
186
|
-
logError("detachAutoGraduate", err);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
181
|
/**
|
|
191
182
|
* If a pending-failure exists, rename it to a unique path (race-free claim),
|
|
192
183
|
* write the transcript to tmp, spawn the failure-principle handler detached.
|
package/src/tools/self-model.ts
CHANGED
|
@@ -524,7 +524,11 @@ async function composeSelfModel(days: number): Promise<string> {
|
|
|
524
524
|
const currentPath = selfModelPath();
|
|
525
525
|
if (existsSync(currentPath)) {
|
|
526
526
|
try {
|
|
527
|
-
|
|
527
|
+
const prev = readFileSync(currentPath, "utf-8");
|
|
528
|
+
// Never feed a failed-synthesis fallback back in — it is a raw data dump,
|
|
529
|
+
// not a model. Doing so bloats the prompt and drives the next run into the
|
|
530
|
+
// same timeout, a self-reinforcing failure loop. Skip it and synthesize fresh.
|
|
531
|
+
if (!prev.includes("Synthesis failed — raw data below")) previousModel = prev;
|
|
528
532
|
} catch {
|
|
529
533
|
/* best effort */
|
|
530
534
|
}
|
|
@@ -539,7 +543,7 @@ async function composeSelfModel(days: number): Promise<string> {
|
|
|
539
543
|
user: userContent,
|
|
540
544
|
model: SONNET_MODEL,
|
|
541
545
|
maxTokens: 1500,
|
|
542
|
-
timeout:
|
|
546
|
+
timeout: 90000,
|
|
543
547
|
caller: "self-model",
|
|
544
548
|
});
|
|
545
549
|
|
|
@@ -565,7 +569,7 @@ async function composeSelfModel(days: number): Promise<string> {
|
|
|
565
569
|
|
|
566
570
|
// ── Write ──
|
|
567
571
|
|
|
568
|
-
|
|
572
|
+
async function writeSelfModel(
|
|
569
573
|
days: number,
|
|
570
574
|
force = false
|
|
571
575
|
): Promise<{ path: string; content: string; skipped?: boolean }> {
|