@yeaft/webchat-agent 0.1.1000 → 0.1.1001
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
CHANGED
package/yeaft/effort.js
CHANGED
|
@@ -61,7 +61,7 @@ export const SCENARIO_EFFORT = Object.freeze({
|
|
|
61
61
|
* Pick the effort level for a given query context.
|
|
62
62
|
*
|
|
63
63
|
* Decision order:
|
|
64
|
-
* 1. If userEffort is a valid Effort ('low'|'medium'|'high'|'max'),
|
|
64
|
+
* 1. If userEffort is a valid Effort ('minimal'|'low'|'medium'|'high'|'max'),
|
|
65
65
|
* return it unchanged. This is the explicit override path —
|
|
66
66
|
* `/max` prefix, Settings slider, or API caller.
|
|
67
67
|
* 2. If toolLoopTurns >= LONG_LOOP_TURN_THRESHOLD, upgrade the
|
|
@@ -74,7 +74,7 @@ export const SCENARIO_EFFORT = Object.freeze({
|
|
|
74
74
|
* already consumed in the current `query()` call.
|
|
75
75
|
* @param {unknown} [ctx.userEffort=null] — User-supplied override.
|
|
76
76
|
* Invalid values are ignored (fall through to scenario path).
|
|
77
|
-
* @returns {'low'|'medium'|'high'|'max'} Resolved effort. Never null —
|
|
77
|
+
* @returns {'minimal'|'low'|'medium'|'high'|'max'} Resolved effort. Never null —
|
|
78
78
|
* the adapter/router is responsible for dropping it when the
|
|
79
79
|
* feature flag is off or the model doesn't support thinking.
|
|
80
80
|
*/
|
|
@@ -52,9 +52,9 @@ function thinkingV1Enabled() {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* Translate a normalised effort ('low'|'medium'|'high'|'max') into the value
|
|
55
|
+
* Translate a normalised effort ('minimal'|'low'|'medium'|'high'|'max') into the value
|
|
56
56
|
* accepted by the OpenAI Responses `reasoning.effort` field. Responses today
|
|
57
|
-
* accepts 'low'|'medium'|'high' — 'max' degrades to 'high' to match the
|
|
57
|
+
* accepts 'minimal'|'low'|'medium'|'high' — 'max' degrades to 'high' to match the
|
|
58
58
|
* registry's normaliseEffort downgrade rule.
|
|
59
59
|
*/
|
|
60
60
|
function effortForResponses(effort) {
|
package/yeaft/llm/router.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { LLMAdapter } from './adapter.js';
|
|
25
|
-
import { getThinkingCapability, normalizeEffort, parseModelRef } from '../models.js';
|
|
25
|
+
import { getModelEffortOptions, getThinkingCapability, normalizeEffort, parseModelRef } from '../models.js';
|
|
26
26
|
import { normalizeKnownProviderForRuntime } from './known-providers.js';
|
|
27
27
|
import { pairSanitize } from '../pair-sanitize.js';
|
|
28
28
|
|
|
@@ -109,11 +109,16 @@ export function filterEffortForModel(params) {
|
|
|
109
109
|
const { effort: _drop, effortSource: _source, ...rest } = params;
|
|
110
110
|
return rest;
|
|
111
111
|
}
|
|
112
|
-
const
|
|
112
|
+
const modelId = parseModelRef(params.model).modelId;
|
|
113
|
+
const cap = getThinkingCapability(modelId);
|
|
113
114
|
if (!cap.supportsThinking || cap.thinkingProtocol === 'none') {
|
|
114
115
|
const { effort: _drop, effortSource: _source, ...rest } = params;
|
|
115
116
|
return rest;
|
|
116
117
|
}
|
|
118
|
+
if (norm === 'minimal' && !getModelEffortOptions(modelId).includes('minimal')) {
|
|
119
|
+
const { effort: _drop, effortSource: _source, ...rest } = params;
|
|
120
|
+
return rest;
|
|
121
|
+
}
|
|
117
122
|
return { ...params, effort: norm, effortSource: params.effortSource };
|
|
118
123
|
}
|
|
119
124
|
|
package/yeaft/models.js
CHANGED
|
@@ -131,6 +131,18 @@ export const MODEL_REGISTRY = new Map([
|
|
|
131
131
|
adapter: 'openai-responses',
|
|
132
132
|
baseUrl: 'https://api.openai.com/v1',
|
|
133
133
|
displayName: 'GPT-5.4',
|
|
134
|
+
supportsThinking: true,
|
|
135
|
+
thinkingProtocol: 'openai-reasoning',
|
|
136
|
+
defaultEffort: null,
|
|
137
|
+
}],
|
|
138
|
+
['gpt-5.5', {
|
|
139
|
+
provider: 'openai',
|
|
140
|
+
adapter: 'openai-responses',
|
|
141
|
+
baseUrl: 'https://api.openai.com/v1',
|
|
142
|
+
displayName: 'GPT-5.5',
|
|
143
|
+
supportsThinking: true,
|
|
144
|
+
thinkingProtocol: 'openai-reasoning',
|
|
145
|
+
defaultEffort: null,
|
|
134
146
|
}],
|
|
135
147
|
['gpt-4.1', {
|
|
136
148
|
provider: 'openai',
|
|
@@ -371,7 +383,7 @@ export function parseModelRef(ref) {
|
|
|
371
383
|
|
|
372
384
|
/**
|
|
373
385
|
* Valid effort levels accepted by Yeaft adapters.
|
|
374
|
-
* @typedef {'low' | 'medium' | 'high' | 'max'} Effort
|
|
386
|
+
* @typedef {'minimal' | 'low' | 'medium' | 'high' | 'max'} Effort
|
|
375
387
|
*/
|
|
376
388
|
|
|
377
389
|
/**
|
|
@@ -396,11 +408,12 @@ export const ANTHROPIC_THINKING_BUDGETS = {
|
|
|
396
408
|
* but the adapter MUST NOT error.
|
|
397
409
|
*
|
|
398
410
|
* @param {Effort} effort
|
|
399
|
-
* @returns {'low' | 'medium' | 'high' | null}
|
|
411
|
+
* @returns {'minimal' | 'low' | 'medium' | 'high' | null}
|
|
400
412
|
*/
|
|
401
413
|
export function mapEffortToOpenAIReasoning(effort) {
|
|
402
414
|
if (!effort) return null;
|
|
403
415
|
switch (effort) {
|
|
416
|
+
case 'minimal': return 'minimal';
|
|
404
417
|
case 'low': return 'low';
|
|
405
418
|
case 'medium': return 'medium';
|
|
406
419
|
case 'high': return 'high';
|
|
@@ -411,7 +424,8 @@ export function mapEffortToOpenAIReasoning(effort) {
|
|
|
411
424
|
}
|
|
412
425
|
}
|
|
413
426
|
|
|
414
|
-
export const
|
|
427
|
+
export const OPENAI_REASONING_EFFORT_OPTIONS = ['minimal', 'low', 'medium', 'high'];
|
|
428
|
+
export const ANTHROPIC_EFFORT_OPTIONS = ['low', 'medium', 'high'];
|
|
415
429
|
|
|
416
430
|
function inferThinkingCapability(model) {
|
|
417
431
|
const id = parseModelRef(model).modelId.toLowerCase();
|
|
@@ -485,7 +499,9 @@ export function getThinkingCapability(model) {
|
|
|
485
499
|
export function getModelEffortOptions(model) {
|
|
486
500
|
const cap = getThinkingCapability(model);
|
|
487
501
|
if (!cap.supportsThinking || cap.thinkingProtocol === 'none') return [];
|
|
488
|
-
return
|
|
502
|
+
if (cap.thinkingProtocol === 'openai-reasoning') return OPENAI_REASONING_EFFORT_OPTIONS.slice();
|
|
503
|
+
if (cap.thinkingProtocol === 'anthropic') return ANTHROPIC_EFFORT_OPTIONS.slice();
|
|
504
|
+
return [];
|
|
489
505
|
}
|
|
490
506
|
|
|
491
507
|
export function modelSupportsEffort(model) {
|
|
@@ -499,7 +515,7 @@ export function modelSupportsEffort(model) {
|
|
|
499
515
|
* @returns {Effort | null}
|
|
500
516
|
*/
|
|
501
517
|
export function normalizeEffort(effort) {
|
|
502
|
-
if (effort === 'low' || effort === 'medium' || effort === 'high' || effort === 'max') {
|
|
518
|
+
if (effort === 'minimal' || effort === 'low' || effort === 'medium' || effort === 'high' || effort === 'max') {
|
|
503
519
|
return effort;
|
|
504
520
|
}
|
|
505
521
|
return null;
|
|
@@ -28,7 +28,7 @@ const CONFIG_FILE = 'config.json';
|
|
|
28
28
|
|
|
29
29
|
/** Whitelist of persisted session model-override fields. Reject everything else. */
|
|
30
30
|
const ALLOWED_KEYS = new Set(['model', 'modelEffort']);
|
|
31
|
-
const ALLOWED_EFFORTS = new Set(['low', 'medium', 'high']);
|
|
31
|
+
const ALLOWED_EFFORTS = new Set(['minimal', 'low', 'medium', 'high']);
|
|
32
32
|
|
|
33
33
|
export class SessionConfigError extends Error {
|
|
34
34
|
constructor(code, message) {
|
|
@@ -101,7 +101,7 @@ export function validateSessionConfig(cfg) {
|
|
|
101
101
|
}
|
|
102
102
|
if ('modelEffort' in cfg && cfg.modelEffort !== null && cfg.modelEffort !== undefined && cfg.modelEffort !== '') {
|
|
103
103
|
if (typeof cfg.modelEffort !== 'string' || !ALLOWED_EFFORTS.has(cfg.modelEffort.trim())) {
|
|
104
|
-
throw new SessionConfigError('invalid_model_effort', 'modelEffort must be low, medium, or high');
|
|
104
|
+
throw new SessionConfigError('invalid_model_effort', 'modelEffort must be minimal, low, medium, or high');
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
}
|
package/yeaft/web-bridge.js
CHANGED
|
@@ -3983,6 +3983,11 @@ export function handleYeaftModelSwitch(msg) {
|
|
|
3983
3983
|
session.config.model = msg.model;
|
|
3984
3984
|
session.config.primaryModel = msg.model;
|
|
3985
3985
|
session.config.modelEffort = msg.modelEffort || null;
|
|
3986
|
+
// Legacy non-session model switches mutate the shared root config instead
|
|
3987
|
+
// of going through handleYeaftUpdateSessionConfig(), so cached per-VP
|
|
3988
|
+
// Engines would otherwise keep the old effective config and drop newly
|
|
3989
|
+
// selected effort values until process restart.
|
|
3990
|
+
vpEngines.clear();
|
|
3986
3991
|
|
|
3987
3992
|
sendSessionEvent({
|
|
3988
3993
|
type: 'model_switched',
|