@yeaft/webchat-agent 0.1.926 → 0.1.928
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/yeaft/llm/router.js +16 -2
- package/yeaft/tools/agent.js +8 -7
- package/yeaft/tools/wait-agent.js +10 -2
- package/yeaft/web-bridge.js +29 -1
package/package.json
CHANGED
package/yeaft/llm/router.js
CHANGED
|
@@ -193,7 +193,21 @@ export class AdapterRouter extends LLMAdapter {
|
|
|
193
193
|
*/
|
|
194
194
|
constructor({ providers }) {
|
|
195
195
|
super();
|
|
196
|
-
this.#providers =
|
|
196
|
+
this.#providers = [];
|
|
197
|
+
this.#modelToProvider = new Map();
|
|
198
|
+
this.#adapterCache = new Map();
|
|
199
|
+
this.refreshProviders(providers);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Replace the provider/model index after config.json changes. Existing
|
|
204
|
+
* provider adapters are dropped because credentials, baseUrl, protocol,
|
|
205
|
+
* or model ownership may have changed along with the list.
|
|
206
|
+
*
|
|
207
|
+
* @param {object[]} providers
|
|
208
|
+
*/
|
|
209
|
+
refreshProviders(providers) {
|
|
210
|
+
this.#providers = Array.isArray(providers) ? providers : [];
|
|
197
211
|
this.#modelToProvider = new Map();
|
|
198
212
|
this.#adapterCache = new Map();
|
|
199
213
|
|
|
@@ -201,7 +215,7 @@ export class AdapterRouter extends LLMAdapter {
|
|
|
201
215
|
// model id appears in multiple providers. Each model entry may declare
|
|
202
216
|
// its own `protocol`; we keep the normalized entry so #effectiveProtocol
|
|
203
217
|
// can consult it later without re-parsing.
|
|
204
|
-
for (const provider of providers) {
|
|
218
|
+
for (const provider of this.#providers) {
|
|
205
219
|
if (!Array.isArray(provider.models)) continue;
|
|
206
220
|
for (const raw of provider.models) {
|
|
207
221
|
const entry = normalizeModelEntry(raw);
|
package/yeaft/tools/agent.js
CHANGED
|
@@ -179,7 +179,8 @@ export default defineTool({
|
|
|
179
179
|
description: `Create a sub-agent to work on an independent task in parallel.
|
|
180
180
|
|
|
181
181
|
Sub-agents run in their own context and can be given a concrete mission
|
|
182
|
-
with an expected_output schema
|
|
182
|
+
with an optional expected_output schema. Optional budget limits
|
|
183
|
+
(max_tokens/max_turns/wall_time_ms) act as safety cutoffs only when supplied.
|
|
183
184
|
Pick a preset persona to pre-wire a tool subset and model tier:
|
|
184
185
|
- explorer : fast, read-only scout (Read/Grep/Glob/ListDir)
|
|
185
186
|
- implementer: builder with full work tools (primary model)
|
|
@@ -188,8 +189,8 @@ Pick a preset persona to pre-wire a tool subset and model tier:
|
|
|
188
189
|
|
|
189
190
|
Guidelines:
|
|
190
191
|
- Give a clear, focused mission — what "done" looks like
|
|
191
|
-
- Use expected_output
|
|
192
|
-
-
|
|
192
|
+
- Use expected_output when the return shape matters
|
|
193
|
+
- Add a budget only when you need an explicit safety cutoff
|
|
193
194
|
- Use PromptAgent to communicate, WaitAgent to collect results, CloseAgent to finalize`,
|
|
194
195
|
parameters: {
|
|
195
196
|
type: 'object',
|
|
@@ -218,11 +219,11 @@ Guidelines:
|
|
|
218
219
|
budget: {
|
|
219
220
|
type: 'object',
|
|
220
221
|
properties: {
|
|
221
|
-
max_tokens: { type: 'number' },
|
|
222
|
-
max_turns: { type: 'number' },
|
|
223
|
-
wall_time_ms: { type: 'number' },
|
|
222
|
+
max_tokens: { type: 'number', description: 'Optional token ceiling; no default limit is applied' },
|
|
223
|
+
max_turns: { type: 'number', description: 'Optional turn ceiling; no default limit is applied' },
|
|
224
|
+
wall_time_ms: { type: 'number', description: 'Optional elapsed-time ceiling in milliseconds; no default limit is applied' },
|
|
224
225
|
},
|
|
225
|
-
description: '
|
|
226
|
+
description: 'Optional safety limits; no max_tokens/max_turns/wall_time_ms defaults are applied. Exceeding an explicit limit returns { status: "budget_exceeded", partial_output, reason }',
|
|
226
227
|
},
|
|
227
228
|
cwd: {
|
|
228
229
|
type: 'string',
|
|
@@ -10,7 +10,9 @@ export default defineTool({
|
|
|
10
10
|
description: `Wait for a sub-agent to complete its task and retrieve the result.
|
|
11
11
|
|
|
12
12
|
Returns the agent's final result or current status if still running.
|
|
13
|
-
Use after sending a task to an agent via PromptAgent
|
|
13
|
+
Use after sending a task to an agent via PromptAgent.
|
|
14
|
+
|
|
15
|
+
The default wait is 30000ms. Callers may request up to 300000ms (5 minutes).`,
|
|
14
16
|
parameters: {
|
|
15
17
|
type: 'object',
|
|
16
18
|
properties: {
|
|
@@ -20,16 +22,22 @@ Use after sending a task to an agent via PromptAgent.`,
|
|
|
20
22
|
},
|
|
21
23
|
timeout_ms: {
|
|
22
24
|
type: 'number',
|
|
23
|
-
|
|
25
|
+
minimum: 0,
|
|
26
|
+
maximum: 300000,
|
|
27
|
+
description: 'Maximum time to wait in milliseconds (default: 30000, max: 300000 / 5 minutes)',
|
|
24
28
|
},
|
|
25
29
|
},
|
|
26
30
|
required: ['agent_id'],
|
|
27
31
|
},
|
|
32
|
+
timeoutMs: 305000,
|
|
28
33
|
isConcurrencySafe: () => true,
|
|
29
34
|
isReadOnly: () => true,
|
|
30
35
|
async execute(input, ctx) {
|
|
31
36
|
const { agent_id, timeout_ms = 30000 } = input;
|
|
32
37
|
if (!agent_id) return JSON.stringify({ error: 'agent_id is required' });
|
|
38
|
+
if (typeof timeout_ms !== 'number' || !Number.isFinite(timeout_ms) || timeout_ms < 0 || timeout_ms > 300000) {
|
|
39
|
+
return JSON.stringify({ error: 'timeout_ms must be a number between 0 and 300000' });
|
|
40
|
+
}
|
|
33
41
|
|
|
34
42
|
const agents = getAgentRegistry();
|
|
35
43
|
const agent = agents.get(agent_id);
|
package/yeaft/web-bridge.js
CHANGED
|
@@ -23,6 +23,7 @@ import { existsSync } from 'node:fs';
|
|
|
23
23
|
import { randomUUID } from 'node:crypto';
|
|
24
24
|
import { Engine } from './engine.js';
|
|
25
25
|
import { loadSession } from './session.js';
|
|
26
|
+
import { loadConfig } from './config.js';
|
|
26
27
|
import { sendToServer } from '../connection/buffer.js';
|
|
27
28
|
import ctx from '../context.js';
|
|
28
29
|
import { hydrateYeaftStatusFromSession } from './status-cache.js';
|
|
@@ -69,6 +70,26 @@ let session = null;
|
|
|
69
70
|
|
|
70
71
|
let threadClassifier = defaultClassifyThread;
|
|
71
72
|
|
|
73
|
+
function refreshLiveSessionConfig() {
|
|
74
|
+
if (!session) return;
|
|
75
|
+
try {
|
|
76
|
+
const freshConfig = loadConfig({ dir: session.yeaftDir || ctx.CONFIG?.yeaftDir });
|
|
77
|
+
const freshModels = Array.isArray(freshConfig.availableModels) ? freshConfig.availableModels : [];
|
|
78
|
+
session.config.availableModels = freshModels;
|
|
79
|
+
if (freshConfig.model && !freshModels.some(m => m?.id === session.config.model)) {
|
|
80
|
+
session.config.model = freshConfig.model;
|
|
81
|
+
}
|
|
82
|
+
if (freshConfig.providers) {
|
|
83
|
+
session.config.providers = freshConfig.providers;
|
|
84
|
+
if (typeof session.adapter?.refreshProviders === 'function') {
|
|
85
|
+
session.adapter.refreshProviders(freshConfig.providers);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
console.warn('[Yeaft] refresh live session config failed:', err?.message || err);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
72
93
|
/** Test-only: replace the lightweight VP thread classifier. */
|
|
73
94
|
export function __testSetThreadClassifier(fn) {
|
|
74
95
|
threadClassifier = typeof fn === 'function' ? fn : defaultClassifyThread;
|
|
@@ -3728,6 +3749,7 @@ export function handleYeaftModeSwitch(_msg) {
|
|
|
3728
3749
|
/** Handle model switch from the web UI. */
|
|
3729
3750
|
export function handleYeaftModelSwitch(msg) {
|
|
3730
3751
|
if (!session || !msg.model) return;
|
|
3752
|
+
refreshLiveSessionConfig();
|
|
3731
3753
|
|
|
3732
3754
|
const available = session.config.availableModels || [];
|
|
3733
3755
|
const found = available.some(m => m.id === msg.model);
|
|
@@ -3774,6 +3796,7 @@ export async function handleYeaftLoadHistory(msg) {
|
|
|
3774
3796
|
installYeaftRuntimeBridge(session);
|
|
3775
3797
|
|
|
3776
3798
|
yeaftConversationId = `yeaft-${Date.now()}`;
|
|
3799
|
+
refreshLiveSessionConfig();
|
|
3777
3800
|
hydrateYeaftStatusFromSession(session, { reason: 'history_load', emitEvent: true });
|
|
3778
3801
|
|
|
3779
3802
|
// Per-group history hydrates lazily via getOrCreateSessionHistory.
|
|
@@ -3782,7 +3805,12 @@ export async function handleYeaftLoadHistory(msg) {
|
|
|
3782
3805
|
// it doesn't (legacy callers), do nothing — the per-group lazy
|
|
3783
3806
|
// hydration handles it.
|
|
3784
3807
|
if (sessionId) setGroupHistory(sessionId, hydrateGroupHistory(sessionId));
|
|
3785
|
-
} else
|
|
3808
|
+
} else {
|
|
3809
|
+
refreshLiveSessionConfig();
|
|
3810
|
+
hydrateYeaftStatusFromSession(session, { reason: 'history_load', emitEvent: true });
|
|
3811
|
+
}
|
|
3812
|
+
|
|
3813
|
+
if (sessionId) {
|
|
3786
3814
|
// Re-entering an existing session with a (possibly new) group filter:
|
|
3787
3815
|
// re-seed THIS group's history from disk so it doesn't carry stale
|
|
3788
3816
|
// in-memory state into the next turn's context.
|