open-agents-ai 0.28.0 → 0.29.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/index.js +50 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10413,32 +10413,31 @@ Rules:
|
|
|
10413
10413
|
* Build a self-eval prompt for the agent when approaching timeout.
|
|
10414
10414
|
* Returns the prompt to inject. The agent will respond with a plan.
|
|
10415
10415
|
*/
|
|
10416
|
-
|
|
10416
|
+
buildHealthCheckPrompt(elapsedMs2, toolCallCount, repetitionScore, checkNumber) {
|
|
10417
10417
|
const elapsedMin = (elapsedMs2 / 6e4).toFixed(1);
|
|
10418
|
-
const remainingMin = (remainingMs / 6e4).toFixed(1);
|
|
10419
10418
|
const stuckWarning = repetitionScore > 0.5 ? `
|
|
10420
10419
|
\u26A0 REPETITION DETECTED: Your recent tool calls are ${Math.round(repetitionScore * 100)}% repetitive. You may be stuck in a loop.` : "";
|
|
10421
|
-
return `[
|
|
10420
|
+
return `[HEALTH CHECK #${checkNumber} \u2014 Progress Assessment]
|
|
10422
10421
|
|
|
10423
|
-
You have been working for ${elapsedMin} minutes with ${toolCallCount} tool calls.
|
|
10422
|
+
You have been working for ${elapsedMin} minutes with ${toolCallCount} tool calls. There is no time limit \u2014 take as long as you need.${stuckWarning}
|
|
10424
10423
|
|
|
10425
|
-
|
|
10424
|
+
Briefly assess your situation and choose ONE action:
|
|
10426
10425
|
|
|
10427
|
-
1. CONTINUE \u2014 If you are making
|
|
10426
|
+
1. CONTINUE \u2014 If you are making progress, briefly note what you've done and what remains. Keep working.
|
|
10428
10427
|
|
|
10429
|
-
2. PIVOT \u2014 If your current approach isn't working,
|
|
10428
|
+
2. PIVOT \u2014 If your current approach isn't working, describe a different strategy and immediately try it.
|
|
10430
10429
|
|
|
10431
|
-
3. CHECKPOINT \u2014 If you've made partial progress
|
|
10430
|
+
3. CHECKPOINT \u2014 If you've made partial progress and want to save it, call task_complete with a summary. The user can continue later.
|
|
10432
10431
|
|
|
10433
|
-
Respond with your assessment, then take action
|
|
10432
|
+
Respond with your assessment, then take action.`;
|
|
10434
10433
|
}
|
|
10435
10434
|
/** Run a task through the agentic loop */
|
|
10436
10435
|
async run(task, context) {
|
|
10437
10436
|
const start = Date.now();
|
|
10438
10437
|
const taskTimeoutMs = this.options.taskTimeoutMs;
|
|
10439
|
-
const
|
|
10440
|
-
|
|
10441
|
-
let
|
|
10438
|
+
const selfEvalInterval = taskTimeoutMs;
|
|
10439
|
+
let nextSelfEval = start + selfEvalInterval;
|
|
10440
|
+
let selfEvalCount = 0;
|
|
10442
10441
|
const toolCallLog = [];
|
|
10443
10442
|
this.aborted = false;
|
|
10444
10443
|
this.pendingUserMessages.length = 0;
|
|
@@ -10467,24 +10466,20 @@ TASK: ${task}` : task }
|
|
|
10467
10466
|
break;
|
|
10468
10467
|
}
|
|
10469
10468
|
const now = Date.now();
|
|
10470
|
-
if (now >
|
|
10471
|
-
|
|
10472
|
-
break;
|
|
10473
|
-
}
|
|
10474
|
-
if (!softTimeoutTriggered && now > softDeadline) {
|
|
10475
|
-
softTimeoutTriggered = true;
|
|
10469
|
+
if (now > nextSelfEval) {
|
|
10470
|
+
selfEvalCount++;
|
|
10476
10471
|
const elapsed = now - start;
|
|
10477
|
-
const remaining = hardDeadline - now;
|
|
10478
10472
|
const repetitionScore = this.detectRepetition(toolCallLog);
|
|
10479
10473
|
this.emit({
|
|
10480
10474
|
type: "compaction",
|
|
10481
|
-
content: `
|
|
10475
|
+
content: `Health check #${selfEvalCount} (${(elapsed / 6e4).toFixed(1)}m elapsed) \u2014 assessing progress`,
|
|
10482
10476
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10483
10477
|
});
|
|
10484
10478
|
messages.push({
|
|
10485
10479
|
role: "user",
|
|
10486
|
-
content: this.
|
|
10480
|
+
content: this.buildHealthCheckPrompt(elapsed, toolCallCount, repetitionScore, selfEvalCount)
|
|
10487
10481
|
});
|
|
10482
|
+
nextSelfEval = now + selfEvalInterval;
|
|
10488
10483
|
}
|
|
10489
10484
|
while (this.pendingUserMessages.length > 0) {
|
|
10490
10485
|
const userMsg = this.pendingUserMessages.shift();
|
|
@@ -10693,7 +10688,7 @@ ${result.output.length > maxLen ? this.foldOutput(result.output, maxLen) : resul
|
|
|
10693
10688
|
});
|
|
10694
10689
|
}
|
|
10695
10690
|
}
|
|
10696
|
-
while (!completed && !this.aborted && this.options.bruteForce && bruteForceCycle < this.options.bruteForceMaxCycles
|
|
10691
|
+
while (!completed && !this.aborted && this.options.bruteForce && bruteForceCycle < this.options.bruteForceMaxCycles) {
|
|
10697
10692
|
bruteForceCycle++;
|
|
10698
10693
|
const totalTurns = messages.filter((m) => m.role === "assistant").length;
|
|
10699
10694
|
this.emit({
|
|
@@ -10727,24 +10722,20 @@ You have ${this.options.maxTurns} more turns. Continue making progress. Call tas
|
|
|
10727
10722
|
break;
|
|
10728
10723
|
}
|
|
10729
10724
|
const bfNow = Date.now();
|
|
10730
|
-
if (bfNow >
|
|
10731
|
-
|
|
10732
|
-
break;
|
|
10733
|
-
}
|
|
10734
|
-
if (!softTimeoutTriggered && bfNow > softDeadline) {
|
|
10735
|
-
softTimeoutTriggered = true;
|
|
10725
|
+
if (bfNow > nextSelfEval) {
|
|
10726
|
+
selfEvalCount++;
|
|
10736
10727
|
const elapsed = bfNow - start;
|
|
10737
|
-
const remaining = hardDeadline - bfNow;
|
|
10738
10728
|
const repetitionScore = this.detectRepetition(toolCallLog);
|
|
10739
10729
|
this.emit({
|
|
10740
10730
|
type: "compaction",
|
|
10741
|
-
content: `
|
|
10731
|
+
content: `Health check #${selfEvalCount} (${(elapsed / 6e4).toFixed(1)}m elapsed) \u2014 assessing progress`,
|
|
10742
10732
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
10743
10733
|
});
|
|
10744
10734
|
messages.push({
|
|
10745
10735
|
role: "user",
|
|
10746
|
-
content: this.
|
|
10736
|
+
content: this.buildHealthCheckPrompt(elapsed, toolCallCount, repetitionScore, selfEvalCount)
|
|
10747
10737
|
});
|
|
10738
|
+
nextSelfEval = bfNow + selfEvalInterval;
|
|
10748
10739
|
}
|
|
10749
10740
|
while (this.pendingUserMessages.length > 0) {
|
|
10750
10741
|
const userMsg = this.pendingUserMessages.shift();
|
|
@@ -11416,8 +11407,7 @@ ${newerSummary}` : newerSummary;
|
|
|
11416
11407
|
const resp = await fetch(`${this.baseUrl}/v1/chat/completions`, {
|
|
11417
11408
|
method: "POST",
|
|
11418
11409
|
headers: this.authHeaders(),
|
|
11419
|
-
body: JSON.stringify(body)
|
|
11420
|
-
signal: AbortSignal.timeout(request.timeoutMs)
|
|
11410
|
+
body: JSON.stringify(body)
|
|
11421
11411
|
});
|
|
11422
11412
|
if (!resp.ok) {
|
|
11423
11413
|
const text = await resp.text().catch(() => "");
|
|
@@ -11477,8 +11467,7 @@ ${newerSummary}` : newerSummary;
|
|
|
11477
11467
|
const resp = await fetch(`${this.baseUrl}/v1/chat/completions`, {
|
|
11478
11468
|
method: "POST",
|
|
11479
11469
|
headers: this.authHeaders(),
|
|
11480
|
-
body: JSON.stringify(body)
|
|
11481
|
-
signal: AbortSignal.timeout(request.timeoutMs)
|
|
11470
|
+
body: JSON.stringify(body)
|
|
11482
11471
|
});
|
|
11483
11472
|
if (!resp.ok) {
|
|
11484
11473
|
const text = await resp.text().catch(() => "");
|
|
@@ -18994,9 +18983,28 @@ var init_status_bar = __esm({
|
|
|
18994
18983
|
this.metrics.totalTokens = update.totalTokens;
|
|
18995
18984
|
if (update.estimatedContextTokens !== void 0)
|
|
18996
18985
|
this.metrics.estimatedContextTokens = update.estimatedContextTokens;
|
|
18986
|
+
this._streamingTokens = 0;
|
|
18997
18987
|
if (this.active)
|
|
18998
18988
|
this.renderFooterPreserveCursor();
|
|
18999
18989
|
}
|
|
18990
|
+
/** Running count of tokens estimated during streaming (reset on authoritative updateMetrics) */
|
|
18991
|
+
_streamingTokens = 0;
|
|
18992
|
+
_streamThrottleTimer = null;
|
|
18993
|
+
/** Increment the live streaming token counter (throttled re-render at 100ms) */
|
|
18994
|
+
incrementStreamingTokens(count) {
|
|
18995
|
+
this._streamingTokens += count;
|
|
18996
|
+
if (!this._streamThrottleTimer && this.active) {
|
|
18997
|
+
this._streamThrottleTimer = setTimeout(() => {
|
|
18998
|
+
this._streamThrottleTimer = null;
|
|
18999
|
+
if (this.active)
|
|
19000
|
+
this.renderFooterPreserveCursor();
|
|
19001
|
+
}, 100);
|
|
19002
|
+
}
|
|
19003
|
+
}
|
|
19004
|
+
/** Get the effective completion tokens (authoritative + live streaming estimate) */
|
|
19005
|
+
get effectiveCompletionTokens() {
|
|
19006
|
+
return this.metrics.completionTokens + this._streamingTokens;
|
|
19007
|
+
}
|
|
19000
19008
|
/** Reset metrics (e.g. on session start) */
|
|
19001
19009
|
resetMetrics() {
|
|
19002
19010
|
this.metrics.promptTokens = 0;
|
|
@@ -19122,7 +19130,8 @@ var init_status_bar = __esm({
|
|
|
19122
19130
|
const pipe = pastel2(60, " \u2502 ");
|
|
19123
19131
|
const tokIn = m.promptTokens > 0 ? m.promptTokens.toLocaleString() : `~${Math.max(m.estimatedContextTokens, 0).toLocaleString()}`;
|
|
19124
19132
|
const tokInLabel = pastel2(117, "In: ") + c2.bold(tokIn);
|
|
19125
|
-
const
|
|
19133
|
+
const effectiveOut = this.effectiveCompletionTokens;
|
|
19134
|
+
const tokOut = effectiveOut > 0 ? effectiveOut.toLocaleString() : `~${Math.ceil(m.totalTokens > 0 ? m.totalTokens - m.promptTokens : m.estimatedContextTokens * 0.3).toLocaleString()}`;
|
|
19126
19135
|
const tokOutLabel = pastel2(151, "Out: ") + c2.bold(tokOut);
|
|
19127
19136
|
const ctxUsed = m.estimatedContextTokens;
|
|
19128
19137
|
const ctxTotal = m.contextWindowSize;
|
|
@@ -19505,7 +19514,7 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
19505
19514
|
streamEnabled: stream?.enabled ?? false,
|
|
19506
19515
|
bruteForce: bruteForce ?? true,
|
|
19507
19516
|
bruteForceMaxCycles: 100,
|
|
19508
|
-
// effectively unlimited — hard timeout
|
|
19517
|
+
// effectively unlimited — no hard timeout, agent runs until complete or aborted
|
|
19509
19518
|
contextWindowSize: contextWindowSize ?? 0
|
|
19510
19519
|
});
|
|
19511
19520
|
const tools = buildTools(repoRoot, config);
|
|
@@ -19594,6 +19603,10 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
19594
19603
|
if (stream?.enabled) {
|
|
19595
19604
|
stream.renderer.write(event.content ?? "", event.streamKind ?? "content");
|
|
19596
19605
|
}
|
|
19606
|
+
if (statusBar && event.content) {
|
|
19607
|
+
const estimatedNewTokens = Math.max(1, Math.ceil(event.content.length / 4));
|
|
19608
|
+
statusBar.incrementStreamingTokens(estimatedNewTokens);
|
|
19609
|
+
}
|
|
19597
19610
|
break;
|
|
19598
19611
|
case "stream_end":
|
|
19599
19612
|
if (stream?.enabled) {
|
package/package.json
CHANGED