@genesislcap/ai-assistant 15.24.0 → 15.24.2
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/ai-assistant.api.json +2 -2
- package/dist/ai-assistant.d.ts +22 -11
- package/dist/chat-driver.cjs +138 -120
- package/dist/chat-driver.cjs.map +4 -4
- package/dist/chat-driver.mjs +138 -120
- package/dist/chat-driver.mjs.map +4 -4
- package/dist/custom-elements.json +119 -61
- package/dist/dts/components/chat-driver/chat-driver.d.ts +22 -11
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/turn-failures.d.ts +96 -0
- package/dist/dts/components/chat-driver/turn-failures.d.ts.map +1 -0
- package/dist/esm/components/chat-driver/chat-driver.js +92 -142
- package/dist/esm/components/chat-driver/turn-failures.js +84 -0
- package/package.json +16 -16
- package/docs/.gitattributes +0 -2
package/dist/chat-driver.mjs
CHANGED
|
@@ -4329,6 +4329,78 @@ function accumulate(messages, into) {
|
|
|
4329
4329
|
// src/utils/tool-fold.ts
|
|
4330
4330
|
var TOOL_FOLD_SYMBOL = Symbol("toolFold");
|
|
4331
4331
|
|
|
4332
|
+
// src/components/chat-driver/turn-failures.ts
|
|
4333
|
+
var TURN_FAILURE_EXITS = {
|
|
4334
|
+
contextGuard: {
|
|
4335
|
+
subReason: "context_exhausted",
|
|
4336
|
+
resultReason: "context-exhausted",
|
|
4337
|
+
copy: "I had to stop here \u2014 this conversation has filled the available context. Compact it to free up room, then ask me to continue."
|
|
4338
|
+
},
|
|
4339
|
+
contextOverflow: {
|
|
4340
|
+
subReason: "context_exhausted",
|
|
4341
|
+
resultReason: "context-exhausted",
|
|
4342
|
+
copy: DEFAULT_CONTEXT_OVERFLOW_MESSAGE
|
|
4343
|
+
},
|
|
4344
|
+
malformedToolCall: {
|
|
4345
|
+
subReason: "malformed_tool_call",
|
|
4346
|
+
// Not `malformed-tool-call`: the main-turn reason is named after the provider finish
|
|
4347
|
+
// reason (`MALFORMED_FUNCTION_CALL`) that produces it, and is part of the published
|
|
4348
|
+
// TurnFailureReason union, so the two names cannot be brought into line here.
|
|
4349
|
+
resultReason: "malformed-function-call",
|
|
4350
|
+
copy: "While working on your request, I repeatedly called my tools incorrectly. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps."
|
|
4351
|
+
},
|
|
4352
|
+
responseTruncated: {
|
|
4353
|
+
subReason: "response_truncated",
|
|
4354
|
+
resultReason: "response-truncated",
|
|
4355
|
+
copy: "My response was cut off because a single step reached the model output limit. This usually means one step tried to produce too much at once \u2014 try breaking your request into smaller steps."
|
|
4356
|
+
},
|
|
4357
|
+
timeout: {
|
|
4358
|
+
subReason: "timeout",
|
|
4359
|
+
// There is no `timeout` member of TurnFailureReason, so the main turn reports the
|
|
4360
|
+
// generic `exception`. A sub-agent gets the specific reason because its parent
|
|
4361
|
+
// branches on it to decide whether a retry is worth attempting.
|
|
4362
|
+
resultReason: "exception",
|
|
4363
|
+
copy: "The request timed out. You can ask me to try again, or break this into a smaller step."
|
|
4364
|
+
},
|
|
4365
|
+
unknownToolLimit: {
|
|
4366
|
+
subReason: "unknown_tool_limit",
|
|
4367
|
+
resultReason: "unknown-tool-limit",
|
|
4368
|
+
copy: "I'm sorry, I repeatedly tried to use tools that aren't available to me, so I couldn't complete that. If a 'Download agent log' option appears in the Settings (cog) menu, you can download the log and share it with whoever set up this assistant to help fix the issue."
|
|
4369
|
+
},
|
|
4370
|
+
maxIterations: {
|
|
4371
|
+
subReason: "max_iterations",
|
|
4372
|
+
resultReason: "max-iterations",
|
|
4373
|
+
copy: "I've reached my limit for this response. You can ask me to continue and I'll pick up where I left off."
|
|
4374
|
+
},
|
|
4375
|
+
refusal: {
|
|
4376
|
+
subReason: "refusal",
|
|
4377
|
+
resultReason: "refusal",
|
|
4378
|
+
copy: "This request was declined. Try rephrasing it, or breaking it into smaller steps."
|
|
4379
|
+
},
|
|
4380
|
+
emptyResponse: {
|
|
4381
|
+
subReason: "empty_response",
|
|
4382
|
+
resultReason: "empty-response",
|
|
4383
|
+
copy: "While working on your request, I repeatedly generated a blank response. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps."
|
|
4384
|
+
},
|
|
4385
|
+
providerRefused: {
|
|
4386
|
+
subReason: "provider_refused",
|
|
4387
|
+
resultReason: "provider-refused",
|
|
4388
|
+
// Overridden per wall by `ChatDriver.providerRefusedBubble`, which prefers a
|
|
4389
|
+
// host-supplied message; this is the fallback that method returns.
|
|
4390
|
+
copy: DEFAULT_PROVIDER_REFUSED_MESSAGE
|
|
4391
|
+
},
|
|
4392
|
+
budgetExhausted: {
|
|
4393
|
+
subReason: "budget_exhausted",
|
|
4394
|
+
resultReason: "budget-exhausted",
|
|
4395
|
+
// Overridden per wall by `ChatDriver.budgetExhaustedBubble`, which upgrades this with
|
|
4396
|
+
// "switch to another AI" when a second vendor is reachable.
|
|
4397
|
+
copy: DEFAULT_BUDGET_EXHAUSTED_MESSAGE
|
|
4398
|
+
}
|
|
4399
|
+
// `satisfies`, not an annotation: an annotation would widen `resultReason` to
|
|
4400
|
+
// `TurnFailureReason` and cost the literal types that let `turn-failures.test.ts` pin the
|
|
4401
|
+
// two deliberate divergences at compile time instead of at runtime.
|
|
4402
|
+
};
|
|
4403
|
+
|
|
4332
4404
|
// src/components/chat-driver/chat-driver.ts
|
|
4333
4405
|
var toolResultImages = (result) => {
|
|
4334
4406
|
if (!result || typeof result !== "object") return void 0;
|
|
@@ -4703,6 +4775,33 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
4703
4775
|
...providerRefused ? { providerRefused } : {}
|
|
4704
4776
|
};
|
|
4705
4777
|
}
|
|
4778
|
+
/**
|
|
4779
|
+
* End the turn on a terminal failure: fail upward when this driver is a sub-agent, speak
|
|
4780
|
+
* to the user when it is not, and hand the reason to the caller either way.
|
|
4781
|
+
*
|
|
4782
|
+
* Only that fork lives here. Each exit keeps its own `recordTurnError` call, because the
|
|
4783
|
+
* telemetry payload is what legitimately differs between them — attempt counts, token
|
|
4784
|
+
* figures, tool names — and folding it in would mean one optional field per condition.
|
|
4785
|
+
*
|
|
4786
|
+
* `overrides.copy` serves the two walls whose prose is composed per occurrence:
|
|
4787
|
+
* `budgetExhaustedBubble` names the vendor and can offer another, `providerRefusedBubble`
|
|
4788
|
+
* prefers a host-supplied message. Every other exit reads its copy from the table.
|
|
4789
|
+
*
|
|
4790
|
+
* One exit stays out: the `BudgetExhaustedError` catch. Not because its shape differs —
|
|
4791
|
+
* its two telemetry payloads are field-for-field identical — but because its main-turn
|
|
4792
|
+
* branch calls `reportBudgetExhausted`, which is public and also serves
|
|
4793
|
+
* `OrchestratingDriver`'s classification phase, where no tool loop is running. That
|
|
4794
|
+
* method has to survive either way, so routing the catch through here would relocate the
|
|
4795
|
+
* duplication rather than remove it.
|
|
4796
|
+
*/
|
|
4797
|
+
endTurnWithFailure(exit, overrides) {
|
|
4798
|
+
if (this.isSubAgent) {
|
|
4799
|
+
this.failSubAgent(exit.subReason, overrides?.budget, overrides?.providerRefused);
|
|
4800
|
+
} else {
|
|
4801
|
+
this.appendDriverNotice(overrides?.copy ?? exit.copy);
|
|
4802
|
+
}
|
|
4803
|
+
return this.turnDone(exit.resultReason, overrides?.budget, overrides?.providerRefused);
|
|
4804
|
+
}
|
|
4706
4805
|
/**
|
|
4707
4806
|
* Terminal budget outcome for a wall hit **outside** the tool loop — today,
|
|
4708
4807
|
* `OrchestratingDriver`'s classification phase, which calls the provider
|
|
@@ -4731,7 +4830,7 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
4731
4830
|
*/
|
|
4732
4831
|
budgetExhaustedBubble(wall) {
|
|
4733
4832
|
if (this.budgetExhaustedMessageOverride != null) return this.budgetExhaustedMessageOverride;
|
|
4734
|
-
if (wall?.otherVendorAvailable !== true) return
|
|
4833
|
+
if (wall?.otherVendorAvailable !== true) return TURN_FAILURE_EXITS.budgetExhausted.copy;
|
|
4735
4834
|
const subject = wall?.vendorLabel ? `${wall.vendorLabel}'s AI usage limit` : "your AI usage limit";
|
|
4736
4835
|
return `You've reached ${subject}. Switch to another AI provider in Settings to keep going, or contact your administrator to raise it.`;
|
|
4737
4836
|
}
|
|
@@ -4765,32 +4864,7 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
4765
4864
|
* has gone unpaid — so there is nothing here to compose. A host override wins verbatim.
|
|
4766
4865
|
*/
|
|
4767
4866
|
providerRefusedBubble() {
|
|
4768
|
-
return this.providerRefusedMessageOverride ??
|
|
4769
|
-
}
|
|
4770
|
-
/**
|
|
4771
|
-
* Terminal provider-refusal outcome. Mirrors `reportBudgetExhausted` so the two walls behave
|
|
4772
|
-
* identically from the caller's side, while keeping their diagnostics distinct.
|
|
4773
|
-
*
|
|
4774
|
-
* `kind` reaches the debug log and the result but never the transcript: it is what lets an operator
|
|
4775
|
-
* tell "top up the account" from "rotate the key", and with cause-free user copy this is the only
|
|
4776
|
-
* place that distinction survives.
|
|
4777
|
-
*/
|
|
4778
|
-
reportProviderRefused(e) {
|
|
4779
|
-
const detail = providerRefusedDetailOf(e);
|
|
4780
|
-
this.providerRefusedThisTurn = true;
|
|
4781
|
-
this.providerRefusedDetail = detail;
|
|
4782
|
-
logger2.error("ChatDriver: provider refused the request", e);
|
|
4783
|
-
recordTurnError(this.sessionKey, "provider-refused", {
|
|
4784
|
-
agent: this.activeAgentName,
|
|
4785
|
-
provider: this.lastResolvedProviderName,
|
|
4786
|
-
vendor: vendorTypeOfLabel(e.vendorLabel) ?? this.lastResolvedProvider,
|
|
4787
|
-
kind: e.kind,
|
|
4788
|
-
upstreamStatus: e.upstreamStatus,
|
|
4789
|
-
upstreamType: e.upstreamType,
|
|
4790
|
-
isSubAgent: this.isSubAgent
|
|
4791
|
-
});
|
|
4792
|
-
this.appendDriverNotice(this.providerRefusedBubble());
|
|
4793
|
-
return this.turnDone("provider-refused", void 0, detail);
|
|
4867
|
+
return this.providerRefusedMessageOverride ?? TURN_FAILURE_EXITS.providerRefused.copy;
|
|
4794
4868
|
}
|
|
4795
4869
|
/** The typed failure reason on a loop result, or `undefined` for a clean turn / handoff. */
|
|
4796
4870
|
static failureReasonOf(result) {
|
|
@@ -6081,12 +6155,10 @@ Output format (strict):
|
|
|
6081
6155
|
via: "sub-agent",
|
|
6082
6156
|
isSubAgent: this.isSubAgent
|
|
6083
6157
|
});
|
|
6084
|
-
|
|
6085
|
-
this.
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
}
|
|
6089
|
-
return this.turnDone("provider-refused", void 0, this.providerRefusedDetail);
|
|
6158
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.providerRefused, {
|
|
6159
|
+
copy: this.providerRefusedBubble(),
|
|
6160
|
+
providerRefused: this.providerRefusedDetail
|
|
6161
|
+
});
|
|
6090
6162
|
}
|
|
6091
6163
|
if (this.budgetExhaustedThisTurn) {
|
|
6092
6164
|
logger2.error("ChatDriver: ending the turn \u2014 a sub-agent hit the AI budget wall");
|
|
@@ -6106,12 +6178,10 @@ Output format (strict):
|
|
|
6106
6178
|
via: "sub-agent",
|
|
6107
6179
|
isSubAgent: this.isSubAgent
|
|
6108
6180
|
});
|
|
6109
|
-
|
|
6110
|
-
this.
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
}
|
|
6114
|
-
return this.turnDone("budget-exhausted", this.budgetWallDetail);
|
|
6181
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.budgetExhausted, {
|
|
6182
|
+
copy: this.budgetExhaustedBubble(this.budgetWallDetail),
|
|
6183
|
+
budget: this.budgetWallDetail
|
|
6184
|
+
});
|
|
6115
6185
|
}
|
|
6116
6186
|
const promptCtx = {
|
|
6117
6187
|
agentName: this.activeAgentName ?? "",
|
|
@@ -6276,14 +6346,7 @@ ${tailBody}
|
|
|
6276
6346
|
iterations,
|
|
6277
6347
|
isSubAgent: this.isSubAgent
|
|
6278
6348
|
});
|
|
6279
|
-
|
|
6280
|
-
this.failSubAgent("context_exhausted");
|
|
6281
|
-
} else {
|
|
6282
|
-
this.appendDriverNotice(
|
|
6283
|
-
"I had to stop here \u2014 this conversation has filled the available context. Compact it to free up room, then ask me to continue."
|
|
6284
|
-
);
|
|
6285
|
-
}
|
|
6286
|
-
return this.turnDone("context-exhausted");
|
|
6349
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.contextGuard);
|
|
6287
6350
|
}
|
|
6288
6351
|
let response;
|
|
6289
6352
|
try {
|
|
@@ -6313,14 +6376,7 @@ ${tailBody}
|
|
|
6313
6376
|
finishMessage: e.finishMessage,
|
|
6314
6377
|
isSubAgent: this.isSubAgent
|
|
6315
6378
|
});
|
|
6316
|
-
|
|
6317
|
-
this.failSubAgent("malformed_tool_call");
|
|
6318
|
-
} else {
|
|
6319
|
-
this.appendDriverNotice(
|
|
6320
|
-
"While working on your request, I repeatedly called my tools incorrectly. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps."
|
|
6321
|
-
);
|
|
6322
|
-
}
|
|
6323
|
-
return this.turnDone("malformed-function-call");
|
|
6379
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.malformedToolCall);
|
|
6324
6380
|
}
|
|
6325
6381
|
if (e instanceof ResponseTruncatedError) {
|
|
6326
6382
|
logger2.error("ChatDriver: response truncated at the output-token cap", e);
|
|
@@ -6333,14 +6389,7 @@ ${tailBody}
|
|
|
6333
6389
|
tools: e.toolNames,
|
|
6334
6390
|
isSubAgent: this.isSubAgent
|
|
6335
6391
|
});
|
|
6336
|
-
|
|
6337
|
-
this.failSubAgent("response_truncated");
|
|
6338
|
-
} else {
|
|
6339
|
-
this.appendDriverNotice(
|
|
6340
|
-
"My response was cut off because a single step reached the model output limit. This usually means one step tried to produce too much at once \u2014 try breaking your request into smaller steps."
|
|
6341
|
-
);
|
|
6342
|
-
}
|
|
6343
|
-
return this.turnDone("response-truncated");
|
|
6392
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.responseTruncated);
|
|
6344
6393
|
}
|
|
6345
6394
|
if (e instanceof ContextOverflowError) {
|
|
6346
6395
|
logger2.error("ChatDriver: the prompt exceeded the model context window", e);
|
|
@@ -6353,30 +6402,28 @@ ${tailBody}
|
|
|
6353
6402
|
via: "provider",
|
|
6354
6403
|
isSubAgent: this.isSubAgent
|
|
6355
6404
|
});
|
|
6356
|
-
|
|
6357
|
-
this.failSubAgent("context_exhausted");
|
|
6358
|
-
} else {
|
|
6359
|
-
this.appendDriverNotice(DEFAULT_CONTEXT_OVERFLOW_MESSAGE);
|
|
6360
|
-
}
|
|
6361
|
-
return this.turnDone("context-exhausted");
|
|
6405
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.contextOverflow);
|
|
6362
6406
|
}
|
|
6363
6407
|
if (e instanceof ProviderRefusedError) {
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
provider: this.lastResolvedProviderName,
|
|
6369
|
-
vendor: vendorTypeOfLabel(e.vendorLabel) ?? this.lastResolvedProvider,
|
|
6370
|
-
kind: e.kind,
|
|
6371
|
-
upstreamStatus: e.upstreamStatus,
|
|
6372
|
-
upstreamType: e.upstreamType,
|
|
6373
|
-
isSubAgent: true
|
|
6374
|
-
});
|
|
6375
|
-
const detail = providerRefusedDetailOf(e);
|
|
6376
|
-
this.failSubAgent("provider_refused", void 0, detail);
|
|
6377
|
-
return this.turnDone("provider-refused", void 0, detail);
|
|
6408
|
+
const detail = providerRefusedDetailOf(e);
|
|
6409
|
+
if (!this.isSubAgent) {
|
|
6410
|
+
this.providerRefusedThisTurn = true;
|
|
6411
|
+
this.providerRefusedDetail = detail;
|
|
6378
6412
|
}
|
|
6379
|
-
|
|
6413
|
+
logger2.error("ChatDriver: provider refused the request", e);
|
|
6414
|
+
recordTurnError(this.sessionKey, "provider-refused", {
|
|
6415
|
+
agent: this.activeAgentName,
|
|
6416
|
+
provider: this.lastResolvedProviderName,
|
|
6417
|
+
vendor: vendorTypeOfLabel(e.vendorLabel) ?? this.lastResolvedProvider,
|
|
6418
|
+
kind: e.kind,
|
|
6419
|
+
upstreamStatus: e.upstreamStatus,
|
|
6420
|
+
upstreamType: e.upstreamType,
|
|
6421
|
+
isSubAgent: this.isSubAgent
|
|
6422
|
+
});
|
|
6423
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.providerRefused, {
|
|
6424
|
+
copy: this.providerRefusedBubble(),
|
|
6425
|
+
providerRefused: detail
|
|
6426
|
+
});
|
|
6380
6427
|
}
|
|
6381
6428
|
if (e instanceof BudgetExhaustedError) {
|
|
6382
6429
|
this.budgetExhaustedThisTurn = true;
|
|
@@ -6406,14 +6453,7 @@ ${tailBody}
|
|
|
6406
6453
|
message: e.message,
|
|
6407
6454
|
isSubAgent: this.isSubAgent
|
|
6408
6455
|
});
|
|
6409
|
-
|
|
6410
|
-
this.failSubAgent("timeout");
|
|
6411
|
-
} else {
|
|
6412
|
-
this.appendDriverNotice(
|
|
6413
|
-
"The request timed out. You can ask me to try again, or break this into a smaller step."
|
|
6414
|
-
);
|
|
6415
|
-
}
|
|
6416
|
-
return this.turnDone("exception");
|
|
6456
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.timeout);
|
|
6417
6457
|
}
|
|
6418
6458
|
if (e instanceof DOMException && e.name === "AbortError") {
|
|
6419
6459
|
return this.completeAbortedTurn();
|
|
@@ -6465,11 +6505,11 @@ ${tailBody}
|
|
|
6465
6505
|
iterations -= 1;
|
|
6466
6506
|
continue;
|
|
6467
6507
|
}
|
|
6468
|
-
const
|
|
6508
|
+
const exit = isRefusal ? TURN_FAILURE_EXITS.refusal : TURN_FAILURE_EXITS.emptyResponse;
|
|
6469
6509
|
logger2.error(
|
|
6470
6510
|
isRefusal ? "ChatDriver: model refused the request (safety decline) \u2014 not retrying" : "ChatDriver: empty model response after all retries"
|
|
6471
6511
|
);
|
|
6472
|
-
recordTurnError(this.sessionKey,
|
|
6512
|
+
recordTurnError(this.sessionKey, exit.resultReason, {
|
|
6473
6513
|
agent: this.activeAgentName,
|
|
6474
6514
|
provider: this.lastResolvedProviderName,
|
|
6475
6515
|
attempts: emptyResponseAttempts,
|
|
@@ -6479,14 +6519,7 @@ ${tailBody}
|
|
|
6479
6519
|
isSubAgent: this.isSubAgent,
|
|
6480
6520
|
...response.responseMeta
|
|
6481
6521
|
});
|
|
6482
|
-
|
|
6483
|
-
this.failSubAgent(isRefusal ? "refusal" : "empty_response");
|
|
6484
|
-
} else {
|
|
6485
|
-
this.appendDriverNotice(
|
|
6486
|
-
isRefusal ? "This request was declined. Try rephrasing it, or breaking it into smaller steps." : "While working on your request, I repeatedly generated a blank response. This often works on a second try \u2014 would you like me to try again? If it happens again, try breaking your request into smaller steps."
|
|
6487
|
-
);
|
|
6488
|
-
}
|
|
6489
|
-
return this.turnDone(failureReason2);
|
|
6522
|
+
return this.endTurnWithFailure(exit);
|
|
6490
6523
|
} else {
|
|
6491
6524
|
const { reasoning, ...rest } = response;
|
|
6492
6525
|
const displayOnly = {
|
|
@@ -6786,14 +6819,7 @@ RECOVERY: this tool failed once \u2014 you may retry it, or take a different val
|
|
|
6786
6819
|
availableTools: Object.keys(this.toolHandlers),
|
|
6787
6820
|
isSubAgent: this.isSubAgent
|
|
6788
6821
|
});
|
|
6789
|
-
|
|
6790
|
-
this.failSubAgent("unknown_tool_limit");
|
|
6791
|
-
} else {
|
|
6792
|
-
this.appendDriverNotice(
|
|
6793
|
-
"I'm sorry, I repeatedly tried to use tools that aren't available to me, so I couldn't complete that. If a 'Download agent log' option appears in the Settings (cog) menu, you can download the log and share it with whoever set up this assistant to help fix the issue."
|
|
6794
|
-
);
|
|
6795
|
-
}
|
|
6796
|
-
return this.turnDone("unknown-tool-limit");
|
|
6822
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.unknownToolLimit);
|
|
6797
6823
|
}
|
|
6798
6824
|
const firstContinuation = systemCalls[0];
|
|
6799
6825
|
if (firstContinuation) {
|
|
@@ -6804,7 +6830,6 @@ RECOVERY: this tool failed once \u2014 you may retry it, or take a different val
|
|
|
6804
6830
|
return this.turnDone();
|
|
6805
6831
|
}
|
|
6806
6832
|
}
|
|
6807
|
-
let failureReason;
|
|
6808
6833
|
if (iterations >= this.maxToolIterations) {
|
|
6809
6834
|
logger2.warn("ChatDriver: reached max tool iterations, stopping");
|
|
6810
6835
|
recordTurnError(this.sessionKey, "max-iterations", {
|
|
@@ -6814,16 +6839,9 @@ RECOVERY: this tool failed once \u2014 you may retry it, or take a different val
|
|
|
6814
6839
|
limit: this.maxToolIterations,
|
|
6815
6840
|
isSubAgent: this.isSubAgent
|
|
6816
6841
|
});
|
|
6817
|
-
|
|
6818
|
-
this.failSubAgent("max_iterations");
|
|
6819
|
-
} else {
|
|
6820
|
-
this.appendDriverNotice(
|
|
6821
|
-
"I've reached my limit for this response. You can ask me to continue and I'll pick up where I left off."
|
|
6822
|
-
);
|
|
6823
|
-
}
|
|
6824
|
-
failureReason = "max-iterations";
|
|
6842
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.maxIterations);
|
|
6825
6843
|
}
|
|
6826
|
-
return this.turnDone(
|
|
6844
|
+
return this.turnDone();
|
|
6827
6845
|
}
|
|
6828
6846
|
/**
|
|
6829
6847
|
* Append prose the DRIVER wrote rather than the model — a failure notice, a limit explanation,
|