@yeaft/webchat-agent 1.0.585 → 1.0.586

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.
Binary file
@@ -17,6 +17,6 @@
17
17
  </head>
18
18
  <body>
19
19
  <div id="app"></div>
20
- <script type="module" src="app.bundle.js?v=cbecebbd"></script>
20
+ <script type="module" src="app.bundle.js?v=8e6f87a6"></script>
21
21
  </body>
22
22
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "1.0.585",
3
+ "version": "1.0.586",
4
4
  "description": "Remote worker agent for Yeaft Web Code Agent — connects the native Yeaft engine, CLI providers, and workbench tools",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -41,7 +41,8 @@ function thinkingV1Enabled() {
41
41
  return process.env.YEAFT_THINKING_V1 === '1';
42
42
  }
43
43
 
44
- function applyAnthropicThinking(body, model, effort, effortContext = {}) {
44
+ /** Apply the native payload rules; bounded callers also use this for budget preflight. */
45
+ export function applyAnthropicThinking(body, model, effort, effortContext = {}) {
45
46
  const cap = getThinkingCapability(model, effortContext);
46
47
  if (!cap.supportsThinking) return;
47
48
  if (!getModelEffortOptions(model, effortContext).includes(effort)) return;
@@ -1,6 +1,7 @@
1
1
  import { loadConfig } from '../config.js';
2
2
  import { createLLMAdapter } from '../llm/adapter.js';
3
- import { resolveContextWindow, resolveMaxOutputTokens } from '../models.js';
3
+ import { applyAnthropicThinking } from '../llm/anthropic.js';
4
+ import { normalizeEffort, resolveContextWindow, resolveMaxOutputTokens } from '../models.js';
4
5
  import { utf8PrefixWithinBytes } from '../utf8.js';
5
6
  import { bytes, digest, fail, LIMITS, PersonError } from './contracts.js';
6
7
 
@@ -8,14 +9,31 @@ import { bytes, digest, fail, LIMITS, PersonError } from './contracts.js';
8
9
  export async function createPersonProvider({ yeaftDir, config: suppliedConfig, adapter: suppliedAdapter, allowedModels, effortEnabled = process.env.YEAFT_THINKING_V1 === '1' }) {
9
10
  const config = suppliedConfig || loadConfig({ dir: yeaftDir });
10
11
  if (!config.providers?.length && !suppliedAdapter) fail('MODEL_UNAVAILABLE');
11
- const available = (config.availableModels || []).filter(m => !allowedModels || allowedModels.includes(m.ref || m.id));
12
- const defaultRef = config.primaryModel || config.model;
13
- available.sort((a, b) => Number((b.ref || b.id) === defaultRef) - Number((a.ref || a.id) === defaultRef));
14
- const catalog = available.slice(0, 8).map(m => ({
15
- id: m.ref || m.id, efforts: effortEnabled ? (m.effortOptions || []).filter(e => ['minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'].includes(e)) : [],
16
- contextWindow: Math.floor(resolveContextWindow(m.id, { ...config, modelInfo: m })),
17
- maxOutput: Math.min(4096, Math.floor(resolveMaxOutputTokens(m.id, { ...config, modelInfo: m }))),
18
- })).filter(m => typeof m.id === 'string' && m.id.length <= 256 && m.contextWindow > m.maxOutput + 1024 && m.maxOutput >= 256);
12
+ const models = config.availableModels || [];
13
+ const requestedDefault = config.primaryModel || config.model;
14
+ // Match router ownership: exact qualified ref first; bare IDs use the first
15
+ // configured provider. Resolve before allowlisting, sorting or truncating.
16
+ const defaultModel = models.find(m => (m.ref || m.id) === requestedDefault)
17
+ || models.find(m => m.id === requestedDefault);
18
+ const defaultRef = defaultModel?.ref || defaultModel?.id;
19
+ const available = models.filter(m => !allowedModels || allowedModels.includes(m.ref || m.id));
20
+ const catalog = available.map(m => {
21
+ const maxOutput = Math.min(4096, Math.floor(resolveMaxOutputTokens(m.id, { ...config, modelInfo: m })));
22
+ const effortContext = { ...m, thinkingProtocol: m.effortProtocol || m.thinkingProtocol };
23
+ const efforts = effortEnabled ? (m.effortOptions || []).filter(e => {
24
+ if (!normalizeEffort(e)) return false;
25
+ // Manual thinking can silently expand native max_tokens. Use the exact
26
+ // adapter rules to admit only combinations that fit this fixed reserve;
27
+ // adaptive and Responses effort do not require a larger output budget.
28
+ const body = { max_tokens: maxOutput };
29
+ applyAnthropicThinking(body, m.id, e, effortContext);
30
+ return body.max_tokens === maxOutput;
31
+ }) : [];
32
+ return { id: m.ref || m.id, efforts, maxOutput,
33
+ contextWindow: Math.floor(resolveContextWindow(m.id, { ...config, modelInfo: m })) };
34
+ }).filter(m => typeof m.id === 'string' && m.id.length <= 256 && m.contextWindow > m.maxOutput + 1024 && m.maxOutput >= 256);
35
+ catalog.sort((a, b) => Number(b.id === defaultRef) - Number(a.id === defaultRef));
36
+ catalog.splice(8);
19
37
  if (!catalog.length) fail('MODEL_UNAVAILABLE');
20
38
  const adapter = suppliedAdapter || await createLLMAdapter(config);
21
39
  return { adapter, catalog, catalogRevision: digest(catalog), defaultSelection: { model: catalog[0].id, effort: null }, effortEnabled };