flavor-code 1.3.16 → 1.3.18
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/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/{app-6SEGTMMC.js → app-LKK5RBTO.js} +77 -6
- package/dist/{chunk-F2HMO5Q2.js → chunk-36UKDXPF.js} +9 -1
- package/dist/{chunk-LMFN2QEA.js → chunk-6LDYDQ3P.js} +1 -1
- package/dist/{chunk-S525EOFQ.js → chunk-PF457XCH.js} +89 -34
- package/dist/{claude-ink-ORUA7GWG.js → claude-ink-AUZBJ3BE.js} +1 -1
- package/dist/cli-main.js +4 -4
- package/dist/cli.js +7 -21
- package/dist/desktop/main.js +89 -34
- package/dist/desktop-renderer/assets/index-CxOMqdQf.js +154 -0
- package/dist/desktop-renderer/assets/{interactive-terminal-f1PNniPO.js → interactive-terminal-BK8GS4b3.js} +1 -1
- package/dist/desktop-renderer/index.html +1 -1
- package/dist/sdk/index.js +2 -2
- package/dist/session/tree.d.ts +3 -0
- package/dist/ui/transcript.d.ts +7 -0
- package/dist/utils/memory-restart.d.ts +3 -2
- package/package.json +2 -1
- package/dist/desktop-renderer/assets/index-C3JpD2_B.js +0 -154
package/dist/desktop/main.js
CHANGED
|
@@ -5507,9 +5507,8 @@ var ContextManager = class _ContextManager {
|
|
|
5507
5507
|
const currentStableHash = currentStable === void 0 ? this.#epoch.stableSourceHash : hashMessages(currentStable);
|
|
5508
5508
|
if (currentStable !== void 0 && currentStableHash !== this.#epoch.stableSourceHash) {
|
|
5509
5509
|
const value = currentStable.map((message2) => message2.content).join("\n\n");
|
|
5510
|
-
const previous = this.#epoch.sources["system-baseline"] ?? this.#epoch.stableMessages.map((message2) => message2.content).join("\n\n");
|
|
5511
5510
|
if (this.#epoch.sources["system-baseline"] !== value) {
|
|
5512
|
-
updates.push(contextUpdateMessage("system-baseline",
|
|
5511
|
+
updates.push(contextUpdateMessage("system-baseline", value));
|
|
5513
5512
|
this.#epoch.sources["system-baseline"] = value;
|
|
5514
5513
|
}
|
|
5515
5514
|
} else if (currentStable !== void 0 && this.#epoch.sources["system-baseline"] !== void 0) {
|
|
@@ -5530,8 +5529,6 @@ var ContextManager = class _ContextManager {
|
|
|
5530
5529
|
}
|
|
5531
5530
|
if (updates.length === 0) return false;
|
|
5532
5531
|
this.#messages.push(...updates);
|
|
5533
|
-
this.#lastRecordedInputTokens = void 0;
|
|
5534
|
-
this.#estimatedTokensAtLastRecordedUsage = void 0;
|
|
5535
5532
|
return true;
|
|
5536
5533
|
}
|
|
5537
5534
|
snapshot() {
|
|
@@ -5591,10 +5588,7 @@ var ContextManager = class _ContextManager {
|
|
|
5591
5588
|
async prepareForModelCall(signal = new AbortController().signal) {
|
|
5592
5589
|
signal.throwIfAborted();
|
|
5593
5590
|
this.refreshContextSources();
|
|
5594
|
-
|
|
5595
|
-
this.#lastRecordedInputTokens = void 0;
|
|
5596
|
-
this.#estimatedTokensAtLastRecordedUsage = void 0;
|
|
5597
|
-
}
|
|
5591
|
+
this.#dropStaleContextUpdates();
|
|
5598
5592
|
if (!this.needsCompaction()) return false;
|
|
5599
5593
|
const originalMessages = this.#messages;
|
|
5600
5594
|
const originalRecordedUsage = this.#lastRecordedInputTokens;
|
|
@@ -5607,8 +5601,6 @@ var ContextManager = class _ContextManager {
|
|
|
5607
5601
|
const microcompact = microcompactMessages(this.#messages, this.#compaction.microcompactKeepRecentToolResults);
|
|
5608
5602
|
if (microcompact.changed) {
|
|
5609
5603
|
this.#messages = microcompact.messages;
|
|
5610
|
-
this.#lastRecordedInputTokens = void 0;
|
|
5611
|
-
this.#estimatedTokensAtLastRecordedUsage = void 0;
|
|
5612
5604
|
}
|
|
5613
5605
|
if (!this.needsCompaction()) {
|
|
5614
5606
|
if (microcompact.changed) {
|
|
@@ -6572,7 +6564,7 @@ function memoryPressureError(heapUsed, heapLimit) {
|
|
|
6572
6564
|
const mb = (bytes) => Math.round(bytes / 1048576);
|
|
6573
6565
|
return {
|
|
6574
6566
|
code: "memory_pressure",
|
|
6575
|
-
message: `Heap usage reached ${Math.round(heapUsed / heapLimit * 100)}% of the V8 limit (${mb(heapUsed)}MB of ${mb(heapLimit)}MB); stopping to avoid a crash. The
|
|
6567
|
+
message: `Heap usage reached ${Math.round(heapUsed / heapLimit * 100)}% of the V8 limit (${mb(heapUsed)}MB of ${mb(heapLimit)}MB); stopping the current turn to avoid a crash. The saved session will reopen after restart.`
|
|
6576
6568
|
};
|
|
6577
6569
|
}
|
|
6578
6570
|
function currentMemoryPressure() {
|
|
@@ -6692,6 +6684,11 @@ var AgentLoop = class {
|
|
|
6692
6684
|
yield { type: "error", error: normalizeProviderError(error) };
|
|
6693
6685
|
return;
|
|
6694
6686
|
}
|
|
6687
|
+
const preparedPressure = currentMemoryPressure();
|
|
6688
|
+
if (preparedPressure !== void 0) {
|
|
6689
|
+
yield { type: "error", error: preparedPressure };
|
|
6690
|
+
return;
|
|
6691
|
+
}
|
|
6695
6692
|
let assistantText = "";
|
|
6696
6693
|
const collectedToolCalls = [];
|
|
6697
6694
|
const collectedThinking = [];
|
|
@@ -6715,6 +6712,11 @@ var AgentLoop = class {
|
|
|
6715
6712
|
tools: [...this.#options.tools],
|
|
6716
6713
|
...request.signal === void 0 ? {} : { signal: request.signal }
|
|
6717
6714
|
};
|
|
6715
|
+
const requestPressure = currentMemoryPressure();
|
|
6716
|
+
if (requestPressure !== void 0) {
|
|
6717
|
+
yield { type: "error", error: requestPressure };
|
|
6718
|
+
return;
|
|
6719
|
+
}
|
|
6718
6720
|
let before;
|
|
6719
6721
|
try {
|
|
6720
6722
|
before = await this.#options.hooks.emit({
|
|
@@ -15501,6 +15503,8 @@ function appendThinkingText(previous, delta) {
|
|
|
15501
15503
|
}
|
|
15502
15504
|
|
|
15503
15505
|
// src/ui/transcript.ts
|
|
15506
|
+
var MAX_TRANSCRIPT_TURNS = 200;
|
|
15507
|
+
var MAX_TRANSCRIPT_CHARS = 2e6;
|
|
15504
15508
|
function createTranscriptState() {
|
|
15505
15509
|
return { completed: [], nextId: 1 };
|
|
15506
15510
|
}
|
|
@@ -15797,7 +15801,7 @@ function hydrateHistory(messages, compact) {
|
|
|
15797
15801
|
}
|
|
15798
15802
|
}
|
|
15799
15803
|
if (turn !== void 0) completed.push(turn);
|
|
15800
|
-
return { completed, nextId: completed.length + 1 };
|
|
15804
|
+
return { completed: boundedCompleted(completed), nextId: completed.length + 1 };
|
|
15801
15805
|
}
|
|
15802
15806
|
function transcriptFromLegacyConversation(messages, compact) {
|
|
15803
15807
|
return hydrateHistory(messages, compact);
|
|
@@ -15891,10 +15895,10 @@ function finishActive(state) {
|
|
|
15891
15895
|
if (state.active === void 0) return state;
|
|
15892
15896
|
const active = withoutModelActivity(state.active);
|
|
15893
15897
|
return {
|
|
15894
|
-
completed: [...state.completed, {
|
|
15898
|
+
completed: boundedCompleted([...state.completed, {
|
|
15895
15899
|
...active,
|
|
15896
15900
|
completedAt: active.completedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
15897
|
-
}],
|
|
15901
|
+
}]),
|
|
15898
15902
|
nextId: state.nextId,
|
|
15899
15903
|
...state.taskSnapshot === void 0 ? {} : { taskSnapshot: state.taskSnapshot }
|
|
15900
15904
|
};
|
|
@@ -15923,12 +15927,26 @@ function withoutModelActivity(turn, id) {
|
|
|
15923
15927
|
function restoreTranscriptState(state) {
|
|
15924
15928
|
const completed = state.completed.map(cloneTurn);
|
|
15925
15929
|
if (state.active !== void 0) completed.push(normalizeInterruptedTurn(cloneTurn(state.active)));
|
|
15930
|
+
const nextId = Math.max(state.nextId, ...completed.map((turn) => turn.id + 1), 1);
|
|
15926
15931
|
return {
|
|
15927
|
-
completed,
|
|
15928
|
-
nextId
|
|
15932
|
+
completed: boundedCompleted(completed),
|
|
15933
|
+
nextId,
|
|
15929
15934
|
...state.taskSnapshot === void 0 ? {} : { taskSnapshot: state.taskSnapshot }
|
|
15930
15935
|
};
|
|
15931
15936
|
}
|
|
15937
|
+
function boundedCompleted(input) {
|
|
15938
|
+
const recent = input.slice(-MAX_TRANSCRIPT_TURNS);
|
|
15939
|
+
let chars = 0;
|
|
15940
|
+
let start = recent.length;
|
|
15941
|
+
for (let index = recent.length - 1; index >= 0; index -= 1) {
|
|
15942
|
+
const turn = recent[index];
|
|
15943
|
+
const size = JSON.stringify(turn).length;
|
|
15944
|
+
if (start < recent.length && chars + size > MAX_TRANSCRIPT_CHARS) break;
|
|
15945
|
+
chars += size;
|
|
15946
|
+
start = index;
|
|
15947
|
+
}
|
|
15948
|
+
return recent.slice(start);
|
|
15949
|
+
}
|
|
15932
15950
|
function compactionTurn(compact) {
|
|
15933
15951
|
const text = `Original execution steps before ${compact.compactedAt} are unavailable.`;
|
|
15934
15952
|
return {
|
|
@@ -16752,6 +16770,8 @@ function isCode9(error, code) {
|
|
|
16752
16770
|
}
|
|
16753
16771
|
|
|
16754
16772
|
// src/session/tree.ts
|
|
16773
|
+
var MAX_SESSION_HISTORY_NODES = 100;
|
|
16774
|
+
var MAX_SESSION_HISTORY_CONTEXT_CHARS = 2e6;
|
|
16755
16775
|
var SessionHistory = class _SessionHistory {
|
|
16756
16776
|
#path;
|
|
16757
16777
|
#checkpoints;
|
|
@@ -16763,8 +16783,8 @@ var SessionHistory = class _SessionHistory {
|
|
|
16763
16783
|
this.#path = join25(resolve21(options.workspace), ".flavor", "session-trees", options.sessionId, "tree.json");
|
|
16764
16784
|
this.#checkpoints = new WorkspaceCheckpointStore({ workspace: options.workspace });
|
|
16765
16785
|
this.#restoreContext = options.restoreContext;
|
|
16766
|
-
this.#nodes = document.nodes;
|
|
16767
|
-
this.#leafId = document.leafId;
|
|
16786
|
+
this.#nodes = boundedNodes(document.nodes);
|
|
16787
|
+
this.#leafId = document.leafId !== null && this.#nodes.some((node) => node.id === document.leafId) ? document.leafId : this.#nodes.at(-1)?.id ?? null;
|
|
16768
16788
|
}
|
|
16769
16789
|
static async open(options) {
|
|
16770
16790
|
const path = join25(resolve21(options.workspace), ".flavor", "session-trees", options.sessionId, "tree.json");
|
|
@@ -16776,7 +16796,9 @@ var SessionHistory = class _SessionHistory {
|
|
|
16776
16796
|
} catch (error) {
|
|
16777
16797
|
if (!isCode10(error, "ENOENT")) throw error;
|
|
16778
16798
|
}
|
|
16779
|
-
|
|
16799
|
+
const history = new _SessionHistory(options, document);
|
|
16800
|
+
if (history.#nodes.length !== document.nodes.length) await history.#persist();
|
|
16801
|
+
return history;
|
|
16780
16802
|
}
|
|
16781
16803
|
get leafId() {
|
|
16782
16804
|
return this.#leafId;
|
|
@@ -16796,6 +16818,7 @@ var SessionHistory = class _SessionHistory {
|
|
|
16796
16818
|
};
|
|
16797
16819
|
this.#nodes.push(node);
|
|
16798
16820
|
this.#leafId = node.id;
|
|
16821
|
+
this.#boundNodes();
|
|
16799
16822
|
await this.#persist();
|
|
16800
16823
|
return structuredClone(node);
|
|
16801
16824
|
}
|
|
@@ -16837,6 +16860,13 @@ var SessionHistory = class _SessionHistory {
|
|
|
16837
16860
|
if (node === void 0) throw new Error(`Unknown session tree node: ${id}`);
|
|
16838
16861
|
return node;
|
|
16839
16862
|
}
|
|
16863
|
+
#boundNodes() {
|
|
16864
|
+
const bounded2 = boundedNodes(this.#nodes);
|
|
16865
|
+
this.#nodes.splice(0, this.#nodes.length, ...bounded2);
|
|
16866
|
+
if (this.#leafId !== null && !this.#nodes.some((node) => node.id === this.#leafId)) {
|
|
16867
|
+
this.#leafId = this.#nodes.at(-1)?.id ?? null;
|
|
16868
|
+
}
|
|
16869
|
+
}
|
|
16840
16870
|
async #persist() {
|
|
16841
16871
|
const document = {
|
|
16842
16872
|
version: 1,
|
|
@@ -16851,6 +16881,24 @@ var SessionHistory = class _SessionHistory {
|
|
|
16851
16881
|
await rename8(temporary, this.#path);
|
|
16852
16882
|
}
|
|
16853
16883
|
};
|
|
16884
|
+
function boundedNodes(input) {
|
|
16885
|
+
const recent = input.slice(-MAX_SESSION_HISTORY_NODES);
|
|
16886
|
+
let contextChars = 0;
|
|
16887
|
+
let start = recent.length;
|
|
16888
|
+
for (let index = recent.length - 1; index >= 0; index -= 1) {
|
|
16889
|
+
const node = recent[index];
|
|
16890
|
+
const size = JSON.stringify(node.context).length;
|
|
16891
|
+
if (start < recent.length && contextChars + size > MAX_SESSION_HISTORY_CONTEXT_CHARS) break;
|
|
16892
|
+
contextChars += size;
|
|
16893
|
+
start = index;
|
|
16894
|
+
}
|
|
16895
|
+
const retained = recent.slice(start).map((node) => structuredClone(node));
|
|
16896
|
+
const ids = new Set(retained.map((node) => node.id));
|
|
16897
|
+
for (const node of retained) {
|
|
16898
|
+
if (node.parentId !== null && !ids.has(node.parentId)) node.parentId = null;
|
|
16899
|
+
}
|
|
16900
|
+
return retained;
|
|
16901
|
+
}
|
|
16854
16902
|
function validate(value, sessionId) {
|
|
16855
16903
|
if (value.version !== 1 || value.sessionId !== sessionId || !Array.isArray(value.nodes)) {
|
|
16856
16904
|
throw new Error("Invalid session tree");
|
|
@@ -21248,6 +21296,7 @@ var HELP = [
|
|
|
21248
21296
|
"/chat <alias-or-uuid> <goal> send a task that starts on the receiving pal",
|
|
21249
21297
|
"/co-work <pal> <goal> | status [id] | cancel <id> [reason]"
|
|
21250
21298
|
].join("\n");
|
|
21299
|
+
var MAX_STOP_DENIALS = 2;
|
|
21251
21300
|
var FlavorSession = class {
|
|
21252
21301
|
#services;
|
|
21253
21302
|
#active;
|
|
@@ -21258,6 +21307,7 @@ var FlavorSession = class {
|
|
|
21258
21307
|
#submissionTail = Promise.resolve();
|
|
21259
21308
|
#coWorkEventTail = Promise.resolve();
|
|
21260
21309
|
#pendingSubmissions = 0;
|
|
21310
|
+
#stopDenials = 0;
|
|
21261
21311
|
#closePromise;
|
|
21262
21312
|
#queue = new AgentMessageQueue();
|
|
21263
21313
|
#queuedSubmissions = { steer: [], followUp: [] };
|
|
@@ -21459,6 +21509,7 @@ var FlavorSession = class {
|
|
|
21459
21509
|
return operation;
|
|
21460
21510
|
}
|
|
21461
21511
|
async #runSubmissionChain(initialSubmission) {
|
|
21512
|
+
this.#stopDenials = 0;
|
|
21462
21513
|
const pending2 = [initialSubmission];
|
|
21463
21514
|
let initial = true;
|
|
21464
21515
|
while (pending2.length > 0) {
|
|
@@ -21552,8 +21603,9 @@ var FlavorSession = class {
|
|
|
21552
21603
|
this.#active = void 0;
|
|
21553
21604
|
this.#activeSubmission = void 0;
|
|
21554
21605
|
if (submission.coWorkPlanningKey !== void 0) this.#finishActivePlanning(submission.coWorkPlanningKey);
|
|
21606
|
+
let stopDecision;
|
|
21555
21607
|
try {
|
|
21556
|
-
await this.#services.hooks.emit({
|
|
21608
|
+
stopDecision = await this.#services.hooks.emit({
|
|
21557
21609
|
version: 1,
|
|
21558
21610
|
type: "Stop",
|
|
21559
21611
|
payload: {
|
|
@@ -21568,6 +21620,21 @@ var FlavorSession = class {
|
|
|
21568
21620
|
} catch {
|
|
21569
21621
|
}
|
|
21570
21622
|
}
|
|
21623
|
+
try {
|
|
21624
|
+
if (stopDecision?.decision === "deny" && typeof stopDecision.reason === "string" && stopDecision.reason.length > 0 && !this.#closed && outcome !== "cancelled" && outcome !== "denied") {
|
|
21625
|
+
if (this.#stopDenials < MAX_STOP_DENIALS) {
|
|
21626
|
+
this.#stopDenials += 1;
|
|
21627
|
+
const text = `[stop-guard] A Stop hook vetoed ending this turn (continuation ${this.#stopDenials}/${MAX_STOP_DENIALS}). It reported:
|
|
21628
|
+
${stopDecision.reason}
|
|
21629
|
+
Address this now (for example run the required verification or fix), then finish.`;
|
|
21630
|
+
this.#enqueueMessage("followUp", { text, displayText: text });
|
|
21631
|
+
this.#notice(`Stop hook requested continuation (${this.#stopDenials}/${MAX_STOP_DENIALS}).`);
|
|
21632
|
+
} else {
|
|
21633
|
+
this.#notice("Stop hook kept vetoing after the continuation budget; ending the turn anyway.");
|
|
21634
|
+
}
|
|
21635
|
+
}
|
|
21636
|
+
} catch {
|
|
21637
|
+
}
|
|
21571
21638
|
this.#ackDurable(submission);
|
|
21572
21639
|
this.#ackActiveSteering();
|
|
21573
21640
|
}
|
|
@@ -26325,7 +26392,7 @@ async function createProductionRuntime(options) {
|
|
|
26325
26392
|
contextEpoch: harness.main.context.snapshot().epoch?.id ?? "legacy"
|
|
26326
26393
|
});
|
|
26327
26394
|
const turnId = harnessJournal.startTurn(turnConfig, { prompt, initialUserMessage: runOptions?.initialUserMessage });
|
|
26328
|
-
return monitorMemoryRestart(durableTurn(
|
|
26395
|
+
return monitorMemoryRestart(durableTurn(persistAfter(runMain(
|
|
26329
26396
|
harness,
|
|
26330
26397
|
skills,
|
|
26331
26398
|
prompt,
|
|
@@ -26341,11 +26408,7 @@ async function createProductionRuntime(options) {
|
|
|
26341
26408
|
runOptions?.initialUserMessage,
|
|
26342
26409
|
runOptions?.additionalContext,
|
|
26343
26410
|
ide
|
|
26344
|
-
), persist, () =>
|
|
26345
|
-
prompt,
|
|
26346
|
-
context: harness.main.context.snapshot(),
|
|
26347
|
-
label: `turn: ${prompt.slice(0, 80)}`
|
|
26348
|
-
})), harnessJournal, turnId, turnConfig), () => requestMemoryRestart(workspace, sessionId, emitOutput));
|
|
26411
|
+
), persist), harnessJournal, turnId, turnConfig), () => requestMemoryRestart(workspace, sessionId, emitOutput));
|
|
26349
26412
|
},
|
|
26350
26413
|
runSkill: (skill, prompt, signal) => persistAfter(
|
|
26351
26414
|
runExplicitSkill(harness, skills, skill, prompt, signal, selectedModels.mainError),
|
|
@@ -27055,14 +27118,6 @@ async function* persistAfter(source, persist) {
|
|
|
27055
27118
|
await persist();
|
|
27056
27119
|
}
|
|
27057
27120
|
}
|
|
27058
|
-
async function* persistAndCheckpointAfter(source, persist, checkpoint) {
|
|
27059
|
-
try {
|
|
27060
|
-
for await (const item of source) yield item;
|
|
27061
|
-
await checkpoint();
|
|
27062
|
-
} finally {
|
|
27063
|
-
await persist();
|
|
27064
|
-
}
|
|
27065
|
-
}
|
|
27066
27121
|
async function* persistEach(source, persist) {
|
|
27067
27122
|
try {
|
|
27068
27123
|
for await (const item of source) {
|