wingbot 3.76.2 → 3.76.4-alpha.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/.claude/settings.local.json +11 -0
- package/package.json +1 -1
- package/src/LLMSession.js +57 -1
- package/src/LLMType.js +7 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(npx mocha:*)",
|
|
5
|
+
"Bash(npx tsc *)",
|
|
6
|
+
"Bash(npm test *)",
|
|
7
|
+
"Bash(node -e \"const p = require\\('./bot/plugins/BTMLLM'\\); console.log\\('factory type:', typeof p\\); console.log\\('factory name:', p.name\\);\")",
|
|
8
|
+
"Bash(grep -n \"prompt\\\\`\\\\|tagged\\\\|render\\\\|compile\\\\|hbs\" /Users/ondrejveres/Wingbot/wingbot-llm/src/prompt.js)"
|
|
9
|
+
]
|
|
10
|
+
}
|
|
11
|
+
}
|
package/package.json
CHANGED
package/src/LLMSession.js
CHANGED
|
@@ -224,6 +224,9 @@ class LLMSession {
|
|
|
224
224
|
this._res = res || llm?.res;
|
|
225
225
|
|
|
226
226
|
this._preset = preset;
|
|
227
|
+
|
|
228
|
+
/** @type {PossiblyAsyncContent|null} */
|
|
229
|
+
this._fallbackMessage = null;
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
/**
|
|
@@ -850,6 +853,38 @@ class LLMSession {
|
|
|
850
853
|
return this;
|
|
851
854
|
}
|
|
852
855
|
|
|
856
|
+
/**
|
|
857
|
+
* Sets a message to send to the user when a subsequent `generate()` call
|
|
858
|
+
* fails (e.g. a provider network timeout). Instead of rejecting - which
|
|
859
|
+
* would surface the raw error to the user - the failure is logged and this
|
|
860
|
+
* message is sent in place of the model's reply, so the chain resolves
|
|
861
|
+
* cleanly. If the message resolves to an empty value, the original error
|
|
862
|
+
* is rethrown (same as when no fallback is set).
|
|
863
|
+
*
|
|
864
|
+
* Only affects `generate()`. `generateStructured()` keeps using delegated
|
|
865
|
+
* errors (see {@link onDelegatedError}).
|
|
866
|
+
*
|
|
867
|
+
* @param {PossiblyAsyncContent} content
|
|
868
|
+
* @returns {this}
|
|
869
|
+
*/
|
|
870
|
+
setFallbackMessage (content) {
|
|
871
|
+
this._job(() => {
|
|
872
|
+
this._fallbackMessage = content;
|
|
873
|
+
}, true);
|
|
874
|
+
return this;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* @returns {Promise<string>}
|
|
879
|
+
*/
|
|
880
|
+
async _resolveFallbackContent () {
|
|
881
|
+
const fallback = this._fallbackMessage;
|
|
882
|
+
const content = typeof fallback === 'function'
|
|
883
|
+
? fallback(this._resolveData())
|
|
884
|
+
: fallback;
|
|
885
|
+
return Promise.resolve(content);
|
|
886
|
+
}
|
|
887
|
+
|
|
853
888
|
/**
|
|
854
889
|
*
|
|
855
890
|
* @param {LLMCallPreset} [providerOptions]
|
|
@@ -857,7 +892,28 @@ class LLMSession {
|
|
|
857
892
|
* @returns {this}
|
|
858
893
|
*/
|
|
859
894
|
generate (providerOptions = this._preset, logOptions = {}) {
|
|
860
|
-
this._job(() =>
|
|
895
|
+
this._job(async () => {
|
|
896
|
+
try {
|
|
897
|
+
return await this._generate(providerOptions, logOptions);
|
|
898
|
+
} catch (e) {
|
|
899
|
+
if (this._fallbackMessage === null) {
|
|
900
|
+
throw e;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
const content = await this._resolveFallbackContent();
|
|
904
|
+
if (!content) {
|
|
905
|
+
// no usable fallback message - propagate the original error
|
|
906
|
+
throw e;
|
|
907
|
+
}
|
|
908
|
+
this._llm.log.error(`LLMSession.generate failed, sending fallback message: ${e.message}`, e);
|
|
909
|
+
|
|
910
|
+
/** @type {LLMMessage} */
|
|
911
|
+
const result = { role: ROLE_ASSISTANT, content };
|
|
912
|
+
this._generatedIndex = this._chat.length;
|
|
913
|
+
this._chat.push(result);
|
|
914
|
+
return result;
|
|
915
|
+
}
|
|
916
|
+
});
|
|
861
917
|
return this;
|
|
862
918
|
}
|
|
863
919
|
|
package/src/LLMType.js
CHANGED
|
@@ -249,6 +249,13 @@ class LLMType {
|
|
|
249
249
|
const childSchema = child.toJSON();
|
|
250
250
|
if (!child._required) {
|
|
251
251
|
childSchema.type = [childSchema.type, 'null'];
|
|
252
|
+
// A nullable enum must also list null among its allowed
|
|
253
|
+
// values — otherwise null satisfies `type` but fails `enum`
|
|
254
|
+
// and is effectively disallowed, forcing the model to pick
|
|
255
|
+
// a value for an optional field.
|
|
256
|
+
if (Array.isArray(childSchema.enum) && !childSchema.enum.includes(null)) {
|
|
257
|
+
childSchema.enum = [...childSchema.enum, null];
|
|
258
|
+
}
|
|
252
259
|
}
|
|
253
260
|
properties[key] = childSchema;
|
|
254
261
|
required.push(key);
|