zelari-code 2.8.0 → 2.9.0
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/dist/cli/budget/modelContextBuilder.js +17 -17
- package/dist/cli/budget/modelContextBuilder.js.map +1 -1
- package/dist/cli/budget/resourceSnapshot.js +3 -3
- package/dist/cli/budget/tokenBudget.js +8 -8
- package/dist/cli/budget/tokenBudget.js.map +1 -1
- package/dist/cli/hooks/conversationContext.js +1 -1
- package/dist/cli/hooks/conversationContext.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +7 -2
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/main.bundled.js +340 -149
- package/dist/cli/main.bundled.js.map +3 -3
- package/dist/cli/missionSlice.js +1 -0
- package/dist/cli/missionSlice.js.map +1 -1
- package/dist/cli/provider/capabilities.js +108 -39
- package/dist/cli/provider/capabilities.js.map +1 -1
- package/dist/cli/provider/openai-compatible.js +21 -6
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/runHeadless.js +17 -78
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/sessionSpine.js +1 -1
- package/dist/cli/sessionSpine.js.map +1 -1
- package/dist/cli/tools/taskTool.js +4 -0
- package/dist/cli/tools/taskTool.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -22068,7 +22068,7 @@ function extractToolObjects(text) {
|
|
|
22068
22068
|
}
|
|
22069
22069
|
return out;
|
|
22070
22070
|
}
|
|
22071
|
-
var AgentHarness, DOOM_LOOP_THRESHOLD;
|
|
22071
|
+
var BUILD_LIVENESS_RECOVERY_PROMPT, AgentHarness, DOOM_LOOP_THRESHOLD;
|
|
22072
22072
|
var init_AgentHarness = __esm({
|
|
22073
22073
|
"packages/core/dist/core/AgentHarness.js"() {
|
|
22074
22074
|
"use strict";
|
|
@@ -22079,6 +22079,7 @@ var init_AgentHarness = __esm({
|
|
|
22079
22079
|
init_requestSnapshot();
|
|
22080
22080
|
init_textLoopDetect();
|
|
22081
22081
|
init_textLoopDetect();
|
|
22082
|
+
BUILD_LIVENESS_RECOVERY_PROMPT = "[build-liveness] The requested task requires an on-disk implementation, but no successful project mutation has occurred yet. Continue working. Inspect only as needed, then make the required change with an available mutating tool. Do not merely describe a patch or claim completion.";
|
|
22082
22083
|
AgentHarness = class {
|
|
22083
22084
|
config;
|
|
22084
22085
|
eventBus;
|
|
@@ -22115,6 +22116,13 @@ var init_AgentHarness = __esm({
|
|
|
22115
22116
|
growth = emptyContextGrowthStats();
|
|
22116
22117
|
/** Ephemeral per-run context; never appended to `config.messages`. */
|
|
22117
22118
|
activeMemoryContext = "";
|
|
22119
|
+
buildProgress = {
|
|
22120
|
+
toolCalls: 0,
|
|
22121
|
+
mutationsAttempted: 0,
|
|
22122
|
+
mutationsSucceeded: 0,
|
|
22123
|
+
verificationCalls: 0,
|
|
22124
|
+
recoveries: 0
|
|
22125
|
+
};
|
|
22118
22126
|
constructor(config2) {
|
|
22119
22127
|
this.config = config2;
|
|
22120
22128
|
this.eventBus = config2.eventBus;
|
|
@@ -22145,6 +22153,33 @@ var init_AgentHarness = __esm({
|
|
|
22145
22153
|
getMessages() {
|
|
22146
22154
|
return this.config.messages;
|
|
22147
22155
|
}
|
|
22156
|
+
/** Immutable snapshot of host-observed build progress for this run. */
|
|
22157
|
+
getBuildProgress() {
|
|
22158
|
+
return { ...this.buildProgress };
|
|
22159
|
+
}
|
|
22160
|
+
toolPermissions(toolName) {
|
|
22161
|
+
return this.config.toolRegistry?.get(toolName)?.permissions ?? [];
|
|
22162
|
+
}
|
|
22163
|
+
isMutationTool(toolName, args) {
|
|
22164
|
+
const permissions = this.toolPermissions(toolName);
|
|
22165
|
+
if (!permissions.includes("write"))
|
|
22166
|
+
return false;
|
|
22167
|
+
if (args.dryRun === true)
|
|
22168
|
+
return false;
|
|
22169
|
+
return classifyToolConcurrency({
|
|
22170
|
+
toolName,
|
|
22171
|
+
args,
|
|
22172
|
+
permissions,
|
|
22173
|
+
registered: Boolean(this.config.toolRegistry?.get(toolName))
|
|
22174
|
+
}) === "exclusive";
|
|
22175
|
+
}
|
|
22176
|
+
recordSuccessfulTool(toolName, args) {
|
|
22177
|
+
const permissions = this.toolPermissions(toolName);
|
|
22178
|
+
if (this.isMutationTool(toolName, args))
|
|
22179
|
+
this.buildProgress.mutationsSucceeded += 1;
|
|
22180
|
+
if (permissions.includes("execute"))
|
|
22181
|
+
this.buildProgress.verificationCalls += 1;
|
|
22182
|
+
}
|
|
22148
22183
|
/**
|
|
22149
22184
|
* Member identity fields (memberId + memberName) to merge into every
|
|
22150
22185
|
* event payload. Returns an empty object when the run is a direct
|
|
@@ -22386,6 +22421,13 @@ ${shared2.content}`,
|
|
|
22386
22421
|
this.toolCallCounts = /* @__PURE__ */ new Map();
|
|
22387
22422
|
this.textToolReentries = 0;
|
|
22388
22423
|
this.growth = emptyContextGrowthStats();
|
|
22424
|
+
this.buildProgress = {
|
|
22425
|
+
toolCalls: 0,
|
|
22426
|
+
mutationsAttempted: 0,
|
|
22427
|
+
mutationsSucceeded: 0,
|
|
22428
|
+
verificationCalls: 0,
|
|
22429
|
+
recoveries: 0
|
|
22430
|
+
};
|
|
22389
22431
|
const memoryWarning = await this.prepareMemoryContext();
|
|
22390
22432
|
const startEvent = createBrainEvent("agent_start", this.sessionId, {
|
|
22391
22433
|
model: this.config.model,
|
|
@@ -22410,7 +22452,11 @@ ${shared2.content}`,
|
|
|
22410
22452
|
this.emit(initialMsgStart);
|
|
22411
22453
|
yield initialMsgStart;
|
|
22412
22454
|
let initialTurnLength = 0;
|
|
22413
|
-
const initialFinishRef = {
|
|
22455
|
+
const initialFinishRef = {
|
|
22456
|
+
value: "stop",
|
|
22457
|
+
clarificationRequested: false,
|
|
22458
|
+
providerError: false
|
|
22459
|
+
};
|
|
22414
22460
|
const initialUsageRef = { value: null };
|
|
22415
22461
|
for await (const ev of this.runSingleTurn(initialMessageId, initialFinishRef, initialUsageRef)) {
|
|
22416
22462
|
if (ev.type === "message_delta") {
|
|
@@ -22437,16 +22483,51 @@ ${shared2.content}`,
|
|
|
22437
22483
|
const hardCap = this.maxToolLoopHardCap;
|
|
22438
22484
|
let extensions = 0;
|
|
22439
22485
|
const maxExtensions = 8;
|
|
22440
|
-
|
|
22486
|
+
const maxBuildRecoveries = Math.max(0, Math.min(10, this.config.buildLiveness?.maxRecoveries ?? 2));
|
|
22487
|
+
const planBuildRecovery = (turn) => {
|
|
22488
|
+
if (!this.config.buildLiveness?.mutationRequired)
|
|
22489
|
+
return null;
|
|
22490
|
+
if (this.buildProgress.mutationsSucceeded > 0)
|
|
22491
|
+
return null;
|
|
22492
|
+
if (turn.value !== "stop" || turn.clarificationRequested || turn.providerError)
|
|
22493
|
+
return null;
|
|
22494
|
+
if (this.buildProgress.recoveries >= maxBuildRecoveries)
|
|
22495
|
+
return null;
|
|
22496
|
+
this.buildProgress.recoveries += 1;
|
|
22497
|
+
this.config.messages.push({ role: "user", content: BUILD_LIVENESS_RECOVERY_PROMPT });
|
|
22498
|
+
return {
|
|
22499
|
+
purpose: "build-recovery",
|
|
22500
|
+
toolChoice: "required",
|
|
22501
|
+
recoveryAttempt: this.buildProgress.recoveries
|
|
22502
|
+
};
|
|
22503
|
+
};
|
|
22504
|
+
let lastTurnState = initialFinishRef;
|
|
22505
|
+
let recoveryGeneration = planBuildRecovery(initialFinishRef);
|
|
22506
|
+
while (!this.cancelled && !hadError && toolLoopTurns < hardCap && (toolLoopTurns < softCap || recoveryGeneration !== null) && (initialFinishRef.value === "tool_calls" || recoveryGeneration !== null)) {
|
|
22441
22507
|
toolLoopTurns++;
|
|
22508
|
+
if (recoveryGeneration) {
|
|
22509
|
+
const recoveryEvent = createBrainEvent("error", this.sessionId, {
|
|
22510
|
+
severity: "recoverable",
|
|
22511
|
+
message: `BUILD liveness recovery ${recoveryGeneration.recoveryAttempt}/${maxBuildRecoveries}: no successful mutation observed; continuing instead of completing.`,
|
|
22512
|
+
code: "build_liveness_recovery"
|
|
22513
|
+
});
|
|
22514
|
+
this.emit(recoveryEvent);
|
|
22515
|
+
yield recoveryEvent;
|
|
22516
|
+
}
|
|
22442
22517
|
const turnMessageId = crypto.randomUUID();
|
|
22443
22518
|
const msgStart = createBrainEvent("message_start", this.sessionId, { messageId: turnMessageId, role: "assistant", ...this.memberFields() });
|
|
22444
22519
|
this.emit(msgStart);
|
|
22445
22520
|
yield msgStart;
|
|
22446
22521
|
let turnLength = 0;
|
|
22447
|
-
const turnFinishRef = {
|
|
22522
|
+
const turnFinishRef = {
|
|
22523
|
+
value: "stop",
|
|
22524
|
+
clarificationRequested: false,
|
|
22525
|
+
providerError: false
|
|
22526
|
+
};
|
|
22448
22527
|
const turnUsageRef = { value: null };
|
|
22449
|
-
|
|
22528
|
+
const generation = recoveryGeneration ?? void 0;
|
|
22529
|
+
recoveryGeneration = null;
|
|
22530
|
+
for await (const ev of this.runSingleTurn(turnMessageId, turnFinishRef, turnUsageRef, generation)) {
|
|
22450
22531
|
if (ev.type === "message_delta") {
|
|
22451
22532
|
turnLength += ev.delta.length;
|
|
22452
22533
|
} else if (ev.type === "error") {
|
|
@@ -22466,6 +22547,10 @@ ${shared2.content}`,
|
|
|
22466
22547
|
this.emit(msgEnd);
|
|
22467
22548
|
yield msgEnd;
|
|
22468
22549
|
initialFinishRef.value = turnFinishRef.value;
|
|
22550
|
+
initialFinishRef.clarificationRequested = turnFinishRef.clarificationRequested;
|
|
22551
|
+
initialFinishRef.providerError = turnFinishRef.providerError;
|
|
22552
|
+
lastTurnState = turnFinishRef;
|
|
22553
|
+
recoveryGeneration = planBuildRecovery(turnFinishRef);
|
|
22469
22554
|
if (hadError || this.cancelled)
|
|
22470
22555
|
break;
|
|
22471
22556
|
if (initialFinishRef.value === "tool_calls" && toolLoopTurns >= softCap && toolLoopTurns < hardCap && extensions < maxExtensions) {
|
|
@@ -22489,10 +22574,23 @@ ${shared2.content}`,
|
|
|
22489
22574
|
if (!this.cancelled && !hadError && initialFinishRef.value === "tool_calls" && hitHardCap) {
|
|
22490
22575
|
yield* this.runFinalAnswerTurn();
|
|
22491
22576
|
}
|
|
22577
|
+
if (!this.cancelled && !hadError && this.config.buildLiveness?.mutationRequired && this.buildProgress.mutationsSucceeded === 0 && !lastTurnState.clarificationRequested) {
|
|
22578
|
+
hadError = true;
|
|
22579
|
+
const providerFailed = lastTurnState.providerError;
|
|
22580
|
+
const stalled = createBrainEvent("error", this.sessionId, {
|
|
22581
|
+
severity: "fatal",
|
|
22582
|
+
message: providerFailed ? "BUILD provider call failed before any successful on-disk mutation was observed." : `BUILD stalled after ${this.buildProgress.recoveries} recovery turn(s): the task required an on-disk mutation, but no successful mutation was observed.`,
|
|
22583
|
+
code: providerFailed ? "build_liveness_provider_error" : "build_liveness_stalled"
|
|
22584
|
+
});
|
|
22585
|
+
this.emit(stalled);
|
|
22586
|
+
yield stalled;
|
|
22587
|
+
}
|
|
22492
22588
|
let turns = 0;
|
|
22493
22589
|
while (turns < this.maxQueuedIterations) {
|
|
22494
22590
|
if (this.cancelled)
|
|
22495
22591
|
break;
|
|
22592
|
+
if (hadError)
|
|
22593
|
+
break;
|
|
22496
22594
|
if (this.queue.length === 0)
|
|
22497
22595
|
break;
|
|
22498
22596
|
const queuedPrompt = this.dequeueNext();
|
|
@@ -22508,7 +22606,11 @@ ${shared2.content}`,
|
|
|
22508
22606
|
this.emit(msgStart);
|
|
22509
22607
|
yield msgStart;
|
|
22510
22608
|
let turnLength = 0;
|
|
22511
|
-
const turnFinishRef = {
|
|
22609
|
+
const turnFinishRef = {
|
|
22610
|
+
value: "stop",
|
|
22611
|
+
clarificationRequested: false,
|
|
22612
|
+
providerError: false
|
|
22613
|
+
};
|
|
22512
22614
|
const turnUsageRef = { value: null };
|
|
22513
22615
|
for await (const ev of this.runSingleTurn(turnMessageId, turnFinishRef, turnUsageRef)) {
|
|
22514
22616
|
if (ev.type === "message_delta") {
|
|
@@ -22570,17 +22672,26 @@ ${shared2.content}`,
|
|
|
22570
22672
|
}
|
|
22571
22673
|
/** Build a provider-only view with memory after the stable system prefix. */
|
|
22572
22674
|
messagesForProvider() {
|
|
22573
|
-
|
|
22574
|
-
return this.config.messages;
|
|
22675
|
+
let messages = this.config.messages;
|
|
22575
22676
|
let prefixEnd = 0;
|
|
22576
|
-
|
|
22577
|
-
prefixEnd
|
|
22677
|
+
if (this.activeMemoryContext) {
|
|
22678
|
+
while (prefixEnd < messages.length && messages[prefixEnd]?.role === "system") {
|
|
22679
|
+
prefixEnd += 1;
|
|
22680
|
+
}
|
|
22681
|
+
messages = [
|
|
22682
|
+
...messages.slice(0, prefixEnd),
|
|
22683
|
+
{ role: "system", content: this.activeMemoryContext },
|
|
22684
|
+
...messages.slice(prefixEnd)
|
|
22685
|
+
];
|
|
22686
|
+
}
|
|
22687
|
+
if (!this.config.requestTail)
|
|
22688
|
+
return messages;
|
|
22689
|
+
try {
|
|
22690
|
+
const tail2 = this.config.requestTail();
|
|
22691
|
+
return tail2.length > 0 ? [...messages, ...tail2] : messages;
|
|
22692
|
+
} catch {
|
|
22693
|
+
return messages;
|
|
22578
22694
|
}
|
|
22579
|
-
return [
|
|
22580
|
-
...this.config.messages.slice(0, prefixEnd),
|
|
22581
|
-
{ role: "system", content: this.activeMemoryContext },
|
|
22582
|
-
...this.config.messages.slice(prefixEnd)
|
|
22583
|
-
];
|
|
22584
22695
|
}
|
|
22585
22696
|
/**
|
|
22586
22697
|
* v1.36.0: capture a deterministic snapshot of the routed request just
|
|
@@ -22614,17 +22725,19 @@ ${shared2.content}`,
|
|
|
22614
22725
|
* Extracted from the original monolithic `run()` body to enable
|
|
22615
22726
|
* the queue-draining loop in Task 18.1.
|
|
22616
22727
|
*/
|
|
22617
|
-
async *runSingleTurn(messageId, finishRef, usageRef) {
|
|
22728
|
+
async *runSingleTurn(messageId, finishRef, usageRef, generation) {
|
|
22618
22729
|
try {
|
|
22619
22730
|
const requestMessages = this.messagesForProvider();
|
|
22620
|
-
this.emitSnapshot(this.config.tools,
|
|
22731
|
+
this.emitSnapshot(this.config.tools, generation, requestMessages);
|
|
22621
22732
|
recordRequest(this.growth, requestMessages);
|
|
22622
22733
|
const stream = this.config.providerStream({
|
|
22623
22734
|
messages: requestMessages,
|
|
22624
22735
|
model: this.config.model,
|
|
22625
22736
|
provider: this.config.provider,
|
|
22626
22737
|
tools: this.config.tools,
|
|
22627
|
-
signal: this.activeController?.signal
|
|
22738
|
+
signal: this.activeController?.signal,
|
|
22739
|
+
conversationId: this.sessionId,
|
|
22740
|
+
generation
|
|
22628
22741
|
});
|
|
22629
22742
|
let toolCallsThisTurn = 0;
|
|
22630
22743
|
const maxToolCalls = this.config.maxToolCallsPerTurn;
|
|
@@ -22690,6 +22803,10 @@ ${shared2.content}`,
|
|
|
22690
22803
|
yield thinkEvent;
|
|
22691
22804
|
} else if (delta.kind === "tool_call") {
|
|
22692
22805
|
toolCallsThisTurn++;
|
|
22806
|
+
this.buildProgress.toolCalls += 1;
|
|
22807
|
+
if (this.isMutationTool(delta.toolName, delta.args)) {
|
|
22808
|
+
this.buildProgress.mutationsAttempted += 1;
|
|
22809
|
+
}
|
|
22693
22810
|
turnToolCalls.push({ id: delta.toolCallId, name: delta.toolName, args: delta.args });
|
|
22694
22811
|
const toolStartEvent = createBrainEvent("tool_execution_start", this.sessionId, {
|
|
22695
22812
|
toolCallId: delta.toolCallId,
|
|
@@ -22743,11 +22860,18 @@ ${cached2}`
|
|
|
22743
22860
|
this.toolCallCache.set(item.cacheKey, item.content);
|
|
22744
22861
|
}
|
|
22745
22862
|
}
|
|
22863
|
+
for (let i = 0; i < executed.length; i++) {
|
|
22864
|
+
const item = executed[i];
|
|
22865
|
+
const pending = pendingNativeTools[i];
|
|
22866
|
+
if (!item.isError)
|
|
22867
|
+
this.recordSuccessfulTool(pending.toolName, pending.args);
|
|
22868
|
+
}
|
|
22746
22869
|
pendingNativeTools.length = 0;
|
|
22747
22870
|
}
|
|
22748
22871
|
const clarificationPause = /---QUESTION---/.test(turnText) && /"choices"\s*:\s*\[/.test(turnText);
|
|
22749
22872
|
if (clarificationPause) {
|
|
22750
22873
|
finishRef.value = "stop";
|
|
22874
|
+
finishRef.clarificationRequested = true;
|
|
22751
22875
|
}
|
|
22752
22876
|
const textTools = clarificationPause ? [] : parseTextToolCalls(turnText);
|
|
22753
22877
|
const toolsToRun = textTools.filter((tt) => {
|
|
@@ -22770,6 +22894,10 @@ ${cached2}`
|
|
|
22770
22894
|
if (typeof maxToolCalls === "number" && toolCallsThisTurn + 1 > maxToolCalls)
|
|
22771
22895
|
break;
|
|
22772
22896
|
toolCallsThisTurn++;
|
|
22897
|
+
this.buildProgress.toolCalls += 1;
|
|
22898
|
+
if (this.isMutationTool(tt.name, tt.args)) {
|
|
22899
|
+
this.buildProgress.mutationsAttempted += 1;
|
|
22900
|
+
}
|
|
22773
22901
|
const toolCallId = `text-${crypto.randomUUID().slice(0, 8)}`;
|
|
22774
22902
|
turnToolCalls.push({ id: toolCallId, name: tt.name, args: tt.args });
|
|
22775
22903
|
const startEv = createBrainEvent("tool_execution_start", this.sessionId, {
|
|
@@ -22831,6 +22959,8 @@ ${cached2}`
|
|
|
22831
22959
|
this.emit(endEv);
|
|
22832
22960
|
yield endEv;
|
|
22833
22961
|
turnToolResults.push({ toolCallId, content: resultStr });
|
|
22962
|
+
if (!isError)
|
|
22963
|
+
this.recordSuccessfulTool(tt.name, tt.args);
|
|
22834
22964
|
executedAny = true;
|
|
22835
22965
|
}
|
|
22836
22966
|
if (executedAny) {
|
|
@@ -22868,6 +22998,7 @@ ${cached2}`
|
|
|
22868
22998
|
}
|
|
22869
22999
|
break;
|
|
22870
23000
|
} else if (delta.kind === "error") {
|
|
23001
|
+
finishRef.providerError = true;
|
|
22871
23002
|
const errEvent = createBrainEvent("error", this.sessionId, {
|
|
22872
23003
|
severity: "recoverable",
|
|
22873
23004
|
message: delta.message
|
|
@@ -22880,6 +23011,7 @@ ${cached2}`
|
|
|
22880
23011
|
}
|
|
22881
23012
|
}
|
|
22882
23013
|
} catch (err) {
|
|
23014
|
+
finishRef.providerError = true;
|
|
22883
23015
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
22884
23016
|
const errEvent = createBrainEvent("error", this.sessionId, {
|
|
22885
23017
|
severity: "recoverable",
|
|
@@ -22924,7 +23056,11 @@ ${cached2}`
|
|
|
22924
23056
|
content: "[system] Hard tool-iteration ceiling reached. Stop calling tools and give a clear status: what is DONE, what remains, and the exact next steps. Use what you already gathered. Do not apologize for the tools."
|
|
22925
23057
|
});
|
|
22926
23058
|
let totalLength = 0;
|
|
22927
|
-
const finishRef = {
|
|
23059
|
+
const finishRef = {
|
|
23060
|
+
value: "stop",
|
|
23061
|
+
clarificationRequested: false,
|
|
23062
|
+
providerError: false
|
|
23063
|
+
};
|
|
22928
23064
|
const usageRef = { value: null };
|
|
22929
23065
|
const requestMessages = this.messagesForProvider();
|
|
22930
23066
|
recordRequest(this.growth, requestMessages);
|
|
@@ -22935,7 +23071,8 @@ ${cached2}`
|
|
|
22935
23071
|
model: this.config.model,
|
|
22936
23072
|
provider: this.config.provider,
|
|
22937
23073
|
tools: [],
|
|
22938
|
-
signal: this.activeController?.signal
|
|
23074
|
+
signal: this.activeController?.signal,
|
|
23075
|
+
conversationId: this.sessionId
|
|
22939
23076
|
});
|
|
22940
23077
|
for await (const delta of stream) {
|
|
22941
23078
|
if (this.cancelled)
|
|
@@ -23506,6 +23643,7 @@ var init_hooks = __esm({
|
|
|
23506
23643
|
var harness_exports = {};
|
|
23507
23644
|
__export(harness_exports, {
|
|
23508
23645
|
AgentHarness: () => AgentHarness,
|
|
23646
|
+
BUILD_LIVENESS_RECOVERY_PROMPT: () => BUILD_LIVENESS_RECOVERY_PROMPT,
|
|
23509
23647
|
DOOM_LOOP_THRESHOLD: () => DOOM_LOOP_THRESHOLD,
|
|
23510
23648
|
LifecycleHookRunner: () => LifecycleHookRunner,
|
|
23511
23649
|
SessionJsonlWriter: () => SessionJsonlWriter,
|
|
@@ -29771,8 +29909,8 @@ var init_types8 = __esm({
|
|
|
29771
29909
|
// observation, digest). Not model-surface. Schema review per ADR-0021.
|
|
29772
29910
|
"verification.evidence",
|
|
29773
29911
|
// 2.6 Track B (resource-aware execution, doc §9-§12): host-owned resource
|
|
29774
|
-
// state. `resource.snapshot` is
|
|
29775
|
-
//
|
|
29912
|
+
// state. `resource.snapshot` is rendered only as a volatile request tail;
|
|
29913
|
+
// it never enters the persistent model-history projection.
|
|
29776
29914
|
"resource.epoch_started",
|
|
29777
29915
|
"resource.snapshot",
|
|
29778
29916
|
"resource.limit_reached",
|
|
@@ -30206,13 +30344,6 @@ function deriveMessages(events, options = {}) {
|
|
|
30206
30344
|
seq: e.seq
|
|
30207
30345
|
});
|
|
30208
30346
|
break;
|
|
30209
|
-
case "resource.snapshot":
|
|
30210
|
-
messages.push({
|
|
30211
|
-
role: "system",
|
|
30212
|
-
content: formatResourceSnapshot(d),
|
|
30213
|
-
seq: e.seq
|
|
30214
|
-
});
|
|
30215
|
-
break;
|
|
30216
30347
|
}
|
|
30217
30348
|
}
|
|
30218
30349
|
pushDueCheckpoints(Number.POSITIVE_INFINITY);
|
|
@@ -30239,7 +30370,7 @@ function pairToolCalls(events) {
|
|
|
30239
30370
|
}
|
|
30240
30371
|
return ordered;
|
|
30241
30372
|
}
|
|
30242
|
-
var MODEL_SURFACE_KINDS, LATEST_ONLY_SURFACE_KINDS;
|
|
30373
|
+
var MODEL_SURFACE_KINDS, EPHEMERAL_TAIL_EVENT_KINDS, LATEST_ONLY_SURFACE_KINDS;
|
|
30243
30374
|
var init_modelSurface = __esm({
|
|
30244
30375
|
"packages/core/dist/session/modelSurface.js"() {
|
|
30245
30376
|
"use strict";
|
|
@@ -30249,11 +30380,12 @@ var init_modelSurface = __esm({
|
|
|
30249
30380
|
"assistant.message",
|
|
30250
30381
|
"tool.call",
|
|
30251
30382
|
"tool.result",
|
|
30252
|
-
"session.compacted"
|
|
30253
|
-
|
|
30383
|
+
"session.compacted"
|
|
30384
|
+
]);
|
|
30385
|
+
EPHEMERAL_TAIL_EVENT_KINDS = /* @__PURE__ */ new Set([
|
|
30254
30386
|
"resource.snapshot"
|
|
30255
30387
|
]);
|
|
30256
|
-
LATEST_ONLY_SURFACE_KINDS = /* @__PURE__ */ new Set(
|
|
30388
|
+
LATEST_ONLY_SURFACE_KINDS = /* @__PURE__ */ new Set();
|
|
30257
30389
|
}
|
|
30258
30390
|
});
|
|
30259
30391
|
|
|
@@ -33263,6 +33395,7 @@ __export(dist_exports, {
|
|
|
33263
33395
|
AgentHarness: () => AgentHarness,
|
|
33264
33396
|
BENNETTS_RAZOR: () => BENNETTS_RAZOR,
|
|
33265
33397
|
BENNETTS_RAZOR_SHORT: () => BENNETTS_RAZOR_SHORT,
|
|
33398
|
+
BUILD_LIVENESS_RECOVERY_PROMPT: () => BUILD_LIVENESS_RECOVERY_PROMPT,
|
|
33266
33399
|
BUILT_IN_PROFILES: () => BUILT_IN_PROFILES,
|
|
33267
33400
|
BonConfigSchema: () => BonConfigSchema,
|
|
33268
33401
|
BudgetPressureSchema: () => BudgetPressureSchema,
|
|
@@ -33293,6 +33426,7 @@ __export(dist_exports, {
|
|
|
33293
33426
|
DefaultMemorySanitizer: () => DefaultMemorySanitizer,
|
|
33294
33427
|
DefaultMemoryService: () => DefaultMemoryService,
|
|
33295
33428
|
DeterministicCheckSchema: () => DeterministicCheckSchema,
|
|
33429
|
+
EPHEMERAL_TAIL_EVENT_KINDS: () => EPHEMERAL_TAIL_EVENT_KINDS,
|
|
33296
33430
|
EVENT_BACKED_EVIDENCE_TIERS: () => EVENT_BACKED_EVIDENCE_TIERS,
|
|
33297
33431
|
EXPERIMENTAL_FLAGS: () => EXPERIMENTAL_FLAGS,
|
|
33298
33432
|
EventBus: () => EventBus,
|
|
@@ -34875,7 +35009,7 @@ var init_sessionSpine = __esm({
|
|
|
34875
35009
|
data: { ...snapshot }
|
|
34876
35010
|
}).then(() => void 0);
|
|
34877
35011
|
}
|
|
34878
|
-
/** Latest emitted resource snapshot (
|
|
35012
|
+
/** Latest emitted resource snapshot (available for request-tail injection). */
|
|
34879
35013
|
latestResourceSnapshot() {
|
|
34880
35014
|
return this.budgetRuntime?.latestEmitted() ?? null;
|
|
34881
35015
|
}
|
|
@@ -36968,6 +37102,10 @@ async function runTentacle(opts) {
|
|
|
36968
37102
|
tools: sub.tools,
|
|
36969
37103
|
toolRegistry: sub.registry,
|
|
36970
37104
|
providerStream: sub.providerStream,
|
|
37105
|
+
buildLiveness: {
|
|
37106
|
+
mutationRequired: agent === "general",
|
|
37107
|
+
maxRecoveries: 2
|
|
37108
|
+
},
|
|
36971
37109
|
cwd: runCwd,
|
|
36972
37110
|
maxToolCallsPerTurn: maxToolCalls,
|
|
36973
37111
|
maxToolLoopIterations: Math.max(12, maxToolCalls + 4),
|
|
@@ -40475,44 +40613,120 @@ var init_semantic2 = __esm({
|
|
|
40475
40613
|
});
|
|
40476
40614
|
|
|
40477
40615
|
// src/cli/provider/capabilities.ts
|
|
40478
|
-
function
|
|
40479
|
-
if (
|
|
40616
|
+
function frozenProfile(input) {
|
|
40617
|
+
if (input.reasoning.levels) Object.freeze(input.reasoning.levels);
|
|
40618
|
+
Object.freeze(input.reasoning);
|
|
40619
|
+
Object.freeze(input.promptCache);
|
|
40620
|
+
Object.freeze(input.toolCalling);
|
|
40621
|
+
Object.freeze(input.buildRecovery);
|
|
40622
|
+
Object.freeze(input.sampling);
|
|
40623
|
+
Object.freeze(input.compaction);
|
|
40624
|
+
return Object.freeze(input);
|
|
40625
|
+
}
|
|
40626
|
+
function resolveHarnessProfile(model, providerId) {
|
|
40627
|
+
const provider = providerId?.trim().toLowerCase();
|
|
40628
|
+
if (provider === "deepseek") return "deepseek-v4";
|
|
40629
|
+
if (provider === "grok") return "grok";
|
|
40630
|
+
if (provider === "minimax") return "minimax";
|
|
40631
|
+
if (provider === "glm") return "glm";
|
|
40632
|
+
if (model && DEEPSEEK_RE.test(model)) return "deepseek-v4";
|
|
40633
|
+
if (model && GROK_RE.test(model)) return "grok";
|
|
40634
|
+
if (model && MINIMAX_RE.test(model)) return "minimax";
|
|
40635
|
+
if (model && GLM_RE.test(model)) return "glm";
|
|
40480
40636
|
return "default";
|
|
40481
40637
|
}
|
|
40482
|
-
function capabilitiesFor(model) {
|
|
40483
|
-
|
|
40638
|
+
function capabilitiesFor(model, providerId) {
|
|
40639
|
+
switch (resolveHarnessProfile(model, providerId)) {
|
|
40640
|
+
case "deepseek-v4":
|
|
40641
|
+
return DEEPSEEK_V4_CAPS;
|
|
40642
|
+
case "grok":
|
|
40643
|
+
return GROK_CAPS;
|
|
40644
|
+
case "minimax":
|
|
40645
|
+
return model && MINIMAX_M3_RE.test(model) ? MINIMAX_M3_CAPS : MINIMAX_M2_CAPS;
|
|
40646
|
+
case "glm":
|
|
40647
|
+
return GLM_CAPS;
|
|
40648
|
+
default:
|
|
40649
|
+
return DEFAULT_CAPS;
|
|
40650
|
+
}
|
|
40484
40651
|
}
|
|
40485
|
-
var DEFAULT_CAPS, DEEPSEEK_V4_CAPS,
|
|
40652
|
+
var SHARED_COMPACTION, DEFAULT_CAPS, DEEPSEEK_V4_CAPS, GROK_CAPS, MINIMAX_M3_CAPS, MINIMAX_M2_CAPS, GLM_CAPS, DEEPSEEK_RE, GROK_RE, MINIMAX_RE, MINIMAX_M3_RE, GLM_RE;
|
|
40486
40653
|
var init_capabilities = __esm({
|
|
40487
40654
|
"src/cli/provider/capabilities.ts"() {
|
|
40488
40655
|
"use strict";
|
|
40489
|
-
|
|
40656
|
+
SHARED_COMPACTION = { warnAt: 0.7, compactAt: 0.85, hardAt: 0.95 };
|
|
40657
|
+
DEFAULT_CAPS = frozenProfile({
|
|
40490
40658
|
contextWindow: 4e5,
|
|
40491
|
-
reasoning:
|
|
40492
|
-
|
|
40493
|
-
|
|
40494
|
-
|
|
40495
|
-
}
|
|
40496
|
-
|
|
40497
|
-
toolCalling: Object.freeze({ parallel: true }),
|
|
40498
|
-
sampling: Object.freeze({ temperature: 0.7 }),
|
|
40499
|
-
compaction: Object.freeze({ warnAt: 0.7, compactAt: 0.85, hardAt: 0.95 }),
|
|
40659
|
+
reasoning: { supported: true, levels: ["low", "medium", "high"], replayReasoning: true },
|
|
40660
|
+
promptCache: { supported: true, pricedCacheRead: false },
|
|
40661
|
+
toolCalling: { parallel: true },
|
|
40662
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40663
|
+
sampling: { temperature: 0.7 },
|
|
40664
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40500
40665
|
profile: "default"
|
|
40501
40666
|
});
|
|
40502
|
-
DEEPSEEK_V4_CAPS =
|
|
40667
|
+
DEEPSEEK_V4_CAPS = frozenProfile({
|
|
40503
40668
|
contextWindow: 1e6,
|
|
40504
|
-
reasoning:
|
|
40505
|
-
|
|
40506
|
-
|
|
40507
|
-
|
|
40508
|
-
}
|
|
40509
|
-
|
|
40510
|
-
toolCalling: Object.freeze({ parallel: true }),
|
|
40511
|
-
sampling: Object.freeze({ temperature: 0.7 }),
|
|
40512
|
-
compaction: Object.freeze({ warnAt: 0.7, compactAt: 0.85, hardAt: 0.95 }),
|
|
40669
|
+
reasoning: { supported: true, levels: ["high", "max"], replayReasoning: true },
|
|
40670
|
+
promptCache: { supported: true, pricedCacheRead: true },
|
|
40671
|
+
toolCalling: { parallel: true },
|
|
40672
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40673
|
+
sampling: { temperature: 0.7 },
|
|
40674
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40513
40675
|
profile: "deepseek-v4"
|
|
40514
40676
|
});
|
|
40515
|
-
|
|
40677
|
+
GROK_CAPS = frozenProfile({
|
|
40678
|
+
contextWindow: 5e5,
|
|
40679
|
+
reasoning: {
|
|
40680
|
+
supported: true,
|
|
40681
|
+
levels: ["low", "medium", "high", "xhigh"],
|
|
40682
|
+
replayReasoning: false
|
|
40683
|
+
},
|
|
40684
|
+
promptCache: {
|
|
40685
|
+
supported: true,
|
|
40686
|
+
pricedCacheRead: true,
|
|
40687
|
+
conversationAffinityHeader: "x-grok-conv-id"
|
|
40688
|
+
},
|
|
40689
|
+
toolCalling: { parallel: true },
|
|
40690
|
+
buildRecovery: { forceToolChoice: true, maxForcedTurns: 1 },
|
|
40691
|
+
sampling: { temperature: 0.7 },
|
|
40692
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40693
|
+
profile: "grok"
|
|
40694
|
+
});
|
|
40695
|
+
MINIMAX_M3_CAPS = frozenProfile({
|
|
40696
|
+
contextWindow: 1e6,
|
|
40697
|
+
reasoning: { supported: true, replayReasoning: true },
|
|
40698
|
+
promptCache: { supported: false, pricedCacheRead: false },
|
|
40699
|
+
toolCalling: { parallel: true },
|
|
40700
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40701
|
+
sampling: { temperature: 0.7 },
|
|
40702
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40703
|
+
profile: "minimax"
|
|
40704
|
+
});
|
|
40705
|
+
MINIMAX_M2_CAPS = frozenProfile({
|
|
40706
|
+
contextWindow: 204800,
|
|
40707
|
+
reasoning: { supported: true, replayReasoning: true },
|
|
40708
|
+
promptCache: { supported: false, pricedCacheRead: false },
|
|
40709
|
+
toolCalling: { parallel: true },
|
|
40710
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40711
|
+
sampling: { temperature: 0.7 },
|
|
40712
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40713
|
+
profile: "minimax"
|
|
40714
|
+
});
|
|
40715
|
+
GLM_CAPS = frozenProfile({
|
|
40716
|
+
contextWindow: 2e5,
|
|
40717
|
+
reasoning: { supported: true, replayReasoning: true },
|
|
40718
|
+
promptCache: { supported: true, pricedCacheRead: false },
|
|
40719
|
+
toolCalling: { parallel: true },
|
|
40720
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40721
|
+
sampling: { temperature: 0.7 },
|
|
40722
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40723
|
+
profile: "glm"
|
|
40724
|
+
});
|
|
40725
|
+
DEEPSEEK_RE = /^deepseek-(?:v4(?:\.|-|$)|chat$|reasoner$)/i;
|
|
40726
|
+
GROK_RE = /^grok(?:\.|-|$)/i;
|
|
40727
|
+
MINIMAX_RE = /^minimax(?:\.|-|$)/i;
|
|
40728
|
+
MINIMAX_M3_RE = /^minimax-m3(?:\.|-|$)/i;
|
|
40729
|
+
GLM_RE = /^glm(?:\.|-|$)/i;
|
|
40516
40730
|
}
|
|
40517
40731
|
});
|
|
40518
40732
|
|
|
@@ -40701,6 +40915,7 @@ ${notes}
|
|
|
40701
40915
|
}
|
|
40702
40916
|
function openaiCompatibleProvider(config2) {
|
|
40703
40917
|
return async function* (params) {
|
|
40918
|
+
const capabilities = capabilitiesFor(params.model, config2.providerId);
|
|
40704
40919
|
const vision = modelSupportsVision(params.model);
|
|
40705
40920
|
const messages = params.messages.map((m) => {
|
|
40706
40921
|
const cacheable = !(m.role === "user" && m.images && m.images.length > 0);
|
|
@@ -40720,7 +40935,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
40720
40935
|
model: params.model,
|
|
40721
40936
|
messages,
|
|
40722
40937
|
stream: true,
|
|
40723
|
-
temperature: generation?.temperature ??
|
|
40938
|
+
temperature: generation?.temperature ?? capabilities.sampling.temperature,
|
|
40724
40939
|
// Task G.4.2 — request the provider to send real token usage in
|
|
40725
40940
|
// the final chunk (gated by `stream_options.include_usage` on the
|
|
40726
40941
|
// OpenAI-compatible API). Providers that don't honor this (some
|
|
@@ -40756,7 +40971,19 @@ function openaiCompatibleProvider(config2) {
|
|
|
40756
40971
|
parameters: t.parameters
|
|
40757
40972
|
}
|
|
40758
40973
|
}));
|
|
40759
|
-
|
|
40974
|
+
const recoveryAttempt = generation?.recoveryAttempt ?? 1;
|
|
40975
|
+
const forceRecoveryTool = generation?.toolChoice === "required" && capabilities.buildRecovery.forceToolChoice && recoveryAttempt <= capabilities.buildRecovery.maxForcedTurns;
|
|
40976
|
+
body.tool_choice = forceRecoveryTool ? "required" : "auto";
|
|
40977
|
+
}
|
|
40978
|
+
const headers2 = {
|
|
40979
|
+
"Content-Type": "application/json",
|
|
40980
|
+
Authorization: `Bearer ${config2.apiKey}`,
|
|
40981
|
+
...config2.extraHeaders ?? {}
|
|
40982
|
+
};
|
|
40983
|
+
const affinityHeader = capabilities.promptCache.conversationAffinityHeader;
|
|
40984
|
+
const conversationId = params.conversationId?.trim();
|
|
40985
|
+
if (affinityHeader && conversationId && conversationId.length <= 256 && !/[\u0000-\u001f\u007f]/.test(conversationId)) {
|
|
40986
|
+
headers2[affinityHeader] = conversationId;
|
|
40760
40987
|
}
|
|
40761
40988
|
let response;
|
|
40762
40989
|
let lastErrText = "";
|
|
@@ -40781,10 +41008,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
40781
41008
|
try {
|
|
40782
41009
|
response = await fetch(`${config2.baseUrl}/chat/completions`, {
|
|
40783
41010
|
method: "POST",
|
|
40784
|
-
headers:
|
|
40785
|
-
"Content-Type": "application/json",
|
|
40786
|
-
Authorization: `Bearer ${config2.apiKey}`
|
|
40787
|
-
},
|
|
41011
|
+
headers: headers2,
|
|
40788
41012
|
body: JSON.stringify(body),
|
|
40789
41013
|
// Cancel aborts the HTTP request; stream idle is enforced below
|
|
40790
41014
|
// per-chunk so active multi-minute streams are not killed.
|
|
@@ -44946,7 +45170,7 @@ function expectsDiskImplementation(task, phase2, prior) {
|
|
|
44946
45170
|
const trimmed = task.trim();
|
|
44947
45171
|
if (!trimmed) return false;
|
|
44948
45172
|
if (isShortContinueReply(trimmed)) return true;
|
|
44949
|
-
if (/\b(implement|
|
|
45173
|
+
if (/\b(implement(?:a|are)?|scriv(?:i|iamo|ere)|applica(?:re)?|modifica(?:re)?|fix|write|edit|crea(?:re)?|aggiung(?:i|ere)|aggiorn(?:a|are)|apply|patch|refactor|corregg(?:i|ere)|risolv(?:i|ere)|remove|rimuov(?:i|ere)|rename|rinomina(?:re)?|replace|sostituisc(?:i|e)|delete|elimina(?:re)?|build|costruisc(?:i|e)|convert(?:i|ire)?|migra(?:re)?|upgrade)\b/i.test(
|
|
44950
45174
|
trimmed
|
|
44951
45175
|
)) {
|
|
44952
45176
|
return true;
|
|
@@ -51129,6 +51353,7 @@ async function runAgentMissionSlice(deps) {
|
|
|
51129
51353
|
tools: toolSpecs,
|
|
51130
51354
|
toolRegistry: deps.toolRegistry,
|
|
51131
51355
|
providerStream: deps.providerStream,
|
|
51356
|
+
buildLiveness: { mutationRequired: writeRetry, maxRecoveries: 2 },
|
|
51132
51357
|
cwd: deps.projectRoot,
|
|
51133
51358
|
maxToolCallsPerTurn: maxToolCalls,
|
|
51134
51359
|
maxToolLoopIterations: maxToolLoop,
|
|
@@ -62658,12 +62883,12 @@ function estimateHistoryTokens(messages) {
|
|
|
62658
62883
|
}
|
|
62659
62884
|
return n;
|
|
62660
62885
|
}
|
|
62661
|
-
function defaultContextLimitForModel(model) {
|
|
62662
|
-
return capabilitiesFor(model).contextWindow;
|
|
62886
|
+
function defaultContextLimitForModel(model, provider) {
|
|
62887
|
+
return capabilitiesFor(model, provider).contextWindow;
|
|
62663
62888
|
}
|
|
62664
|
-
function resolveContextLimit(model) {
|
|
62889
|
+
function resolveContextLimit(model, provider) {
|
|
62665
62890
|
return envNumber(process.env.ZELARI_CONTEXT_LIMIT, {
|
|
62666
|
-
default: defaultContextLimitForModel(model),
|
|
62891
|
+
default: defaultContextLimitForModel(model, provider),
|
|
62667
62892
|
min: 4e3,
|
|
62668
62893
|
max: 2e6
|
|
62669
62894
|
});
|
|
@@ -62679,8 +62904,8 @@ function phaseKnobs(phase2) {
|
|
|
62679
62904
|
}
|
|
62680
62905
|
var RESERVED_OUTPUT_TOKENS = 8192;
|
|
62681
62906
|
async function applyBudgetPolicyAsync(history2, phase2, opts) {
|
|
62682
|
-
const contextLimit = resolveContextLimit(opts?.model);
|
|
62683
|
-
const compact3 = capabilitiesFor(opts?.model).compaction;
|
|
62907
|
+
const contextLimit = resolveContextLimit(opts?.model, opts?.provider);
|
|
62908
|
+
const compact3 = capabilitiesFor(opts?.model, opts?.provider).compaction;
|
|
62684
62909
|
const sessionExtra = opts?.sessionTokens ?? 0;
|
|
62685
62910
|
const warnings = [];
|
|
62686
62911
|
let { historyTurns, maxToolLoopIterations } = phaseKnobs(phase2);
|
|
@@ -62955,8 +63180,11 @@ function messageWasRecompacted(message, history2) {
|
|
|
62955
63180
|
if (message.compactedFromSeq === void 0) return false;
|
|
62956
63181
|
return !history2.some((candidate) => candidate.seq !== void 0 && candidate.seq === message.seq);
|
|
62957
63182
|
}
|
|
62958
|
-
function
|
|
62959
|
-
return { role: "system", content: formatResourceSnapshot(payload) };
|
|
63183
|
+
function resourceStatusTail(payload) {
|
|
63184
|
+
return payload ? [{ role: "system", content: formatResourceSnapshot(payload) }] : [];
|
|
63185
|
+
}
|
|
63186
|
+
function isLegacyResourceStatus(message) {
|
|
63187
|
+
return message.role === "system" && message.content.startsWith("RESOURCE STATUS");
|
|
62960
63188
|
}
|
|
62961
63189
|
async function sessionHistory(session) {
|
|
62962
63190
|
if (!session || session.status !== "active") return null;
|
|
@@ -62967,7 +63195,10 @@ async function sessionHistory(session) {
|
|
|
62967
63195
|
async function buildModelContext(input) {
|
|
62968
63196
|
const derived = await sessionHistory(input.session);
|
|
62969
63197
|
const source2 = derived ? "session" : "fallback";
|
|
62970
|
-
const sourceHistory = derived ?? [...input.fallbackHistory]
|
|
63198
|
+
const sourceHistory = (derived ?? [...input.fallbackHistory]).filter(
|
|
63199
|
+
(message) => !isLegacyResourceStatus(message)
|
|
63200
|
+
);
|
|
63201
|
+
const requestTail = resourceStatusTail(input.resourceSnapshot);
|
|
62971
63202
|
const inputTokens = estimateHistoryTokens(sourceHistory);
|
|
62972
63203
|
const requestSurface = input.systemMessages || input.tools ? {
|
|
62973
63204
|
provider: input.provider ?? "local",
|
|
@@ -62977,7 +63208,8 @@ async function buildModelContext(input) {
|
|
|
62977
63208
|
} : null;
|
|
62978
63209
|
let budget = await applyBudgetPolicyAsync(sourceHistory, input.phase, {
|
|
62979
63210
|
model: input.model,
|
|
62980
|
-
|
|
63211
|
+
provider: input.provider,
|
|
63212
|
+
sessionTokens: (input.sessionTokens ?? 0) + estimateHistoryTokens(requestTail),
|
|
62981
63213
|
sessionId: input.sessionId,
|
|
62982
63214
|
signal: input.signal,
|
|
62983
63215
|
requestSnapshot: input.requestSnapshot,
|
|
@@ -63024,16 +63256,11 @@ async function buildModelContext(input) {
|
|
|
63024
63256
|
};
|
|
63025
63257
|
input.onCompactionMetric?.(compactionMetrics);
|
|
63026
63258
|
}
|
|
63027
|
-
if (input.resourceSnapshot && !history2.some(
|
|
63028
|
-
(m) => m.role === "system" && typeof m.content === "string" && m.content.startsWith("RESOURCE STATUS")
|
|
63029
|
-
)) {
|
|
63030
|
-
history2 = [...history2, resourceStatusMessage(input.resourceSnapshot)];
|
|
63031
|
-
}
|
|
63032
63259
|
if (requestSurface) {
|
|
63033
63260
|
const measured = measureRequest({
|
|
63034
63261
|
systemMessages: requestSurface.systemMessages,
|
|
63035
63262
|
tools: requestSurface.tools,
|
|
63036
|
-
conversation: history2,
|
|
63263
|
+
conversation: [...history2, ...requestTail],
|
|
63037
63264
|
anchor: input.requestSnapshot,
|
|
63038
63265
|
contextLimit: budget.contextLimit,
|
|
63039
63266
|
reservedOutputTokens: 8192
|
|
@@ -63046,7 +63273,7 @@ async function buildModelContext(input) {
|
|
|
63046
63273
|
contextPressureTokens: measured.contextPressureTokens
|
|
63047
63274
|
};
|
|
63048
63275
|
} else {
|
|
63049
|
-
const estimated = estimateHistoryTokens(history2);
|
|
63276
|
+
const estimated = estimateHistoryTokens([...history2, ...requestTail]);
|
|
63050
63277
|
budget = {
|
|
63051
63278
|
...budget,
|
|
63052
63279
|
history: history2,
|
|
@@ -63056,6 +63283,7 @@ async function buildModelContext(input) {
|
|
|
63056
63283
|
}
|
|
63057
63284
|
return {
|
|
63058
63285
|
history: history2,
|
|
63286
|
+
requestTail,
|
|
63059
63287
|
budget,
|
|
63060
63288
|
source: source2,
|
|
63061
63289
|
...compactionPayload ? { compactionPayload } : {},
|
|
@@ -63476,6 +63704,17 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
63476
63704
|
})),
|
|
63477
63705
|
toolRegistry,
|
|
63478
63706
|
providerStream,
|
|
63707
|
+
buildLiveness: {
|
|
63708
|
+
mutationRequired: expectsDiskImplementation(
|
|
63709
|
+
userText,
|
|
63710
|
+
workPhase,
|
|
63711
|
+
historyForModel
|
|
63712
|
+
),
|
|
63713
|
+
maxRecoveries: 2
|
|
63714
|
+
},
|
|
63715
|
+
requestTail: () => resourceStatusTail(
|
|
63716
|
+
writerRef.current?.spine?.latestResourceSnapshot() ?? null
|
|
63717
|
+
),
|
|
63479
63718
|
// 2.6 Phase 3: host-owned pre-dispatch resource gate via the spine
|
|
63480
63719
|
// mirror (doc section 11.3). Degrade-and-stop (null gate = allow).
|
|
63481
63720
|
// 2.6.1 (plan §13): argument-aware — bash is essential only when
|
|
@@ -69243,7 +69482,6 @@ init_harness();
|
|
|
69243
69482
|
init_dist();
|
|
69244
69483
|
init_events2();
|
|
69245
69484
|
init_conversationContext();
|
|
69246
|
-
init_council();
|
|
69247
69485
|
init_toolRegistry();
|
|
69248
69486
|
init_candidateRegistry();
|
|
69249
69487
|
init_metrics2();
|
|
@@ -69900,6 +70138,11 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69900
70138
|
}
|
|
69901
70139
|
const effectiveTask = buildAgentUserWithHistory(opts.task, historySeed);
|
|
69902
70140
|
if (opts.task) spine.userMessage(effectiveTask);
|
|
70141
|
+
const wantWrites = expectsDiskImplementation(
|
|
70142
|
+
opts.task,
|
|
70143
|
+
opts.phase,
|
|
70144
|
+
historySeed
|
|
70145
|
+
);
|
|
69903
70146
|
const maxToolLoop = (() => {
|
|
69904
70147
|
const n = envNumber(process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, {
|
|
69905
70148
|
default: 30,
|
|
@@ -69916,6 +70159,8 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69916
70159
|
tools,
|
|
69917
70160
|
toolRegistry,
|
|
69918
70161
|
providerStream,
|
|
70162
|
+
buildLiveness: { mutationRequired: wantWrites, maxRecoveries: 2 },
|
|
70163
|
+
requestTail: () => resourceStatusTail(spine.spine.latestResourceSnapshot()),
|
|
69919
70164
|
// 2.6 Phase 3: host-owned pre-dispatch resource gate (doc section 11.3).
|
|
69920
70165
|
// Advisory by default; ZELARI_RESOURCE_ENFORCEMENT=protected enables the
|
|
69921
70166
|
// protected verification reserve. Degrade-and-stop (null gate = allow).
|
|
@@ -69929,12 +70174,13 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69929
70174
|
memoryContextChars: 2e3
|
|
69930
70175
|
} : {}
|
|
69931
70176
|
});
|
|
70177
|
+
const readBuildProgress = () => {
|
|
70178
|
+
const getter = harness.getBuildProgress;
|
|
70179
|
+
return typeof getter === "function" ? getter.call(harness) : { mutationsAttempted: 0, mutationsSucceeded: 0 };
|
|
70180
|
+
};
|
|
69932
70181
|
let finalReason = "completed";
|
|
69933
70182
|
let exitCode = 0;
|
|
69934
70183
|
const textBuffer = [];
|
|
69935
|
-
let successfulWrites = 0;
|
|
69936
|
-
let emittedWrites = 0;
|
|
69937
|
-
const pendingToolNames = /* @__PURE__ */ new Map();
|
|
69938
70184
|
const scrub = createStreamScrubber2();
|
|
69939
70185
|
try {
|
|
69940
70186
|
for await (const event of harness.run()) {
|
|
@@ -69943,27 +70189,6 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69943
70189
|
if (event.type === "message_start") {
|
|
69944
70190
|
scrub.reset();
|
|
69945
70191
|
}
|
|
69946
|
-
if (event.type === "tool_execution_start") {
|
|
69947
|
-
const name = event.toolName ?? "";
|
|
69948
|
-
const id3 = event.toolCallId ?? "";
|
|
69949
|
-
if (id3 && name) pendingToolNames.set(id3, name);
|
|
69950
|
-
if (name === "write_file" || name === "edit_file" || name === "apply_diff") {
|
|
69951
|
-
emittedWrites += 1;
|
|
69952
|
-
}
|
|
69953
|
-
}
|
|
69954
|
-
if (event.type === "tool_execution_end") {
|
|
69955
|
-
const id3 = event.toolCallId ?? "";
|
|
69956
|
-
const name = pendingToolNames.get(id3) ?? "";
|
|
69957
|
-
pendingToolNames.delete(id3);
|
|
69958
|
-
const isError = !!event.isError;
|
|
69959
|
-
const result = String(event.result ?? "");
|
|
69960
|
-
if ((name === "write_file" || name === "edit_file" || name === "apply_diff") && !isError) {
|
|
69961
|
-
const zeroEdit = name === "edit_file" && /occurrencesReplaced["']?\s*[:=]\s*0\b|0 occurrence|no changes/i.test(
|
|
69962
|
-
result
|
|
69963
|
-
);
|
|
69964
|
-
if (!zeroEdit) successfulWrites += 1;
|
|
69965
|
-
}
|
|
69966
|
-
}
|
|
69967
70192
|
if (event.type === "message_delta" && typeof event.delta === "string") {
|
|
69968
70193
|
const cleanDelta = scrub.push(event.delta);
|
|
69969
70194
|
if (opts.output === "json") {
|
|
@@ -70003,17 +70228,18 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70003
70228
|
finalReason: "error",
|
|
70004
70229
|
exitCode: 2,
|
|
70005
70230
|
textBuffer,
|
|
70006
|
-
successfulWrites,
|
|
70007
|
-
emittedWrites,
|
|
70231
|
+
successfulWrites: readBuildProgress().mutationsSucceeded,
|
|
70232
|
+
emittedWrites: readBuildProgress().mutationsAttempted,
|
|
70008
70233
|
messages: harness.getMessages()
|
|
70009
70234
|
};
|
|
70010
70235
|
}
|
|
70236
|
+
const buildProgress = readBuildProgress();
|
|
70011
70237
|
return {
|
|
70012
70238
|
finalReason,
|
|
70013
70239
|
exitCode,
|
|
70014
70240
|
textBuffer,
|
|
70015
|
-
successfulWrites,
|
|
70016
|
-
emittedWrites,
|
|
70241
|
+
successfulWrites: buildProgress.mutationsSucceeded,
|
|
70242
|
+
emittedWrites: buildProgress.mutationsAttempted,
|
|
70017
70243
|
messages: harness.getMessages()
|
|
70018
70244
|
};
|
|
70019
70245
|
}
|
|
@@ -70037,41 +70263,6 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70037
70263
|
}
|
|
70038
70264
|
];
|
|
70039
70265
|
let pass = await runSinglePass(initialMessages, sessionId2);
|
|
70040
|
-
const wantWrites = expectsDiskImplementation(
|
|
70041
|
-
opts.task,
|
|
70042
|
-
opts.phase,
|
|
70043
|
-
historySeed
|
|
70044
|
-
);
|
|
70045
|
-
if (wantWrites && pass.successfulWrites === 0 && pass.finalReason === "completed" && pass.exitCode === 0) {
|
|
70046
|
-
const retryPrompt = buildImplementationWriteRetryPrompt(opts.task);
|
|
70047
|
-
if (opts.output === "json") {
|
|
70048
|
-
emitEvent({
|
|
70049
|
-
type: "log",
|
|
70050
|
-
message: "[headless] BUILD: no successful write_file/edit_file \u2014 forcing implementation retry"
|
|
70051
|
-
});
|
|
70052
|
-
} else {
|
|
70053
|
-
process.stderr.write(
|
|
70054
|
-
`[zelari-code --headless] BUILD: no successful writes \u2014 forcing implementation retry
|
|
70055
|
-
`
|
|
70056
|
-
);
|
|
70057
|
-
}
|
|
70058
|
-
const retryMessages = [
|
|
70059
|
-
...pass.messages.filter((m) => m.role !== "system")
|
|
70060
|
-
];
|
|
70061
|
-
const withSystem = [
|
|
70062
|
-
...systemMessages,
|
|
70063
|
-
...retryMessages,
|
|
70064
|
-
{ role: "user", content: retryPrompt }
|
|
70065
|
-
];
|
|
70066
|
-
progressRuntime.beginPass();
|
|
70067
|
-
const retry = await runSinglePass(withSystem, `${sessionId2}-write-retry`);
|
|
70068
|
-
pass = {
|
|
70069
|
-
...retry,
|
|
70070
|
-
textBuffer: [...pass.textBuffer, ...retry.textBuffer],
|
|
70071
|
-
successfulWrites: pass.successfulWrites + retry.successfulWrites,
|
|
70072
|
-
emittedWrites: pass.emittedWrites + retry.emittedWrites
|
|
70073
|
-
};
|
|
70074
|
-
}
|
|
70075
70266
|
let strictExit = 0;
|
|
70076
70267
|
const verifierReviewDeps = {
|
|
70077
70268
|
session: { provider, model },
|
|
@@ -70155,7 +70346,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70155
70346
|
}
|
|
70156
70347
|
process.stdout.write("");
|
|
70157
70348
|
if (pass.finalReason !== "error" && opts.output === "json" && wantWrites && pass.successfulWrites === 0) {
|
|
70158
|
-
emitEvent({ type: "log", message: "[headless] BUILD
|
|
70349
|
+
emitEvent({ type: "log", message: "[headless] BUILD failed: zero successful mutations after liveness recovery" });
|
|
70159
70350
|
}
|
|
70160
70351
|
try {
|
|
70161
70352
|
const closeStatus = pass.finalReason === "error" ? "error" : strictExit !== 0 ? "stopped" : "completed";
|