zelari-code 2.8.0 → 2.9.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/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 +538 -181
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/missionSlice.js +1 -0
- package/dist/cli/missionSlice.js.map +1 -1
- package/dist/cli/provider/capabilities.js +151 -39
- package/dist/cli/provider/capabilities.js.map +1 -1
- package/dist/cli/provider/openai-compatible.js +130 -22
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/provider/sse.js +58 -0
- package/dist/cli/provider/sse.js.map +1 -0
- 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,218 @@ 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.wire);
|
|
40623
|
+
Object.freeze(input.sampling);
|
|
40624
|
+
Object.freeze(input.compaction);
|
|
40625
|
+
return Object.freeze(input);
|
|
40626
|
+
}
|
|
40627
|
+
function resolveHarnessProfile(model, providerId) {
|
|
40628
|
+
const provider = providerId?.trim().toLowerCase();
|
|
40629
|
+
if (provider === "deepseek") return "deepseek-v4";
|
|
40630
|
+
if (provider === "grok") return "grok";
|
|
40631
|
+
if (provider === "minimax") return "minimax";
|
|
40632
|
+
if (provider === "glm") return "glm";
|
|
40633
|
+
if (model && DEEPSEEK_RE.test(model)) return "deepseek-v4";
|
|
40634
|
+
if (model && GROK_RE.test(model)) return "grok";
|
|
40635
|
+
if (model && MINIMAX_RE.test(model)) return "minimax";
|
|
40636
|
+
if (model && GLM_RE.test(model)) return "glm";
|
|
40480
40637
|
return "default";
|
|
40481
40638
|
}
|
|
40482
|
-
function capabilitiesFor(model) {
|
|
40483
|
-
|
|
40639
|
+
function capabilitiesFor(model, providerId) {
|
|
40640
|
+
switch (resolveHarnessProfile(model, providerId)) {
|
|
40641
|
+
case "deepseek-v4":
|
|
40642
|
+
return DEEPSEEK_V4_CAPS;
|
|
40643
|
+
case "grok":
|
|
40644
|
+
return GROK_CAPS;
|
|
40645
|
+
case "minimax":
|
|
40646
|
+
return model && MINIMAX_M3_RE.test(model) ? MINIMAX_M3_CAPS : MINIMAX_M2_CAPS;
|
|
40647
|
+
case "glm":
|
|
40648
|
+
return GLM_CAPS;
|
|
40649
|
+
default:
|
|
40650
|
+
return DEFAULT_CAPS;
|
|
40651
|
+
}
|
|
40484
40652
|
}
|
|
40485
|
-
var DEFAULT_CAPS, DEEPSEEK_V4_CAPS,
|
|
40653
|
+
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
40654
|
var init_capabilities = __esm({
|
|
40487
40655
|
"src/cli/provider/capabilities.ts"() {
|
|
40488
40656
|
"use strict";
|
|
40489
|
-
|
|
40657
|
+
SHARED_COMPACTION = { warnAt: 0.7, compactAt: 0.85, hardAt: 0.95 };
|
|
40658
|
+
DEFAULT_CAPS = frozenProfile({
|
|
40490
40659
|
contextWindow: 4e5,
|
|
40491
|
-
reasoning:
|
|
40492
|
-
|
|
40493
|
-
|
|
40494
|
-
|
|
40495
|
-
|
|
40496
|
-
|
|
40497
|
-
|
|
40498
|
-
|
|
40499
|
-
|
|
40660
|
+
reasoning: { supported: true, levels: ["low", "medium", "high"], replayReasoning: true },
|
|
40661
|
+
promptCache: { supported: true, pricedCacheRead: false },
|
|
40662
|
+
toolCalling: { parallel: true },
|
|
40663
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40664
|
+
wire: {
|
|
40665
|
+
grokRequestHeaders: false,
|
|
40666
|
+
omitAutoToolChoice: false,
|
|
40667
|
+
toolCallDeltasResetIdle: false,
|
|
40668
|
+
retriesBeforeOutput: 0,
|
|
40669
|
+
strictSseJson: false
|
|
40670
|
+
},
|
|
40671
|
+
sampling: { temperature: 0.7 },
|
|
40672
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40500
40673
|
profile: "default"
|
|
40501
40674
|
});
|
|
40502
|
-
DEEPSEEK_V4_CAPS =
|
|
40675
|
+
DEEPSEEK_V4_CAPS = frozenProfile({
|
|
40503
40676
|
contextWindow: 1e6,
|
|
40504
|
-
reasoning:
|
|
40505
|
-
|
|
40506
|
-
|
|
40507
|
-
|
|
40508
|
-
|
|
40509
|
-
|
|
40510
|
-
|
|
40511
|
-
|
|
40512
|
-
|
|
40677
|
+
reasoning: { supported: true, levels: ["high", "max"], replayReasoning: true },
|
|
40678
|
+
promptCache: { supported: true, pricedCacheRead: true },
|
|
40679
|
+
toolCalling: { parallel: true },
|
|
40680
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40681
|
+
wire: {
|
|
40682
|
+
grokRequestHeaders: false,
|
|
40683
|
+
omitAutoToolChoice: false,
|
|
40684
|
+
toolCallDeltasResetIdle: false,
|
|
40685
|
+
retriesBeforeOutput: 0,
|
|
40686
|
+
strictSseJson: false
|
|
40687
|
+
},
|
|
40688
|
+
sampling: { temperature: 0.7 },
|
|
40689
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40513
40690
|
profile: "deepseek-v4"
|
|
40514
40691
|
});
|
|
40515
|
-
|
|
40692
|
+
GROK_CAPS = frozenProfile({
|
|
40693
|
+
contextWindow: 5e5,
|
|
40694
|
+
reasoning: {
|
|
40695
|
+
supported: true,
|
|
40696
|
+
levels: ["low", "medium", "high", "xhigh"],
|
|
40697
|
+
replayReasoning: false
|
|
40698
|
+
},
|
|
40699
|
+
promptCache: {
|
|
40700
|
+
supported: true,
|
|
40701
|
+
pricedCacheRead: true,
|
|
40702
|
+
conversationAffinityHeader: "x-grok-conv-id"
|
|
40703
|
+
},
|
|
40704
|
+
toolCalling: { parallel: true },
|
|
40705
|
+
buildRecovery: { forceToolChoice: true, maxForcedTurns: 1 },
|
|
40706
|
+
wire: {
|
|
40707
|
+
grokRequestHeaders: true,
|
|
40708
|
+
omitAutoToolChoice: true,
|
|
40709
|
+
toolCallDeltasResetIdle: true,
|
|
40710
|
+
retriesBeforeOutput: 1,
|
|
40711
|
+
strictSseJson: true
|
|
40712
|
+
},
|
|
40713
|
+
sampling: { temperature: 0.7 },
|
|
40714
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40715
|
+
profile: "grok"
|
|
40716
|
+
});
|
|
40717
|
+
MINIMAX_M3_CAPS = frozenProfile({
|
|
40718
|
+
contextWindow: 1e6,
|
|
40719
|
+
reasoning: { supported: true, replayReasoning: true },
|
|
40720
|
+
promptCache: { supported: false, pricedCacheRead: false },
|
|
40721
|
+
toolCalling: { parallel: true },
|
|
40722
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40723
|
+
wire: {
|
|
40724
|
+
grokRequestHeaders: false,
|
|
40725
|
+
omitAutoToolChoice: false,
|
|
40726
|
+
toolCallDeltasResetIdle: false,
|
|
40727
|
+
retriesBeforeOutput: 0,
|
|
40728
|
+
strictSseJson: false
|
|
40729
|
+
},
|
|
40730
|
+
sampling: { temperature: 0.7 },
|
|
40731
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40732
|
+
profile: "minimax"
|
|
40733
|
+
});
|
|
40734
|
+
MINIMAX_M2_CAPS = frozenProfile({
|
|
40735
|
+
contextWindow: 204800,
|
|
40736
|
+
reasoning: { supported: true, replayReasoning: true },
|
|
40737
|
+
promptCache: { supported: false, pricedCacheRead: false },
|
|
40738
|
+
toolCalling: { parallel: true },
|
|
40739
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40740
|
+
wire: {
|
|
40741
|
+
grokRequestHeaders: false,
|
|
40742
|
+
omitAutoToolChoice: false,
|
|
40743
|
+
toolCallDeltasResetIdle: false,
|
|
40744
|
+
retriesBeforeOutput: 0,
|
|
40745
|
+
strictSseJson: false
|
|
40746
|
+
},
|
|
40747
|
+
sampling: { temperature: 0.7 },
|
|
40748
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40749
|
+
profile: "minimax"
|
|
40750
|
+
});
|
|
40751
|
+
GLM_CAPS = frozenProfile({
|
|
40752
|
+
contextWindow: 2e5,
|
|
40753
|
+
reasoning: { supported: true, replayReasoning: true },
|
|
40754
|
+
promptCache: { supported: true, pricedCacheRead: false },
|
|
40755
|
+
toolCalling: { parallel: true },
|
|
40756
|
+
buildRecovery: { forceToolChoice: false, maxForcedTurns: 0 },
|
|
40757
|
+
wire: {
|
|
40758
|
+
grokRequestHeaders: false,
|
|
40759
|
+
omitAutoToolChoice: false,
|
|
40760
|
+
toolCallDeltasResetIdle: false,
|
|
40761
|
+
retriesBeforeOutput: 0,
|
|
40762
|
+
strictSseJson: false
|
|
40763
|
+
},
|
|
40764
|
+
sampling: { temperature: 0.7 },
|
|
40765
|
+
compaction: { ...SHARED_COMPACTION },
|
|
40766
|
+
profile: "glm"
|
|
40767
|
+
});
|
|
40768
|
+
DEEPSEEK_RE = /^deepseek-(?:v4(?:\.|-|$)|chat$|reasoner$)/i;
|
|
40769
|
+
GROK_RE = /^grok(?:\.|-|$)/i;
|
|
40770
|
+
MINIMAX_RE = /^minimax(?:\.|-|$)/i;
|
|
40771
|
+
MINIMAX_M3_RE = /^minimax-m3(?:\.|-|$)/i;
|
|
40772
|
+
GLM_RE = /^glm(?:\.|-|$)/i;
|
|
40773
|
+
}
|
|
40774
|
+
});
|
|
40775
|
+
|
|
40776
|
+
// src/cli/provider/sse.ts
|
|
40777
|
+
var SseDataDecoder;
|
|
40778
|
+
var init_sse = __esm({
|
|
40779
|
+
"src/cli/provider/sse.ts"() {
|
|
40780
|
+
"use strict";
|
|
40781
|
+
SseDataDecoder = class {
|
|
40782
|
+
lineBuffer = "";
|
|
40783
|
+
dataLines = [];
|
|
40784
|
+
firstText = true;
|
|
40785
|
+
push(text, final = false) {
|
|
40786
|
+
if (this.firstText) {
|
|
40787
|
+
this.firstText = false;
|
|
40788
|
+
if (text.charCodeAt(0) === 65279) text = text.slice(1);
|
|
40789
|
+
}
|
|
40790
|
+
this.lineBuffer += text;
|
|
40791
|
+
const lines = this.lineBuffer.split("\n");
|
|
40792
|
+
this.lineBuffer = final ? "" : lines.pop() ?? "";
|
|
40793
|
+
const events = [];
|
|
40794
|
+
for (const rawLine of lines) {
|
|
40795
|
+
this.acceptLine(rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine, events);
|
|
40796
|
+
}
|
|
40797
|
+
if (final) {
|
|
40798
|
+
if (this.lineBuffer.length > 0) {
|
|
40799
|
+
this.acceptLine(
|
|
40800
|
+
this.lineBuffer.endsWith("\r") ? this.lineBuffer.slice(0, -1) : this.lineBuffer,
|
|
40801
|
+
events
|
|
40802
|
+
);
|
|
40803
|
+
this.lineBuffer = "";
|
|
40804
|
+
}
|
|
40805
|
+
this.dispatch(events);
|
|
40806
|
+
}
|
|
40807
|
+
return events;
|
|
40808
|
+
}
|
|
40809
|
+
acceptLine(line, events) {
|
|
40810
|
+
if (line.length === 0) {
|
|
40811
|
+
this.dispatch(events);
|
|
40812
|
+
return;
|
|
40813
|
+
}
|
|
40814
|
+
if (line.startsWith(":")) return;
|
|
40815
|
+
const colon = line.indexOf(":");
|
|
40816
|
+
const field = colon < 0 ? line : line.slice(0, colon);
|
|
40817
|
+
if (field !== "data") return;
|
|
40818
|
+
let value = colon < 0 ? "" : line.slice(colon + 1);
|
|
40819
|
+
if (value.startsWith(" ")) value = value.slice(1);
|
|
40820
|
+
this.dataLines.push(value);
|
|
40821
|
+
}
|
|
40822
|
+
dispatch(events) {
|
|
40823
|
+
if (this.dataLines.length === 0) return;
|
|
40824
|
+
events.push(this.dataLines.join("\n"));
|
|
40825
|
+
this.dataLines = [];
|
|
40826
|
+
}
|
|
40827
|
+
};
|
|
40516
40828
|
}
|
|
40517
40829
|
});
|
|
40518
40830
|
|
|
@@ -40524,12 +40836,14 @@ __export(openai_compatible_exports, {
|
|
|
40524
40836
|
modelSupportsVision: () => modelSupportsVision,
|
|
40525
40837
|
openaiCompatibleProvider: () => openaiCompatibleProvider,
|
|
40526
40838
|
parseCachedPromptTokens: () => parseCachedPromptTokens,
|
|
40839
|
+
parseOpenAiStreamError: () => parseOpenAiStreamError,
|
|
40527
40840
|
providerConfigFor: () => providerConfigFor,
|
|
40528
40841
|
providerFromEnv: () => providerFromEnv,
|
|
40529
40842
|
readChunkWithTimeout: () => readChunkWithTimeout,
|
|
40530
40843
|
resolveActiveProvider: () => resolveActiveProvider,
|
|
40531
40844
|
resolveBaseUrl: () => resolveBaseUrl
|
|
40532
40845
|
});
|
|
40846
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
40533
40847
|
function abortableSleep(ms, signal) {
|
|
40534
40848
|
return new Promise((resolve7) => {
|
|
40535
40849
|
if (signal?.aborted) return resolve7();
|
|
@@ -40573,9 +40887,10 @@ async function readChunkWithTimeout(reader, opts) {
|
|
|
40573
40887
|
reader.read(),
|
|
40574
40888
|
new Promise((_, reject) => {
|
|
40575
40889
|
idleTimer = setTimeout(() => {
|
|
40890
|
+
const totalIdleMs = Math.max(opts.idleMs, Date.now() - opts.lastUsefulAt());
|
|
40576
40891
|
reject(
|
|
40577
40892
|
new Error(
|
|
40578
|
-
`Provider stream idle for ${Math.round(
|
|
40893
|
+
`Provider stream idle for ${Math.round(totalIdleMs / 1e3)}s (no useful deltas). The model/gateway stalled \u2014 try again or switch model. Override with ZELARI_PROVIDER_STREAM_IDLE_MS.`
|
|
40579
40894
|
)
|
|
40580
40895
|
);
|
|
40581
40896
|
}, waitMs);
|
|
@@ -40623,6 +40938,22 @@ function parseCachedPromptTokens(usage) {
|
|
|
40623
40938
|
}
|
|
40624
40939
|
return 0;
|
|
40625
40940
|
}
|
|
40941
|
+
function parseOpenAiStreamError(value) {
|
|
40942
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
40943
|
+
const root = value;
|
|
40944
|
+
const nested = root.error;
|
|
40945
|
+
if (nested && typeof nested === "object" && !Array.isArray(nested)) {
|
|
40946
|
+
const error51 = nested;
|
|
40947
|
+
const message = typeof error51.message === "string" && error51.message.trim() ? error51.message.trim() : "unknown error";
|
|
40948
|
+
const type = typeof error51.type === "string" && error51.type.trim() ? error51.type.trim() : "server_error";
|
|
40949
|
+
return `Provider stream error (${type}): ${message}`;
|
|
40950
|
+
}
|
|
40951
|
+
if (typeof nested === "string" && nested.trim()) {
|
|
40952
|
+
const type = typeof root.code === "string" && root.code.trim() ? root.code.trim() : "server_error";
|
|
40953
|
+
return `Provider stream error (${type}): ${nested.trim()}`;
|
|
40954
|
+
}
|
|
40955
|
+
return null;
|
|
40956
|
+
}
|
|
40626
40957
|
function resolveBaseUrl(providerId) {
|
|
40627
40958
|
const custom2 = getCustomEndpoint(providerId);
|
|
40628
40959
|
if (custom2) return custom2;
|
|
@@ -40700,7 +41031,8 @@ ${notes}
|
|
|
40700
41031
|
return { role: m.role, content: m.content };
|
|
40701
41032
|
}
|
|
40702
41033
|
function openaiCompatibleProvider(config2) {
|
|
40703
|
-
|
|
41034
|
+
const run = async function* (params, streamRetryAttempt = 0) {
|
|
41035
|
+
const capabilities = capabilitiesFor(params.model, config2.providerId);
|
|
40704
41036
|
const vision = modelSupportsVision(params.model);
|
|
40705
41037
|
const messages = params.messages.map((m) => {
|
|
40706
41038
|
const cacheable = !(m.role === "user" && m.images && m.images.length > 0);
|
|
@@ -40720,7 +41052,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
40720
41052
|
model: params.model,
|
|
40721
41053
|
messages,
|
|
40722
41054
|
stream: true,
|
|
40723
|
-
temperature: generation?.temperature ??
|
|
41055
|
+
temperature: generation?.temperature ?? capabilities.sampling.temperature,
|
|
40724
41056
|
// Task G.4.2 — request the provider to send real token usage in
|
|
40725
41057
|
// the final chunk (gated by `stream_options.include_usage` on the
|
|
40726
41058
|
// OpenAI-compatible API). Providers that don't honor this (some
|
|
@@ -40756,7 +41088,31 @@ function openaiCompatibleProvider(config2) {
|
|
|
40756
41088
|
parameters: t.parameters
|
|
40757
41089
|
}
|
|
40758
41090
|
}));
|
|
40759
|
-
|
|
41091
|
+
const recoveryAttempt = generation?.recoveryAttempt ?? 1;
|
|
41092
|
+
const forceRecoveryTool = generation?.toolChoice === "required" && capabilities.buildRecovery.forceToolChoice && recoveryAttempt <= capabilities.buildRecovery.maxForcedTurns;
|
|
41093
|
+
if (forceRecoveryTool) {
|
|
41094
|
+
body.tool_choice = "required";
|
|
41095
|
+
} else if (!capabilities.wire.omitAutoToolChoice) {
|
|
41096
|
+
body.tool_choice = "auto";
|
|
41097
|
+
}
|
|
41098
|
+
}
|
|
41099
|
+
const headers2 = {
|
|
41100
|
+
"Content-Type": "application/json",
|
|
41101
|
+
Authorization: `Bearer ${config2.apiKey}`,
|
|
41102
|
+
...config2.extraHeaders ?? {}
|
|
41103
|
+
};
|
|
41104
|
+
const affinityHeader = capabilities.promptCache.conversationAffinityHeader;
|
|
41105
|
+
const conversationId = params.conversationId?.trim();
|
|
41106
|
+
const safeConversationId = conversationId && conversationId.length <= 256 && !/[\u0000-\u001f\u007f]/.test(conversationId) ? conversationId : void 0;
|
|
41107
|
+
if (affinityHeader && safeConversationId) {
|
|
41108
|
+
headers2[affinityHeader] = safeConversationId;
|
|
41109
|
+
}
|
|
41110
|
+
if (capabilities.wire.grokRequestHeaders) {
|
|
41111
|
+
headers2.Accept = "text/event-stream";
|
|
41112
|
+
headers2["x-grok-client-identifier"] = "zelari-code";
|
|
41113
|
+
headers2["x-grok-req-id"] = `zelari-${randomUUID2()}`;
|
|
41114
|
+
headers2["x-grok-model-override"] = params.model;
|
|
41115
|
+
if (safeConversationId) headers2["x-grok-session-id"] = safeConversationId;
|
|
40760
41116
|
}
|
|
40761
41117
|
let response;
|
|
40762
41118
|
let lastErrText = "";
|
|
@@ -40781,10 +41137,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
40781
41137
|
try {
|
|
40782
41138
|
response = await fetch(`${config2.baseUrl}/chat/completions`, {
|
|
40783
41139
|
method: "POST",
|
|
40784
|
-
headers:
|
|
40785
|
-
"Content-Type": "application/json",
|
|
40786
|
-
Authorization: `Bearer ${config2.apiKey}`
|
|
40787
|
-
},
|
|
41140
|
+
headers: headers2,
|
|
40788
41141
|
body: JSON.stringify(body),
|
|
40789
41142
|
// Cancel aborts the HTTP request; stream idle is enforced below
|
|
40790
41143
|
// per-chunk so active multi-minute streams are not killed.
|
|
@@ -40827,9 +41180,10 @@ function openaiCompatibleProvider(config2) {
|
|
|
40827
41180
|
}
|
|
40828
41181
|
const reader = response.body.getReader();
|
|
40829
41182
|
const decoder = new TextDecoder();
|
|
40830
|
-
|
|
41183
|
+
const sseDecoder = new SseDataDecoder();
|
|
40831
41184
|
const toolCallAccumulator = /* @__PURE__ */ new Map();
|
|
40832
41185
|
let emittedToolCall = false;
|
|
41186
|
+
let emittedProviderDelta = false;
|
|
40833
41187
|
let reasoningDetailsBuf = "";
|
|
40834
41188
|
const tryParseArgs = (raw) => {
|
|
40835
41189
|
const t = raw.trim();
|
|
@@ -40852,6 +41206,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
40852
41206
|
if (args === null) continue;
|
|
40853
41207
|
toolCallAccumulator.delete(idx);
|
|
40854
41208
|
emittedToolCall = true;
|
|
41209
|
+
emittedProviderDelta = true;
|
|
40855
41210
|
markUseful();
|
|
40856
41211
|
yield {
|
|
40857
41212
|
kind: "tool_call",
|
|
@@ -40887,18 +41242,19 @@ function openaiCompatibleProvider(config2) {
|
|
|
40887
41242
|
await reader.cancel(msg);
|
|
40888
41243
|
} catch {
|
|
40889
41244
|
}
|
|
41245
|
+
if (!emittedProviderDelta && streamRetryAttempt < capabilities.wire.retriesBeforeOutput) {
|
|
41246
|
+
await abortableSleep(backoffDelay(streamRetryAttempt, null), params.signal);
|
|
41247
|
+
yield* run(params, streamRetryAttempt + 1);
|
|
41248
|
+
return;
|
|
41249
|
+
}
|
|
40890
41250
|
yield { kind: "error", message: msg };
|
|
40891
41251
|
return;
|
|
40892
41252
|
}
|
|
40893
41253
|
const { value, done } = chunk;
|
|
40894
|
-
|
|
40895
|
-
|
|
40896
|
-
const
|
|
40897
|
-
|
|
40898
|
-
for (const line of lines) {
|
|
40899
|
-
const trimmed = line.trim();
|
|
40900
|
-
if (!trimmed.startsWith("data:")) continue;
|
|
40901
|
-
const data = trimmed.slice(5).trim();
|
|
41254
|
+
const decoded = done ? decoder.decode() : decoder.decode(value, { stream: true });
|
|
41255
|
+
const events = sseDecoder.push(decoded, done);
|
|
41256
|
+
for (const data of events) {
|
|
41257
|
+
if (data.length === 0) continue;
|
|
40902
41258
|
if (data === "[DONE]") {
|
|
40903
41259
|
yield* flushToolAccumulator();
|
|
40904
41260
|
yield {
|
|
@@ -40908,7 +41264,22 @@ function openaiCompatibleProvider(config2) {
|
|
|
40908
41264
|
return;
|
|
40909
41265
|
}
|
|
40910
41266
|
try {
|
|
40911
|
-
const
|
|
41267
|
+
const rawParsed = JSON.parse(data);
|
|
41268
|
+
const streamError = parseOpenAiStreamError(rawParsed);
|
|
41269
|
+
if (streamError) {
|
|
41270
|
+
try {
|
|
41271
|
+
await reader.cancel(streamError);
|
|
41272
|
+
} catch {
|
|
41273
|
+
}
|
|
41274
|
+
if (!emittedProviderDelta && streamRetryAttempt < capabilities.wire.retriesBeforeOutput) {
|
|
41275
|
+
await abortableSleep(backoffDelay(streamRetryAttempt, null), params.signal);
|
|
41276
|
+
yield* run(params, streamRetryAttempt + 1);
|
|
41277
|
+
return;
|
|
41278
|
+
}
|
|
41279
|
+
yield { kind: "error", message: streamError };
|
|
41280
|
+
return;
|
|
41281
|
+
}
|
|
41282
|
+
const parsed = rawParsed;
|
|
40912
41283
|
const choice = parsed.choices?.[0];
|
|
40913
41284
|
const delta = choice?.delta;
|
|
40914
41285
|
if (parsed.usage && typeof parsed.usage === "object") {
|
|
@@ -40917,6 +41288,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
40917
41288
|
const totalTokens = typeof parsed.usage.total_tokens === "number" ? parsed.usage.total_tokens : promptTokens + completionTokens;
|
|
40918
41289
|
const cachedPromptTokens = parseCachedPromptTokens(parsed.usage);
|
|
40919
41290
|
markUseful();
|
|
41291
|
+
emittedProviderDelta = true;
|
|
40920
41292
|
yield {
|
|
40921
41293
|
kind: "usage",
|
|
40922
41294
|
usage: {
|
|
@@ -40929,11 +41301,13 @@ function openaiCompatibleProvider(config2) {
|
|
|
40929
41301
|
}
|
|
40930
41302
|
if (typeof delta?.content === "string" && delta.content.length > 0) {
|
|
40931
41303
|
markUseful();
|
|
41304
|
+
emittedProviderDelta = true;
|
|
40932
41305
|
yield { kind: "text", delta: delta.content };
|
|
40933
41306
|
}
|
|
40934
41307
|
const reasoning = delta?.reasoning_content ?? delta?.reasoning;
|
|
40935
41308
|
if (typeof reasoning === "string" && reasoning.length > 0) {
|
|
40936
41309
|
markUseful();
|
|
41310
|
+
emittedProviderDelta = true;
|
|
40937
41311
|
yield { kind: "thinking", delta: reasoning };
|
|
40938
41312
|
}
|
|
40939
41313
|
const details = delta?.reasoning_details;
|
|
@@ -40947,16 +41321,21 @@ function openaiCompatibleProvider(config2) {
|
|
|
40947
41321
|
reasoningDetailsBuf = t;
|
|
40948
41322
|
if (piece.length > 0) {
|
|
40949
41323
|
markUseful();
|
|
41324
|
+
emittedProviderDelta = true;
|
|
40950
41325
|
yield { kind: "thinking", delta: piece };
|
|
40951
41326
|
}
|
|
40952
41327
|
} else {
|
|
40953
41328
|
reasoningDetailsBuf += t;
|
|
40954
41329
|
markUseful();
|
|
41330
|
+
emittedProviderDelta = true;
|
|
40955
41331
|
yield { kind: "thinking", delta: t };
|
|
40956
41332
|
}
|
|
40957
41333
|
}
|
|
40958
41334
|
}
|
|
40959
41335
|
if (Array.isArray(delta?.tool_calls)) {
|
|
41336
|
+
if (capabilities.wire.toolCallDeltasResetIdle && delta.tool_calls.length > 0) {
|
|
41337
|
+
markUseful();
|
|
41338
|
+
}
|
|
40960
41339
|
for (const tc of delta.tool_calls) {
|
|
40961
41340
|
const idx = tc.index ?? 0;
|
|
40962
41341
|
const existing = toolCallAccumulator.get(idx) ?? {
|
|
@@ -40973,12 +41352,21 @@ function openaiCompatibleProvider(config2) {
|
|
|
40973
41352
|
if (choice?.finish_reason) {
|
|
40974
41353
|
yield* flushToolAccumulator();
|
|
40975
41354
|
markUseful();
|
|
41355
|
+
emittedProviderDelta = true;
|
|
40976
41356
|
const reason = choice.finish_reason === "stop" && emittedToolCall ? "tool_calls" : choice.finish_reason;
|
|
40977
41357
|
yield { kind: "finish", reason };
|
|
40978
41358
|
}
|
|
40979
41359
|
} catch {
|
|
41360
|
+
if (capabilities.wire.strictSseJson) {
|
|
41361
|
+
yield {
|
|
41362
|
+
kind: "error",
|
|
41363
|
+
message: "Malformed Grok SSE data event (expected Chat Completions JSON)."
|
|
41364
|
+
};
|
|
41365
|
+
return;
|
|
41366
|
+
}
|
|
40980
41367
|
}
|
|
40981
41368
|
}
|
|
41369
|
+
if (done) break;
|
|
40982
41370
|
}
|
|
40983
41371
|
yield* flushToolAccumulator();
|
|
40984
41372
|
yield {
|
|
@@ -40989,6 +41377,7 @@ function openaiCompatibleProvider(config2) {
|
|
|
40989
41377
|
reader.releaseLock();
|
|
40990
41378
|
}
|
|
40991
41379
|
};
|
|
41380
|
+
return (params) => run(params);
|
|
40992
41381
|
}
|
|
40993
41382
|
function extraFromStored(providerId) {
|
|
40994
41383
|
const stored = getOAuthToken(providerId);
|
|
@@ -41031,6 +41420,7 @@ var init_openai_compatible = __esm({
|
|
|
41031
41420
|
init_providerConfig();
|
|
41032
41421
|
init_thinking();
|
|
41033
41422
|
init_capabilities();
|
|
41423
|
+
init_sse();
|
|
41034
41424
|
RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
41035
41425
|
MAX_RETRIES = (() => {
|
|
41036
41426
|
const raw = process.env.ZELARI_PROVIDER_MAX_RETRIES;
|
|
@@ -44009,11 +44399,11 @@ var init_metrics3 = __esm({
|
|
|
44009
44399
|
});
|
|
44010
44400
|
|
|
44011
44401
|
// src/cli/state/fileStateStore.ts
|
|
44012
|
-
import { createHash as createHash13, randomUUID as
|
|
44402
|
+
import { createHash as createHash13, randomUUID as randomUUID3 } from "node:crypto";
|
|
44013
44403
|
import { promises as fs21 } from "node:fs";
|
|
44014
44404
|
import * as path43 from "node:path";
|
|
44015
44405
|
function shortId() {
|
|
44016
|
-
return
|
|
44406
|
+
return randomUUID3().replace(/-/g, "").slice(0, 12);
|
|
44017
44407
|
}
|
|
44018
44408
|
async function writeJsonAtomic(filePath, data) {
|
|
44019
44409
|
await fs21.mkdir(path43.dirname(filePath), { recursive: true });
|
|
@@ -44946,7 +45336,7 @@ function expectsDiskImplementation(task, phase2, prior) {
|
|
|
44946
45336
|
const trimmed = task.trim();
|
|
44947
45337
|
if (!trimmed) return false;
|
|
44948
45338
|
if (isShortContinueReply(trimmed)) return true;
|
|
44949
|
-
if (/\b(implement|
|
|
45339
|
+
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
45340
|
trimmed
|
|
44951
45341
|
)) {
|
|
44952
45342
|
return true;
|
|
@@ -46380,7 +46770,7 @@ WHERE NOT EXISTS (SELECT 1 FROM memory_fts f WHERE f.node_id = n.id);
|
|
|
46380
46770
|
});
|
|
46381
46771
|
|
|
46382
46772
|
// src/cli/memory/sqliteBackend.ts
|
|
46383
|
-
import { createHash as createHash15, randomUUID as
|
|
46773
|
+
import { createHash as createHash15, randomUUID as randomUUID4 } from "node:crypto";
|
|
46384
46774
|
import { promises as fs23 } from "node:fs";
|
|
46385
46775
|
import * as path46 from "node:path";
|
|
46386
46776
|
function boundedLimit(value, fallback = 50) {
|
|
@@ -46503,7 +46893,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46503
46893
|
const createdAt = input.createdAt ?? now;
|
|
46504
46894
|
const recordedAt = input.recordedAt ?? createdAt;
|
|
46505
46895
|
const node = MemoryNodeSchema.parse({
|
|
46506
|
-
id: input.id ?? `mem_${
|
|
46896
|
+
id: input.id ?? `mem_${randomUUID4()}`,
|
|
46507
46897
|
schemaVersion: 1,
|
|
46508
46898
|
projectId: input.projectId,
|
|
46509
46899
|
kind: input.kind,
|
|
@@ -46529,7 +46919,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46529
46919
|
(version_id, memory_id, revision, snapshot_json, recorded_at, actor, reason)
|
|
46530
46920
|
VALUES (?, ?, 1, ?, ?, ?, ?)`,
|
|
46531
46921
|
params: [
|
|
46532
|
-
`ver_${
|
|
46922
|
+
`ver_${randomUUID4()}`,
|
|
46533
46923
|
node.id,
|
|
46534
46924
|
JSON.stringify(node),
|
|
46535
46925
|
recordedAt,
|
|
@@ -46590,7 +46980,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46590
46980
|
(version_id, memory_id, revision, snapshot_json, recorded_at, actor, reason)
|
|
46591
46981
|
VALUES (?, ?, (SELECT COALESCE(MAX(revision), 0) + 1 FROM memory_versions WHERE memory_id=?), ?, ?, ?, ?)`,
|
|
46592
46982
|
params: [
|
|
46593
|
-
`ver_${
|
|
46983
|
+
`ver_${randomUUID4()}`,
|
|
46594
46984
|
updated.id,
|
|
46595
46985
|
updated.id,
|
|
46596
46986
|
JSON.stringify(updated),
|
|
@@ -46824,7 +47214,7 @@ VALUES (${Array.from({ length: 19 }, () => "?").join(",")})`;
|
|
|
46824
47214
|
if (decoded) return decoded;
|
|
46825
47215
|
const edge = MemoryEdgeSchema.parse({
|
|
46826
47216
|
...input,
|
|
46827
|
-
id: input.id ?? `edge_${
|
|
47217
|
+
id: input.id ?? `edge_${randomUUID4()}`,
|
|
46828
47218
|
strength: input.strength ?? 1,
|
|
46829
47219
|
confidence: input.confidence ?? 0.8,
|
|
46830
47220
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -50207,7 +50597,7 @@ import { promisify as promisify2 } from "node:util";
|
|
|
50207
50597
|
import { mkdtempSync, rmSync as rmSync2 } from "node:fs";
|
|
50208
50598
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
50209
50599
|
import path49 from "node:path";
|
|
50210
|
-
import { randomUUID as
|
|
50600
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
50211
50601
|
async function git3(cwd, args, env) {
|
|
50212
50602
|
const { stdout } = await execFileAsync2("git", ["-C", cwd, ...args], {
|
|
50213
50603
|
maxBuffer: 64 * 1024 * 1024,
|
|
@@ -50250,7 +50640,7 @@ async function createCheckpoint(cwd, label = "checkpoint") {
|
|
|
50250
50640
|
}
|
|
50251
50641
|
try {
|
|
50252
50642
|
const { tree, head } = await snapshotTree(cwd);
|
|
50253
|
-
const id3 =
|
|
50643
|
+
const id3 = randomUUID5().slice(0, 8);
|
|
50254
50644
|
const createdAt = Date.now();
|
|
50255
50645
|
const message = `zelari-checkpoint ${id3}: ${label}`;
|
|
50256
50646
|
const commitArgs = ["commit-tree", tree, "-m", message];
|
|
@@ -50417,7 +50807,7 @@ __export(fileBackend_exports, {
|
|
|
50417
50807
|
getMemoryBackend: () => getMemoryBackend,
|
|
50418
50808
|
isMemoryEnabled: () => isMemoryEnabled
|
|
50419
50809
|
});
|
|
50420
|
-
import { randomUUID as
|
|
50810
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
50421
50811
|
import { promises as fs26 } from "node:fs";
|
|
50422
50812
|
import * as path50 from "node:path";
|
|
50423
50813
|
function tokenize(text) {
|
|
@@ -50476,7 +50866,7 @@ var init_fileBackend = __esm({
|
|
|
50476
50866
|
}
|
|
50477
50867
|
async add(content, metadata2 = {}, graph) {
|
|
50478
50868
|
const fact = {
|
|
50479
|
-
id:
|
|
50869
|
+
id: randomUUID6(),
|
|
50480
50870
|
content,
|
|
50481
50871
|
metadata: metadata2,
|
|
50482
50872
|
...graph ? { graph } : {},
|
|
@@ -50584,7 +50974,7 @@ __export(zelariMission_exports, {
|
|
|
50584
50974
|
resolveMaxTokens: () => resolveMaxTokens,
|
|
50585
50975
|
runZelariMission: () => runZelariMission
|
|
50586
50976
|
});
|
|
50587
|
-
import { randomUUID as
|
|
50977
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
50588
50978
|
import { promises as fs28 } from "node:fs";
|
|
50589
50979
|
import * as path52 from "node:path";
|
|
50590
50980
|
function resolveMaxIterations(env = process.env) {
|
|
@@ -50681,7 +51071,7 @@ async function runZelariMission(userMessage, brief, deps) {
|
|
|
50681
51071
|
const maxStall = resolveMaxStall(deps.env);
|
|
50682
51072
|
const maxCost = resolveMaxCost(deps.env);
|
|
50683
51073
|
const maxTokens = resolveMaxTokens(deps.env);
|
|
50684
|
-
const missionId = deps.missionId ?? `m_${
|
|
51074
|
+
const missionId = deps.missionId ?? `m_${randomUUID7().slice(0, 8)}`;
|
|
50685
51075
|
const startedAt = now().toISOString();
|
|
50686
51076
|
const state3 = {
|
|
50687
51077
|
missionId,
|
|
@@ -51129,6 +51519,7 @@ async function runAgentMissionSlice(deps) {
|
|
|
51129
51519
|
tools: toolSpecs,
|
|
51130
51520
|
toolRegistry: deps.toolRegistry,
|
|
51131
51521
|
providerStream: deps.providerStream,
|
|
51522
|
+
buildLiveness: { mutationRequired: writeRetry, maxRecoveries: 2 },
|
|
51132
51523
|
cwd: deps.projectRoot,
|
|
51133
51524
|
maxToolCallsPerTurn: maxToolCalls,
|
|
51134
51525
|
maxToolLoopIterations: maxToolLoop,
|
|
@@ -57212,7 +57603,7 @@ var init_mcpCli = __esm({
|
|
|
57212
57603
|
|
|
57213
57604
|
// src/cli/mcp/mcpPermissionServer.ts
|
|
57214
57605
|
import { createInterface as createInterface2 } from "node:readline";
|
|
57215
|
-
import { randomUUID as
|
|
57606
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
57216
57607
|
function startPermissionMcpServer(opts) {
|
|
57217
57608
|
const socketPath = opts.socketPath.trim();
|
|
57218
57609
|
const requestTimeoutMs = opts.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
@@ -57308,7 +57699,7 @@ function startPermissionMcpServer(opts) {
|
|
|
57308
57699
|
socketPath,
|
|
57309
57700
|
{
|
|
57310
57701
|
t: "ask",
|
|
57311
|
-
id:
|
|
57702
|
+
id: randomUUID9(),
|
|
57312
57703
|
kind: "permission",
|
|
57313
57704
|
tool: toolName,
|
|
57314
57705
|
input: input2,
|
|
@@ -57347,7 +57738,7 @@ function startPermissionMcpServer(opts) {
|
|
|
57347
57738
|
socketPath,
|
|
57348
57739
|
{
|
|
57349
57740
|
t: "ask",
|
|
57350
|
-
id:
|
|
57741
|
+
id: randomUUID9(),
|
|
57351
57742
|
kind: "question",
|
|
57352
57743
|
question,
|
|
57353
57744
|
choices,
|
|
@@ -57639,7 +58030,7 @@ var init_config = __esm({
|
|
|
57639
58030
|
// src/cli/companion/runManager.ts
|
|
57640
58031
|
import { spawn as spawn17 } from "node:child_process";
|
|
57641
58032
|
import { createInterface as createInterface3 } from "node:readline";
|
|
57642
|
-
import { randomUUID as
|
|
58033
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
57643
58034
|
import { writeFileSync as writeFileSync26, unlinkSync as unlinkSync3 } from "node:fs";
|
|
57644
58035
|
import { join as join44 } from "node:path";
|
|
57645
58036
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
@@ -57708,7 +58099,7 @@ var init_runManager = __esm({
|
|
|
57708
58099
|
}
|
|
57709
58100
|
const prompt = args.prompt?.trim();
|
|
57710
58101
|
if (!prompt) return { ok: false, error: "prompt is required" };
|
|
57711
|
-
const id3 =
|
|
58102
|
+
const id3 = randomUUID10();
|
|
57712
58103
|
const mode = (args.mode || "kraken").toLowerCase();
|
|
57713
58104
|
const phase2 = (args.phase || "build").toLowerCase();
|
|
57714
58105
|
const run = {
|
|
@@ -62658,12 +63049,12 @@ function estimateHistoryTokens(messages) {
|
|
|
62658
63049
|
}
|
|
62659
63050
|
return n;
|
|
62660
63051
|
}
|
|
62661
|
-
function defaultContextLimitForModel(model) {
|
|
62662
|
-
return capabilitiesFor(model).contextWindow;
|
|
63052
|
+
function defaultContextLimitForModel(model, provider) {
|
|
63053
|
+
return capabilitiesFor(model, provider).contextWindow;
|
|
62663
63054
|
}
|
|
62664
|
-
function resolveContextLimit(model) {
|
|
63055
|
+
function resolveContextLimit(model, provider) {
|
|
62665
63056
|
return envNumber(process.env.ZELARI_CONTEXT_LIMIT, {
|
|
62666
|
-
default: defaultContextLimitForModel(model),
|
|
63057
|
+
default: defaultContextLimitForModel(model, provider),
|
|
62667
63058
|
min: 4e3,
|
|
62668
63059
|
max: 2e6
|
|
62669
63060
|
});
|
|
@@ -62679,8 +63070,8 @@ function phaseKnobs(phase2) {
|
|
|
62679
63070
|
}
|
|
62680
63071
|
var RESERVED_OUTPUT_TOKENS = 8192;
|
|
62681
63072
|
async function applyBudgetPolicyAsync(history2, phase2, opts) {
|
|
62682
|
-
const contextLimit = resolveContextLimit(opts?.model);
|
|
62683
|
-
const compact3 = capabilitiesFor(opts?.model).compaction;
|
|
63073
|
+
const contextLimit = resolveContextLimit(opts?.model, opts?.provider);
|
|
63074
|
+
const compact3 = capabilitiesFor(opts?.model, opts?.provider).compaction;
|
|
62684
63075
|
const sessionExtra = opts?.sessionTokens ?? 0;
|
|
62685
63076
|
const warnings = [];
|
|
62686
63077
|
let { historyTurns, maxToolLoopIterations } = phaseKnobs(phase2);
|
|
@@ -62955,8 +63346,11 @@ function messageWasRecompacted(message, history2) {
|
|
|
62955
63346
|
if (message.compactedFromSeq === void 0) return false;
|
|
62956
63347
|
return !history2.some((candidate) => candidate.seq !== void 0 && candidate.seq === message.seq);
|
|
62957
63348
|
}
|
|
62958
|
-
function
|
|
62959
|
-
return { role: "system", content: formatResourceSnapshot(payload) };
|
|
63349
|
+
function resourceStatusTail(payload) {
|
|
63350
|
+
return payload ? [{ role: "system", content: formatResourceSnapshot(payload) }] : [];
|
|
63351
|
+
}
|
|
63352
|
+
function isLegacyResourceStatus(message) {
|
|
63353
|
+
return message.role === "system" && message.content.startsWith("RESOURCE STATUS");
|
|
62960
63354
|
}
|
|
62961
63355
|
async function sessionHistory(session) {
|
|
62962
63356
|
if (!session || session.status !== "active") return null;
|
|
@@ -62967,7 +63361,10 @@ async function sessionHistory(session) {
|
|
|
62967
63361
|
async function buildModelContext(input) {
|
|
62968
63362
|
const derived = await sessionHistory(input.session);
|
|
62969
63363
|
const source2 = derived ? "session" : "fallback";
|
|
62970
|
-
const sourceHistory = derived ?? [...input.fallbackHistory]
|
|
63364
|
+
const sourceHistory = (derived ?? [...input.fallbackHistory]).filter(
|
|
63365
|
+
(message) => !isLegacyResourceStatus(message)
|
|
63366
|
+
);
|
|
63367
|
+
const requestTail = resourceStatusTail(input.resourceSnapshot);
|
|
62971
63368
|
const inputTokens = estimateHistoryTokens(sourceHistory);
|
|
62972
63369
|
const requestSurface = input.systemMessages || input.tools ? {
|
|
62973
63370
|
provider: input.provider ?? "local",
|
|
@@ -62977,7 +63374,8 @@ async function buildModelContext(input) {
|
|
|
62977
63374
|
} : null;
|
|
62978
63375
|
let budget = await applyBudgetPolicyAsync(sourceHistory, input.phase, {
|
|
62979
63376
|
model: input.model,
|
|
62980
|
-
|
|
63377
|
+
provider: input.provider,
|
|
63378
|
+
sessionTokens: (input.sessionTokens ?? 0) + estimateHistoryTokens(requestTail),
|
|
62981
63379
|
sessionId: input.sessionId,
|
|
62982
63380
|
signal: input.signal,
|
|
62983
63381
|
requestSnapshot: input.requestSnapshot,
|
|
@@ -63024,16 +63422,11 @@ async function buildModelContext(input) {
|
|
|
63024
63422
|
};
|
|
63025
63423
|
input.onCompactionMetric?.(compactionMetrics);
|
|
63026
63424
|
}
|
|
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
63425
|
if (requestSurface) {
|
|
63033
63426
|
const measured = measureRequest({
|
|
63034
63427
|
systemMessages: requestSurface.systemMessages,
|
|
63035
63428
|
tools: requestSurface.tools,
|
|
63036
|
-
conversation: history2,
|
|
63429
|
+
conversation: [...history2, ...requestTail],
|
|
63037
63430
|
anchor: input.requestSnapshot,
|
|
63038
63431
|
contextLimit: budget.contextLimit,
|
|
63039
63432
|
reservedOutputTokens: 8192
|
|
@@ -63046,7 +63439,7 @@ async function buildModelContext(input) {
|
|
|
63046
63439
|
contextPressureTokens: measured.contextPressureTokens
|
|
63047
63440
|
};
|
|
63048
63441
|
} else {
|
|
63049
|
-
const estimated = estimateHistoryTokens(history2);
|
|
63442
|
+
const estimated = estimateHistoryTokens([...history2, ...requestTail]);
|
|
63050
63443
|
budget = {
|
|
63051
63444
|
...budget,
|
|
63052
63445
|
history: history2,
|
|
@@ -63056,6 +63449,7 @@ async function buildModelContext(input) {
|
|
|
63056
63449
|
}
|
|
63057
63450
|
return {
|
|
63058
63451
|
history: history2,
|
|
63452
|
+
requestTail,
|
|
63059
63453
|
budget,
|
|
63060
63454
|
source: source2,
|
|
63061
63455
|
...compactionPayload ? { compactionPayload } : {},
|
|
@@ -63476,6 +63870,17 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
63476
63870
|
})),
|
|
63477
63871
|
toolRegistry,
|
|
63478
63872
|
providerStream,
|
|
63873
|
+
buildLiveness: {
|
|
63874
|
+
mutationRequired: expectsDiskImplementation(
|
|
63875
|
+
userText,
|
|
63876
|
+
workPhase,
|
|
63877
|
+
historyForModel
|
|
63878
|
+
),
|
|
63879
|
+
maxRecoveries: 2
|
|
63880
|
+
},
|
|
63881
|
+
requestTail: () => resourceStatusTail(
|
|
63882
|
+
writerRef.current?.spine?.latestResourceSnapshot() ?? null
|
|
63883
|
+
),
|
|
63479
63884
|
// 2.6 Phase 3: host-owned pre-dispatch resource gate via the spine
|
|
63480
63885
|
// mirror (doc section 11.3). Degrade-and-stop (null gate = allow).
|
|
63481
63886
|
// 2.6.1 (plan §13): argument-aware — bash is essential only when
|
|
@@ -69243,7 +69648,6 @@ init_harness();
|
|
|
69243
69648
|
init_dist();
|
|
69244
69649
|
init_events2();
|
|
69245
69650
|
init_conversationContext();
|
|
69246
|
-
init_council();
|
|
69247
69651
|
init_toolRegistry();
|
|
69248
69652
|
init_candidateRegistry();
|
|
69249
69653
|
init_metrics2();
|
|
@@ -69287,7 +69691,7 @@ init_taskTool();
|
|
|
69287
69691
|
init_sessionTodos();
|
|
69288
69692
|
import { promises as fs41 } from "node:fs";
|
|
69289
69693
|
import path68 from "node:path";
|
|
69290
|
-
import { randomUUID as
|
|
69694
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
69291
69695
|
|
|
69292
69696
|
// src/cli/kraken/verifierLifecycle.ts
|
|
69293
69697
|
init_verification2();
|
|
@@ -69584,7 +69988,7 @@ async function runHeadlessKrakenGraph(opts, provider, model) {
|
|
|
69584
69988
|
});
|
|
69585
69989
|
log(formatKrakenGraphAscii2(graph));
|
|
69586
69990
|
if (opts.planOnly) {
|
|
69587
|
-
const planId =
|
|
69991
|
+
const planId = randomUUID8();
|
|
69588
69992
|
const planDir = path68.join(cwd, ".zelari", "radio");
|
|
69589
69993
|
const planPath = path68.join(planDir, `plan-${planId}.json`);
|
|
69590
69994
|
await fs41.mkdir(planDir, { recursive: true });
|
|
@@ -69900,6 +70304,11 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69900
70304
|
}
|
|
69901
70305
|
const effectiveTask = buildAgentUserWithHistory(opts.task, historySeed);
|
|
69902
70306
|
if (opts.task) spine.userMessage(effectiveTask);
|
|
70307
|
+
const wantWrites = expectsDiskImplementation(
|
|
70308
|
+
opts.task,
|
|
70309
|
+
opts.phase,
|
|
70310
|
+
historySeed
|
|
70311
|
+
);
|
|
69903
70312
|
const maxToolLoop = (() => {
|
|
69904
70313
|
const n = envNumber(process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, {
|
|
69905
70314
|
default: 30,
|
|
@@ -69916,6 +70325,8 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69916
70325
|
tools,
|
|
69917
70326
|
toolRegistry,
|
|
69918
70327
|
providerStream,
|
|
70328
|
+
buildLiveness: { mutationRequired: wantWrites, maxRecoveries: 2 },
|
|
70329
|
+
requestTail: () => resourceStatusTail(spine.spine.latestResourceSnapshot()),
|
|
69919
70330
|
// 2.6 Phase 3: host-owned pre-dispatch resource gate (doc section 11.3).
|
|
69920
70331
|
// Advisory by default; ZELARI_RESOURCE_ENFORCEMENT=protected enables the
|
|
69921
70332
|
// protected verification reserve. Degrade-and-stop (null gate = allow).
|
|
@@ -69929,12 +70340,13 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69929
70340
|
memoryContextChars: 2e3
|
|
69930
70341
|
} : {}
|
|
69931
70342
|
});
|
|
70343
|
+
const readBuildProgress = () => {
|
|
70344
|
+
const getter = harness.getBuildProgress;
|
|
70345
|
+
return typeof getter === "function" ? getter.call(harness) : { mutationsAttempted: 0, mutationsSucceeded: 0 };
|
|
70346
|
+
};
|
|
69932
70347
|
let finalReason = "completed";
|
|
69933
70348
|
let exitCode = 0;
|
|
69934
70349
|
const textBuffer = [];
|
|
69935
|
-
let successfulWrites = 0;
|
|
69936
|
-
let emittedWrites = 0;
|
|
69937
|
-
const pendingToolNames = /* @__PURE__ */ new Map();
|
|
69938
70350
|
const scrub = createStreamScrubber2();
|
|
69939
70351
|
try {
|
|
69940
70352
|
for await (const event of harness.run()) {
|
|
@@ -69943,27 +70355,6 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
69943
70355
|
if (event.type === "message_start") {
|
|
69944
70356
|
scrub.reset();
|
|
69945
70357
|
}
|
|
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
70358
|
if (event.type === "message_delta" && typeof event.delta === "string") {
|
|
69968
70359
|
const cleanDelta = scrub.push(event.delta);
|
|
69969
70360
|
if (opts.output === "json") {
|
|
@@ -70003,17 +70394,18 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70003
70394
|
finalReason: "error",
|
|
70004
70395
|
exitCode: 2,
|
|
70005
70396
|
textBuffer,
|
|
70006
|
-
successfulWrites,
|
|
70007
|
-
emittedWrites,
|
|
70397
|
+
successfulWrites: readBuildProgress().mutationsSucceeded,
|
|
70398
|
+
emittedWrites: readBuildProgress().mutationsAttempted,
|
|
70008
70399
|
messages: harness.getMessages()
|
|
70009
70400
|
};
|
|
70010
70401
|
}
|
|
70402
|
+
const buildProgress = readBuildProgress();
|
|
70011
70403
|
return {
|
|
70012
70404
|
finalReason,
|
|
70013
70405
|
exitCode,
|
|
70014
70406
|
textBuffer,
|
|
70015
|
-
successfulWrites,
|
|
70016
|
-
emittedWrites,
|
|
70407
|
+
successfulWrites: buildProgress.mutationsSucceeded,
|
|
70408
|
+
emittedWrites: buildProgress.mutationsAttempted,
|
|
70017
70409
|
messages: harness.getMessages()
|
|
70018
70410
|
};
|
|
70019
70411
|
}
|
|
@@ -70037,41 +70429,6 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70037
70429
|
}
|
|
70038
70430
|
];
|
|
70039
70431
|
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
70432
|
let strictExit = 0;
|
|
70076
70433
|
const verifierReviewDeps = {
|
|
70077
70434
|
session: { provider, model },
|
|
@@ -70155,7 +70512,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
70155
70512
|
}
|
|
70156
70513
|
process.stdout.write("");
|
|
70157
70514
|
if (pass.finalReason !== "error" && opts.output === "json" && wantWrites && pass.successfulWrites === 0) {
|
|
70158
|
-
emitEvent({ type: "log", message: "[headless] BUILD
|
|
70515
|
+
emitEvent({ type: "log", message: "[headless] BUILD failed: zero successful mutations after liveness recovery" });
|
|
70159
70516
|
}
|
|
70160
70517
|
try {
|
|
70161
70518
|
const closeStatus = pass.finalReason === "error" ? "error" : strictExit !== 0 ? "stopped" : "completed";
|