@genesislcap/ai-assistant 15.23.2 → 15.24.0-FUI-2603.10
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 +421 -52
- package/dist/ai-assistant.d.ts +239 -694
- 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 +361 -602
- 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/dts/components/orchestrating-driver/orchestrating-driver.d.ts +16 -0
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/index.d.ts +1 -0
- package/dist/dts/components/settings-modal/index.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/settings-modal.d.ts +215 -0
- package/dist/dts/components/settings-modal/settings-modal.d.ts.map +1 -0
- package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
- package/dist/dts/main/attachment-controller.d.ts +66 -0
- package/dist/dts/main/attachment-controller.d.ts.map +1 -0
- package/dist/dts/main/budget-controller.d.ts +368 -0
- package/dist/dts/main/budget-controller.d.ts.map +1 -0
- package/dist/dts/main/composer-menu-controller.d.ts +113 -0
- package/dist/dts/main/composer-menu-controller.d.ts.map +1 -0
- package/dist/dts/main/composer-resize-controller.d.ts +80 -0
- package/dist/dts/main/composer-resize-controller.d.ts.map +1 -0
- package/dist/dts/main/context-gate-controller.d.ts +197 -0
- package/dist/dts/main/context-gate-controller.d.ts.map +1 -0
- package/dist/dts/main/cost-ledger-controller.d.ts +228 -0
- package/dist/dts/main/cost-ledger-controller.d.ts.map +1 -0
- package/dist/dts/main/main.d.ts +201 -722
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/main/main.types.d.ts +25 -0
- package/dist/dts/main/main.types.d.ts.map +1 -1
- package/dist/dts/main/meta-snapshot.d.ts +50 -0
- package/dist/dts/main/meta-snapshot.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
- package/dist/esm/components/chat-driver/chat-driver.js +92 -142
- package/dist/esm/components/chat-driver/turn-failures.js +84 -0
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +18 -0
- package/dist/esm/components/settings-modal/index.js +1 -0
- package/dist/esm/components/settings-modal/settings-modal.js +436 -0
- package/dist/esm/components/settings-modal/settings-modal.template.js +15 -4
- package/dist/esm/main/attachment-controller.js +254 -0
- package/dist/esm/main/budget-controller.js +745 -0
- package/dist/esm/main/composer-menu-controller.js +234 -0
- package/dist/esm/main/composer-resize-controller.js +119 -0
- package/dist/esm/main/context-gate-controller.js +289 -0
- package/dist/esm/main/cost-ledger-controller.js +498 -0
- package/dist/esm/main/main.js +501 -2268
- package/dist/esm/main/meta-snapshot.js +108 -0
- package/dist/esm/state/persistence/session-persister.js +5 -4
- package/docs/migration-GENC-1580.md +209 -0
- package/package.json +16 -16
- package/docs/.gitattributes +0 -2
package/dist/chat-driver.cjs
CHANGED
|
@@ -4400,6 +4400,78 @@ function accumulate(messages, into) {
|
|
|
4400
4400
|
// src/utils/tool-fold.ts
|
|
4401
4401
|
var TOOL_FOLD_SYMBOL = Symbol("toolFold");
|
|
4402
4402
|
|
|
4403
|
+
// src/components/chat-driver/turn-failures.ts
|
|
4404
|
+
var TURN_FAILURE_EXITS = {
|
|
4405
|
+
contextGuard: {
|
|
4406
|
+
subReason: "context_exhausted",
|
|
4407
|
+
resultReason: "context-exhausted",
|
|
4408
|
+
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."
|
|
4409
|
+
},
|
|
4410
|
+
contextOverflow: {
|
|
4411
|
+
subReason: "context_exhausted",
|
|
4412
|
+
resultReason: "context-exhausted",
|
|
4413
|
+
copy: DEFAULT_CONTEXT_OVERFLOW_MESSAGE
|
|
4414
|
+
},
|
|
4415
|
+
malformedToolCall: {
|
|
4416
|
+
subReason: "malformed_tool_call",
|
|
4417
|
+
// Not `malformed-tool-call`: the main-turn reason is named after the provider finish
|
|
4418
|
+
// reason (`MALFORMED_FUNCTION_CALL`) that produces it, and is part of the published
|
|
4419
|
+
// TurnFailureReason union, so the two names cannot be brought into line here.
|
|
4420
|
+
resultReason: "malformed-function-call",
|
|
4421
|
+
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."
|
|
4422
|
+
},
|
|
4423
|
+
responseTruncated: {
|
|
4424
|
+
subReason: "response_truncated",
|
|
4425
|
+
resultReason: "response-truncated",
|
|
4426
|
+
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."
|
|
4427
|
+
},
|
|
4428
|
+
timeout: {
|
|
4429
|
+
subReason: "timeout",
|
|
4430
|
+
// There is no `timeout` member of TurnFailureReason, so the main turn reports the
|
|
4431
|
+
// generic `exception`. A sub-agent gets the specific reason because its parent
|
|
4432
|
+
// branches on it to decide whether a retry is worth attempting.
|
|
4433
|
+
resultReason: "exception",
|
|
4434
|
+
copy: "The request timed out. You can ask me to try again, or break this into a smaller step."
|
|
4435
|
+
},
|
|
4436
|
+
unknownToolLimit: {
|
|
4437
|
+
subReason: "unknown_tool_limit",
|
|
4438
|
+
resultReason: "unknown-tool-limit",
|
|
4439
|
+
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."
|
|
4440
|
+
},
|
|
4441
|
+
maxIterations: {
|
|
4442
|
+
subReason: "max_iterations",
|
|
4443
|
+
resultReason: "max-iterations",
|
|
4444
|
+
copy: "I've reached my limit for this response. You can ask me to continue and I'll pick up where I left off."
|
|
4445
|
+
},
|
|
4446
|
+
refusal: {
|
|
4447
|
+
subReason: "refusal",
|
|
4448
|
+
resultReason: "refusal",
|
|
4449
|
+
copy: "This request was declined. Try rephrasing it, or breaking it into smaller steps."
|
|
4450
|
+
},
|
|
4451
|
+
emptyResponse: {
|
|
4452
|
+
subReason: "empty_response",
|
|
4453
|
+
resultReason: "empty-response",
|
|
4454
|
+
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."
|
|
4455
|
+
},
|
|
4456
|
+
providerRefused: {
|
|
4457
|
+
subReason: "provider_refused",
|
|
4458
|
+
resultReason: "provider-refused",
|
|
4459
|
+
// Overridden per wall by `ChatDriver.providerRefusedBubble`, which prefers a
|
|
4460
|
+
// host-supplied message; this is the fallback that method returns.
|
|
4461
|
+
copy: DEFAULT_PROVIDER_REFUSED_MESSAGE
|
|
4462
|
+
},
|
|
4463
|
+
budgetExhausted: {
|
|
4464
|
+
subReason: "budget_exhausted",
|
|
4465
|
+
resultReason: "budget-exhausted",
|
|
4466
|
+
// Overridden per wall by `ChatDriver.budgetExhaustedBubble`, which upgrades this with
|
|
4467
|
+
// "switch to another AI" when a second vendor is reachable.
|
|
4468
|
+
copy: DEFAULT_BUDGET_EXHAUSTED_MESSAGE
|
|
4469
|
+
}
|
|
4470
|
+
// `satisfies`, not an annotation: an annotation would widen `resultReason` to
|
|
4471
|
+
// `TurnFailureReason` and cost the literal types that let `turn-failures.test.ts` pin the
|
|
4472
|
+
// two deliberate divergences at compile time instead of at runtime.
|
|
4473
|
+
};
|
|
4474
|
+
|
|
4403
4475
|
// src/components/chat-driver/chat-driver.ts
|
|
4404
4476
|
var toolResultImages = (result) => {
|
|
4405
4477
|
if (!result || typeof result !== "object") return void 0;
|
|
@@ -4774,6 +4846,33 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
4774
4846
|
...providerRefused ? { providerRefused } : {}
|
|
4775
4847
|
};
|
|
4776
4848
|
}
|
|
4849
|
+
/**
|
|
4850
|
+
* End the turn on a terminal failure: fail upward when this driver is a sub-agent, speak
|
|
4851
|
+
* to the user when it is not, and hand the reason to the caller either way.
|
|
4852
|
+
*
|
|
4853
|
+
* Only that fork lives here. Each exit keeps its own `recordTurnError` call, because the
|
|
4854
|
+
* telemetry payload is what legitimately differs between them — attempt counts, token
|
|
4855
|
+
* figures, tool names — and folding it in would mean one optional field per condition.
|
|
4856
|
+
*
|
|
4857
|
+
* `overrides.copy` serves the two walls whose prose is composed per occurrence:
|
|
4858
|
+
* `budgetExhaustedBubble` names the vendor and can offer another, `providerRefusedBubble`
|
|
4859
|
+
* prefers a host-supplied message. Every other exit reads its copy from the table.
|
|
4860
|
+
*
|
|
4861
|
+
* One exit stays out: the `BudgetExhaustedError` catch. Not because its shape differs —
|
|
4862
|
+
* its two telemetry payloads are field-for-field identical — but because its main-turn
|
|
4863
|
+
* branch calls `reportBudgetExhausted`, which is public and also serves
|
|
4864
|
+
* `OrchestratingDriver`'s classification phase, where no tool loop is running. That
|
|
4865
|
+
* method has to survive either way, so routing the catch through here would relocate the
|
|
4866
|
+
* duplication rather than remove it.
|
|
4867
|
+
*/
|
|
4868
|
+
endTurnWithFailure(exit, overrides) {
|
|
4869
|
+
if (this.isSubAgent) {
|
|
4870
|
+
this.failSubAgent(exit.subReason, overrides?.budget, overrides?.providerRefused);
|
|
4871
|
+
} else {
|
|
4872
|
+
this.appendDriverNotice(overrides?.copy ?? exit.copy);
|
|
4873
|
+
}
|
|
4874
|
+
return this.turnDone(exit.resultReason, overrides?.budget, overrides?.providerRefused);
|
|
4875
|
+
}
|
|
4777
4876
|
/**
|
|
4778
4877
|
* Terminal budget outcome for a wall hit **outside** the tool loop — today,
|
|
4779
4878
|
* `OrchestratingDriver`'s classification phase, which calls the provider
|
|
@@ -4802,7 +4901,7 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
4802
4901
|
*/
|
|
4803
4902
|
budgetExhaustedBubble(wall) {
|
|
4804
4903
|
if (this.budgetExhaustedMessageOverride != null) return this.budgetExhaustedMessageOverride;
|
|
4805
|
-
if (wall?.otherVendorAvailable !== true) return
|
|
4904
|
+
if (wall?.otherVendorAvailable !== true) return TURN_FAILURE_EXITS.budgetExhausted.copy;
|
|
4806
4905
|
const subject = wall?.vendorLabel ? `${wall.vendorLabel}'s AI usage limit` : "your AI usage limit";
|
|
4807
4906
|
return `You've reached ${subject}. Switch to another AI provider in Settings to keep going, or contact your administrator to raise it.`;
|
|
4808
4907
|
}
|
|
@@ -4836,32 +4935,7 @@ var ChatDriver = class _ChatDriver extends EventTarget {
|
|
|
4836
4935
|
* has gone unpaid — so there is nothing here to compose. A host override wins verbatim.
|
|
4837
4936
|
*/
|
|
4838
4937
|
providerRefusedBubble() {
|
|
4839
|
-
return this.providerRefusedMessageOverride ??
|
|
4840
|
-
}
|
|
4841
|
-
/**
|
|
4842
|
-
* Terminal provider-refusal outcome. Mirrors `reportBudgetExhausted` so the two walls behave
|
|
4843
|
-
* identically from the caller's side, while keeping their diagnostics distinct.
|
|
4844
|
-
*
|
|
4845
|
-
* `kind` reaches the debug log and the result but never the transcript: it is what lets an operator
|
|
4846
|
-
* tell "top up the account" from "rotate the key", and with cause-free user copy this is the only
|
|
4847
|
-
* place that distinction survives.
|
|
4848
|
-
*/
|
|
4849
|
-
reportProviderRefused(e) {
|
|
4850
|
-
const detail = providerRefusedDetailOf(e);
|
|
4851
|
-
this.providerRefusedThisTurn = true;
|
|
4852
|
-
this.providerRefusedDetail = detail;
|
|
4853
|
-
logger2.error("ChatDriver: provider refused the request", e);
|
|
4854
|
-
recordTurnError(this.sessionKey, "provider-refused", {
|
|
4855
|
-
agent: this.activeAgentName,
|
|
4856
|
-
provider: this.lastResolvedProviderName,
|
|
4857
|
-
vendor: vendorTypeOfLabel(e.vendorLabel) ?? this.lastResolvedProvider,
|
|
4858
|
-
kind: e.kind,
|
|
4859
|
-
upstreamStatus: e.upstreamStatus,
|
|
4860
|
-
upstreamType: e.upstreamType,
|
|
4861
|
-
isSubAgent: this.isSubAgent
|
|
4862
|
-
});
|
|
4863
|
-
this.appendDriverNotice(this.providerRefusedBubble());
|
|
4864
|
-
return this.turnDone("provider-refused", void 0, detail);
|
|
4938
|
+
return this.providerRefusedMessageOverride ?? TURN_FAILURE_EXITS.providerRefused.copy;
|
|
4865
4939
|
}
|
|
4866
4940
|
/** The typed failure reason on a loop result, or `undefined` for a clean turn / handoff. */
|
|
4867
4941
|
static failureReasonOf(result) {
|
|
@@ -6152,12 +6226,10 @@ Output format (strict):
|
|
|
6152
6226
|
via: "sub-agent",
|
|
6153
6227
|
isSubAgent: this.isSubAgent
|
|
6154
6228
|
});
|
|
6155
|
-
|
|
6156
|
-
this.
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
}
|
|
6160
|
-
return this.turnDone("provider-refused", void 0, this.providerRefusedDetail);
|
|
6229
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.providerRefused, {
|
|
6230
|
+
copy: this.providerRefusedBubble(),
|
|
6231
|
+
providerRefused: this.providerRefusedDetail
|
|
6232
|
+
});
|
|
6161
6233
|
}
|
|
6162
6234
|
if (this.budgetExhaustedThisTurn) {
|
|
6163
6235
|
logger2.error("ChatDriver: ending the turn \u2014 a sub-agent hit the AI budget wall");
|
|
@@ -6177,12 +6249,10 @@ Output format (strict):
|
|
|
6177
6249
|
via: "sub-agent",
|
|
6178
6250
|
isSubAgent: this.isSubAgent
|
|
6179
6251
|
});
|
|
6180
|
-
|
|
6181
|
-
this.
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
}
|
|
6185
|
-
return this.turnDone("budget-exhausted", this.budgetWallDetail);
|
|
6252
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.budgetExhausted, {
|
|
6253
|
+
copy: this.budgetExhaustedBubble(this.budgetWallDetail),
|
|
6254
|
+
budget: this.budgetWallDetail
|
|
6255
|
+
});
|
|
6186
6256
|
}
|
|
6187
6257
|
const promptCtx = {
|
|
6188
6258
|
agentName: this.activeAgentName ?? "",
|
|
@@ -6347,14 +6417,7 @@ ${tailBody}
|
|
|
6347
6417
|
iterations,
|
|
6348
6418
|
isSubAgent: this.isSubAgent
|
|
6349
6419
|
});
|
|
6350
|
-
|
|
6351
|
-
this.failSubAgent("context_exhausted");
|
|
6352
|
-
} else {
|
|
6353
|
-
this.appendDriverNotice(
|
|
6354
|
-
"I had to stop here \u2014 this conversation has filled the available context. Compact it to free up room, then ask me to continue."
|
|
6355
|
-
);
|
|
6356
|
-
}
|
|
6357
|
-
return this.turnDone("context-exhausted");
|
|
6420
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.contextGuard);
|
|
6358
6421
|
}
|
|
6359
6422
|
let response;
|
|
6360
6423
|
try {
|
|
@@ -6384,14 +6447,7 @@ ${tailBody}
|
|
|
6384
6447
|
finishMessage: e.finishMessage,
|
|
6385
6448
|
isSubAgent: this.isSubAgent
|
|
6386
6449
|
});
|
|
6387
|
-
|
|
6388
|
-
this.failSubAgent("malformed_tool_call");
|
|
6389
|
-
} else {
|
|
6390
|
-
this.appendDriverNotice(
|
|
6391
|
-
"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."
|
|
6392
|
-
);
|
|
6393
|
-
}
|
|
6394
|
-
return this.turnDone("malformed-function-call");
|
|
6450
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.malformedToolCall);
|
|
6395
6451
|
}
|
|
6396
6452
|
if (e instanceof ResponseTruncatedError) {
|
|
6397
6453
|
logger2.error("ChatDriver: response truncated at the output-token cap", e);
|
|
@@ -6404,14 +6460,7 @@ ${tailBody}
|
|
|
6404
6460
|
tools: e.toolNames,
|
|
6405
6461
|
isSubAgent: this.isSubAgent
|
|
6406
6462
|
});
|
|
6407
|
-
|
|
6408
|
-
this.failSubAgent("response_truncated");
|
|
6409
|
-
} else {
|
|
6410
|
-
this.appendDriverNotice(
|
|
6411
|
-
"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."
|
|
6412
|
-
);
|
|
6413
|
-
}
|
|
6414
|
-
return this.turnDone("response-truncated");
|
|
6463
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.responseTruncated);
|
|
6415
6464
|
}
|
|
6416
6465
|
if (e instanceof ContextOverflowError) {
|
|
6417
6466
|
logger2.error("ChatDriver: the prompt exceeded the model context window", e);
|
|
@@ -6424,30 +6473,28 @@ ${tailBody}
|
|
|
6424
6473
|
via: "provider",
|
|
6425
6474
|
isSubAgent: this.isSubAgent
|
|
6426
6475
|
});
|
|
6427
|
-
|
|
6428
|
-
this.failSubAgent("context_exhausted");
|
|
6429
|
-
} else {
|
|
6430
|
-
this.appendDriverNotice(DEFAULT_CONTEXT_OVERFLOW_MESSAGE);
|
|
6431
|
-
}
|
|
6432
|
-
return this.turnDone("context-exhausted");
|
|
6476
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.contextOverflow);
|
|
6433
6477
|
}
|
|
6434
6478
|
if (e instanceof ProviderRefusedError) {
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
provider: this.lastResolvedProviderName,
|
|
6440
|
-
vendor: vendorTypeOfLabel(e.vendorLabel) ?? this.lastResolvedProvider,
|
|
6441
|
-
kind: e.kind,
|
|
6442
|
-
upstreamStatus: e.upstreamStatus,
|
|
6443
|
-
upstreamType: e.upstreamType,
|
|
6444
|
-
isSubAgent: true
|
|
6445
|
-
});
|
|
6446
|
-
const detail = providerRefusedDetailOf(e);
|
|
6447
|
-
this.failSubAgent("provider_refused", void 0, detail);
|
|
6448
|
-
return this.turnDone("provider-refused", void 0, detail);
|
|
6479
|
+
const detail = providerRefusedDetailOf(e);
|
|
6480
|
+
if (!this.isSubAgent) {
|
|
6481
|
+
this.providerRefusedThisTurn = true;
|
|
6482
|
+
this.providerRefusedDetail = detail;
|
|
6449
6483
|
}
|
|
6450
|
-
|
|
6484
|
+
logger2.error("ChatDriver: provider refused the request", e);
|
|
6485
|
+
recordTurnError(this.sessionKey, "provider-refused", {
|
|
6486
|
+
agent: this.activeAgentName,
|
|
6487
|
+
provider: this.lastResolvedProviderName,
|
|
6488
|
+
vendor: vendorTypeOfLabel(e.vendorLabel) ?? this.lastResolvedProvider,
|
|
6489
|
+
kind: e.kind,
|
|
6490
|
+
upstreamStatus: e.upstreamStatus,
|
|
6491
|
+
upstreamType: e.upstreamType,
|
|
6492
|
+
isSubAgent: this.isSubAgent
|
|
6493
|
+
});
|
|
6494
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.providerRefused, {
|
|
6495
|
+
copy: this.providerRefusedBubble(),
|
|
6496
|
+
providerRefused: detail
|
|
6497
|
+
});
|
|
6451
6498
|
}
|
|
6452
6499
|
if (e instanceof BudgetExhaustedError) {
|
|
6453
6500
|
this.budgetExhaustedThisTurn = true;
|
|
@@ -6477,14 +6524,7 @@ ${tailBody}
|
|
|
6477
6524
|
message: e.message,
|
|
6478
6525
|
isSubAgent: this.isSubAgent
|
|
6479
6526
|
});
|
|
6480
|
-
|
|
6481
|
-
this.failSubAgent("timeout");
|
|
6482
|
-
} else {
|
|
6483
|
-
this.appendDriverNotice(
|
|
6484
|
-
"The request timed out. You can ask me to try again, or break this into a smaller step."
|
|
6485
|
-
);
|
|
6486
|
-
}
|
|
6487
|
-
return this.turnDone("exception");
|
|
6527
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.timeout);
|
|
6488
6528
|
}
|
|
6489
6529
|
if (e instanceof DOMException && e.name === "AbortError") {
|
|
6490
6530
|
return this.completeAbortedTurn();
|
|
@@ -6536,11 +6576,11 @@ ${tailBody}
|
|
|
6536
6576
|
iterations -= 1;
|
|
6537
6577
|
continue;
|
|
6538
6578
|
}
|
|
6539
|
-
const
|
|
6579
|
+
const exit = isRefusal ? TURN_FAILURE_EXITS.refusal : TURN_FAILURE_EXITS.emptyResponse;
|
|
6540
6580
|
logger2.error(
|
|
6541
6581
|
isRefusal ? "ChatDriver: model refused the request (safety decline) \u2014 not retrying" : "ChatDriver: empty model response after all retries"
|
|
6542
6582
|
);
|
|
6543
|
-
recordTurnError(this.sessionKey,
|
|
6583
|
+
recordTurnError(this.sessionKey, exit.resultReason, {
|
|
6544
6584
|
agent: this.activeAgentName,
|
|
6545
6585
|
provider: this.lastResolvedProviderName,
|
|
6546
6586
|
attempts: emptyResponseAttempts,
|
|
@@ -6550,14 +6590,7 @@ ${tailBody}
|
|
|
6550
6590
|
isSubAgent: this.isSubAgent,
|
|
6551
6591
|
...response.responseMeta
|
|
6552
6592
|
});
|
|
6553
|
-
|
|
6554
|
-
this.failSubAgent(isRefusal ? "refusal" : "empty_response");
|
|
6555
|
-
} else {
|
|
6556
|
-
this.appendDriverNotice(
|
|
6557
|
-
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."
|
|
6558
|
-
);
|
|
6559
|
-
}
|
|
6560
|
-
return this.turnDone(failureReason2);
|
|
6593
|
+
return this.endTurnWithFailure(exit);
|
|
6561
6594
|
} else {
|
|
6562
6595
|
const { reasoning, ...rest } = response;
|
|
6563
6596
|
const displayOnly = {
|
|
@@ -6857,14 +6890,7 @@ RECOVERY: this tool failed once \u2014 you may retry it, or take a different val
|
|
|
6857
6890
|
availableTools: Object.keys(this.toolHandlers),
|
|
6858
6891
|
isSubAgent: this.isSubAgent
|
|
6859
6892
|
});
|
|
6860
|
-
|
|
6861
|
-
this.failSubAgent("unknown_tool_limit");
|
|
6862
|
-
} else {
|
|
6863
|
-
this.appendDriverNotice(
|
|
6864
|
-
"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."
|
|
6865
|
-
);
|
|
6866
|
-
}
|
|
6867
|
-
return this.turnDone("unknown-tool-limit");
|
|
6893
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.unknownToolLimit);
|
|
6868
6894
|
}
|
|
6869
6895
|
const firstContinuation = systemCalls[0];
|
|
6870
6896
|
if (firstContinuation) {
|
|
@@ -6875,7 +6901,6 @@ RECOVERY: this tool failed once \u2014 you may retry it, or take a different val
|
|
|
6875
6901
|
return this.turnDone();
|
|
6876
6902
|
}
|
|
6877
6903
|
}
|
|
6878
|
-
let failureReason;
|
|
6879
6904
|
if (iterations >= this.maxToolIterations) {
|
|
6880
6905
|
logger2.warn("ChatDriver: reached max tool iterations, stopping");
|
|
6881
6906
|
recordTurnError(this.sessionKey, "max-iterations", {
|
|
@@ -6885,16 +6910,9 @@ RECOVERY: this tool failed once \u2014 you may retry it, or take a different val
|
|
|
6885
6910
|
limit: this.maxToolIterations,
|
|
6886
6911
|
isSubAgent: this.isSubAgent
|
|
6887
6912
|
});
|
|
6888
|
-
|
|
6889
|
-
this.failSubAgent("max_iterations");
|
|
6890
|
-
} else {
|
|
6891
|
-
this.appendDriverNotice(
|
|
6892
|
-
"I've reached my limit for this response. You can ask me to continue and I'll pick up where I left off."
|
|
6893
|
-
);
|
|
6894
|
-
}
|
|
6895
|
-
failureReason = "max-iterations";
|
|
6913
|
+
return this.endTurnWithFailure(TURN_FAILURE_EXITS.maxIterations);
|
|
6896
6914
|
}
|
|
6897
|
-
return this.turnDone(
|
|
6915
|
+
return this.turnDone();
|
|
6898
6916
|
}
|
|
6899
6917
|
/**
|
|
6900
6918
|
* Append prose the DRIVER wrote rather than the model — a failure notice, a limit explanation,
|