wingbot 3.77.0-alpha.1 → 3.77.0-alpha.3
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/package.json +1 -1
- package/src/ChatGpt.js +3 -1
- package/src/LLMSession.js +73 -4
- package/src/LLMToolRunner.js +8 -0
- package/src/Responder.js +36 -12
package/package.json
CHANGED
package/src/ChatGpt.js
CHANGED
|
@@ -450,8 +450,10 @@ class ChatGpt {
|
|
|
450
450
|
...(requestTokens ? {
|
|
451
451
|
max_completion_tokens: requestTokens
|
|
452
452
|
} : {}),
|
|
453
|
+
// Chat Completions takes "reasoning_effort" ("reasoning: { effort }" is the
|
|
454
|
+
// Responses API - here 400 Unknown parameter)
|
|
453
455
|
...(reasoningEffort ? {
|
|
454
|
-
|
|
456
|
+
reasoning_effort: reasoningEffort
|
|
455
457
|
} : {}),
|
|
456
458
|
...(typeof parallelToolCalls === 'boolean' ? {
|
|
457
459
|
parallel_tool_calls: parallelToolCalls
|
package/src/LLMSession.js
CHANGED
|
@@ -170,6 +170,14 @@ const stateData = require('./utils/stateData');
|
|
|
170
170
|
* @prop {Responder} [res]
|
|
171
171
|
* @prop {object} [data]
|
|
172
172
|
* @prop {LLMCallPreset} [preset]
|
|
173
|
+
* @prop {SystemSource} [system] - the system prompt of the session - compiled again,
|
|
174
|
+
* when recompileSystemPrompt() is called (e.g. a tool changed the state)
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @callback SystemSource
|
|
179
|
+
* @param {boolean} recompile - false at the start, true to compile the instructions again
|
|
180
|
+
* @returns {Promise<LLMMessage[]>}
|
|
173
181
|
*/
|
|
174
182
|
|
|
175
183
|
// max number of consecutive tool-call rounds resolved within a single generate()
|
|
@@ -219,11 +227,20 @@ class LLMSession {
|
|
|
219
227
|
data = {},
|
|
220
228
|
req = null,
|
|
221
229
|
res = null,
|
|
222
|
-
preset = undefined
|
|
230
|
+
preset = undefined,
|
|
231
|
+
system = null
|
|
223
232
|
} = options;
|
|
224
233
|
|
|
225
234
|
this._llm = llm;
|
|
226
235
|
|
|
236
|
+
/** @type {SystemSource|null} */
|
|
237
|
+
this._systemSource = system;
|
|
238
|
+
|
|
239
|
+
/** @type {Set<object>} - the system messages compiled from the system source */
|
|
240
|
+
this._compiledSystem = new Set();
|
|
241
|
+
|
|
242
|
+
this._systemRecompileRequested = false;
|
|
243
|
+
|
|
227
244
|
this._onSend = onSend;
|
|
228
245
|
|
|
229
246
|
this._inExecution = false;
|
|
@@ -234,6 +251,9 @@ class LLMSession {
|
|
|
234
251
|
|
|
235
252
|
/** @type {LLMMessageSrc[]} */
|
|
236
253
|
this._chat = [];
|
|
254
|
+
if (system) {
|
|
255
|
+
this.push(this._compileSystem(false));
|
|
256
|
+
}
|
|
237
257
|
this.push(...chat);
|
|
238
258
|
|
|
239
259
|
this._generatedIndex = null;
|
|
@@ -822,6 +842,55 @@ class LLMSession {
|
|
|
822
842
|
return this;
|
|
823
843
|
}
|
|
824
844
|
|
|
845
|
+
/**
|
|
846
|
+
* @param {boolean} recompile
|
|
847
|
+
* @returns {Promise<LLMMessage[]>}
|
|
848
|
+
*/
|
|
849
|
+
async _compileSystem (recompile) {
|
|
850
|
+
const messages = await this._systemSource(recompile);
|
|
851
|
+
messages.forEach((m) => this._compiledSystem.add(m));
|
|
852
|
+
return messages;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* The system prompt (from the system source of the session) is compiled again
|
|
857
|
+
* before the next request to the LLM - e.g. a tool changed the language or the buttons
|
|
858
|
+
* under the answer. The other system messages stay.
|
|
859
|
+
*
|
|
860
|
+
* @returns {this}
|
|
861
|
+
*/
|
|
862
|
+
recompileSystemPrompt () {
|
|
863
|
+
this._systemRecompileRequested = !!this._systemSource;
|
|
864
|
+
return this;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
async _recompileSystemIfRequested () {
|
|
868
|
+
if (!this._systemRecompileRequested) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
this._systemRecompileRequested = false;
|
|
872
|
+
|
|
873
|
+
const previous = this._compiledSystem;
|
|
874
|
+
this._compiledSystem = new Set();
|
|
875
|
+
const messages = await this._compileSystem(true);
|
|
876
|
+
|
|
877
|
+
// the new messages at the place of the previous ones
|
|
878
|
+
const at = this._chat.findIndex((m) => previous.has(m));
|
|
879
|
+
const chat = this._chat.filter((m) => !previous.has(m));
|
|
880
|
+
chat.splice(at === -1 ? 0 : at, 0, ...messages);
|
|
881
|
+
this._chat = chat;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* @param {LLMCallPreset} providerOptions
|
|
886
|
+
* @param {LLMLogOptions} logOptions
|
|
887
|
+
* @returns {Promise<LLMMessage<any>>}
|
|
888
|
+
*/
|
|
889
|
+
async _requestLlm (providerOptions, logOptions) {
|
|
890
|
+
await this._recompileSystemIfRequested();
|
|
891
|
+
return this._llm.generate(this, providerOptions, logOptions);
|
|
892
|
+
}
|
|
893
|
+
|
|
825
894
|
/**
|
|
826
895
|
*
|
|
827
896
|
* @param {string|Promise<string>|Renderer} content
|
|
@@ -1032,7 +1101,7 @@ class LLMSession {
|
|
|
1032
1101
|
*/
|
|
1033
1102
|
async _generate (providerOptions = this._preset, logOptions = {}) {
|
|
1034
1103
|
const { maxToolCallRounds = MAX_TOOL_CALL_ROUNDS } = this._llm.llmOptions(providerOptions);
|
|
1035
|
-
let result = await this.
|
|
1104
|
+
let result = await this._requestLlm(providerOptions, logOptions);
|
|
1036
1105
|
|
|
1037
1106
|
// the model may chain several rounds of tool calls before it produces
|
|
1038
1107
|
// a final text answer - keep resolving them until it stops (bounded)
|
|
@@ -1068,7 +1137,7 @@ class LLMSession {
|
|
|
1068
1137
|
}
|
|
1069
1138
|
|
|
1070
1139
|
if (toolCalls.length) {
|
|
1071
|
-
result = await this.
|
|
1140
|
+
result = await this._requestLlm(providerOptions, logOptions);
|
|
1072
1141
|
} else {
|
|
1073
1142
|
// everything failed - force a final text answer without tools
|
|
1074
1143
|
this._llm.log.error(
|
|
@@ -1115,7 +1184,7 @@ class LLMSession {
|
|
|
1115
1184
|
...providerOptions,
|
|
1116
1185
|
toolChoice: 'none'
|
|
1117
1186
|
};
|
|
1118
|
-
return this.
|
|
1187
|
+
return this._requestLlm(overrideChoice, logOptions);
|
|
1119
1188
|
}
|
|
1120
1189
|
|
|
1121
1190
|
/**
|
package/src/LLMToolRunner.js
CHANGED
|
@@ -463,6 +463,14 @@ class LLMToolRunner {
|
|
|
463
463
|
// only the buttons of the last situation are offered (the earlier ones are outdated)
|
|
464
464
|
this.quickReplies = [];
|
|
465
465
|
this._addButtons(sitDef, situation, values);
|
|
466
|
+
|
|
467
|
+
// the answer of the LLM follows - its system prompt compiled again: the tool could change
|
|
468
|
+
// the state (e.g. the language) and these buttons go under the answer ({{$qrTexts}})
|
|
469
|
+
res.setData({ _qRepliesToSend: [...this.quickReplies] });
|
|
470
|
+
if (session && typeof session.recompileSystemPrompt === 'function') {
|
|
471
|
+
session.recompileSystemPrompt();
|
|
472
|
+
}
|
|
473
|
+
|
|
466
474
|
return this._instructionText(sitDef, situation, values);
|
|
467
475
|
}
|
|
468
476
|
|
package/src/Responder.js
CHANGED
|
@@ -262,6 +262,17 @@ class Responder {
|
|
|
262
262
|
[this.LLM_ERROR, []]
|
|
263
263
|
]);
|
|
264
264
|
|
|
265
|
+
/**
|
|
266
|
+
* the instructions as added - _llmContext keeps them compiled (once in the request),
|
|
267
|
+
* these compile them again (e.g. after a tool changed the state)
|
|
268
|
+
*
|
|
269
|
+
* @type {Map<string,PromptContextItem[]>}
|
|
270
|
+
*/
|
|
271
|
+
this._llmContextSource = new Map([
|
|
272
|
+
[this.LLM_CTX_DEFAULT, []],
|
|
273
|
+
[this.LLM_ERROR, []]
|
|
274
|
+
]);
|
|
275
|
+
|
|
265
276
|
/** @type {Map<string,PreprocessedRule[]>} */
|
|
266
277
|
this._llmResultRules = new Map([
|
|
267
278
|
[this.LLM_CTX_DEFAULT, []]
|
|
@@ -298,8 +309,10 @@ class Responder {
|
|
|
298
309
|
if (!this._llmContext.has(contextType)) {
|
|
299
310
|
// @todo make it array of messages / maybe keep it in a single array
|
|
300
311
|
this._llmContext.set(contextType, []);
|
|
312
|
+
this._llmContextSource.set(contextType, []);
|
|
301
313
|
}
|
|
302
314
|
this._llmContext.get(contextType).push(systemPrompt);
|
|
315
|
+
this._llmContextSource.get(contextType).push(systemPrompt);
|
|
303
316
|
|
|
304
317
|
return this;
|
|
305
318
|
}
|
|
@@ -390,10 +403,11 @@ class Responder {
|
|
|
390
403
|
/**
|
|
391
404
|
*
|
|
392
405
|
* @param {string} contextType
|
|
406
|
+
* @param {boolean} [recompile] - compile the instructions again (the state could change)
|
|
393
407
|
* @returns {AsyncLLMMessage}
|
|
394
408
|
*/
|
|
395
|
-
async _getSystemMessagesForType (contextType) {
|
|
396
|
-
const system = await this._getSystemContentForType(contextType);
|
|
409
|
+
async _getSystemMessagesForType (contextType, recompile = false) {
|
|
410
|
+
const system = await this._getSystemContentForType(contextType, [], recompile);
|
|
397
411
|
return system.map((content) => ({ role: LLM.ROLE_SYSTEM, content }));
|
|
398
412
|
}
|
|
399
413
|
|
|
@@ -405,14 +419,14 @@ class Responder {
|
|
|
405
419
|
* @returns {LLMSession}
|
|
406
420
|
*/
|
|
407
421
|
llmSession (contextType = this.LLM_CTX_DEFAULT, callPreset = undefined, errorPrompt = undefined) { // eslint-disable-line max-len
|
|
408
|
-
const system = this._getSystemMessagesForType(contextType);
|
|
409
|
-
|
|
410
422
|
const filters = this._filtersForContext(contextType);
|
|
411
|
-
const session = new LLMSession(this.llm, [
|
|
423
|
+
const session = new LLMSession(this.llm, [], {
|
|
412
424
|
onSend: this._llmSend.bind(this),
|
|
413
425
|
filters,
|
|
414
426
|
preset: callPreset,
|
|
415
|
-
res: this
|
|
427
|
+
res: this,
|
|
428
|
+
// compiled again on demand (session.recompileSystemPrompt())
|
|
429
|
+
system: (recompile) => this._getSystemMessagesForType(contextType, recompile)
|
|
416
430
|
});
|
|
417
431
|
session.onDelegatedError(
|
|
418
432
|
errorPrompt ?? (() => this._getSystemContentForType(this.LLM_ERROR)
|
|
@@ -483,9 +497,10 @@ class Responder {
|
|
|
483
497
|
*
|
|
484
498
|
* @param {string} contextType
|
|
485
499
|
* @param {string[]} [callStack]
|
|
500
|
+
* @param {boolean} [recompile] - compile the instructions again (the state could change)
|
|
486
501
|
* @returns {Promise<string[]>}
|
|
487
502
|
*/
|
|
488
|
-
async _getSystemContentForType (contextType, callStack = []) {
|
|
503
|
+
async _getSystemContentForType (contextType, callStack = [], recompile = false) {
|
|
489
504
|
if (new Set(callStack).size < callStack.length) {
|
|
490
505
|
throw new Error(`Circular reference detected: contextType -> ${callStack}`);
|
|
491
506
|
}
|
|
@@ -494,9 +509,14 @@ class Responder {
|
|
|
494
509
|
return [];
|
|
495
510
|
}
|
|
496
511
|
|
|
512
|
+
// compiled once in the request - again only on demand (from the instructions as added)
|
|
513
|
+
const parts = recompile && this._llmContextSource.has(contextType)
|
|
514
|
+
? this._llmContextSource.get(contextType)
|
|
515
|
+
: this._llmContext.get(contextType);
|
|
516
|
+
|
|
497
517
|
/** @typedef {Promise<string>} PromisedString */
|
|
498
518
|
/** @type {PromisedString[]} */
|
|
499
|
-
const promiseStrings =
|
|
519
|
+
const promiseStrings = parts
|
|
500
520
|
.map(async (p) => (typeof p === 'function' ? p(this) : p));
|
|
501
521
|
this._llmContext.set(contextType, promiseStrings);
|
|
502
522
|
|
|
@@ -506,8 +526,11 @@ class Responder {
|
|
|
506
526
|
const s = await promiseString;
|
|
507
527
|
|
|
508
528
|
const replaced = await this._replaceAsync(s.trim(), /\$\{([a-zA-Z0-9\s]+)\}/g, async (str, reqType) => {
|
|
509
|
-
const nested = await this
|
|
510
|
-
|
|
529
|
+
const nested = await this._getSystemContentForType(
|
|
530
|
+
reqType,
|
|
531
|
+
[...callStack, contextType],
|
|
532
|
+
recompile
|
|
533
|
+
);
|
|
511
534
|
|
|
512
535
|
return nested.join('\n\n');
|
|
513
536
|
});
|
|
@@ -539,13 +562,14 @@ class Responder {
|
|
|
539
562
|
|
|
540
563
|
const filters = this._filtersForContext(contextType);
|
|
541
564
|
const session = new LLMSession(this.llm, [
|
|
542
|
-
this._getSystemMessagesForType(contextType),
|
|
543
565
|
this._getTranscriptMessages(transcriptLength, transcriptFlag, transcriptAnonymize)
|
|
544
566
|
], {
|
|
545
567
|
onSend: this._llmSend.bind(this),
|
|
546
568
|
filters,
|
|
547
569
|
preset: callPreset,
|
|
548
|
-
res: this
|
|
570
|
+
res: this,
|
|
571
|
+
// compiled again on demand (session.recompileSystemPrompt())
|
|
572
|
+
system: (recompile) => this._getSystemMessagesForType(contextType, recompile)
|
|
549
573
|
});
|
|
550
574
|
session.onDelegatedError(
|
|
551
575
|
errorPrompt ?? (() => this._getSystemContentForType(this.LLM_ERROR)
|