@yeaft/webchat-agent 0.1.508 → 0.1.509
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/unify/engine.js
CHANGED
|
@@ -26,6 +26,7 @@ import { buildMemoryInjection } from './memory/layout.js';
|
|
|
26
26
|
import { runStopHooks } from './stop-hooks.js';
|
|
27
27
|
import { getThreadStore, MAIN_THREAD_ID } from './threads/store.js';
|
|
28
28
|
import { pickEffort, parseEffortPrefix } from './effort.js';
|
|
29
|
+
import { normalizeEffort } from './models.js';
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* task-324 — Turn cap removed.
|
|
@@ -446,9 +447,12 @@ export class Engine {
|
|
|
446
447
|
|
|
447
448
|
// task-327b: `/max` / `/high` / `/medium` / `/low` prefix override.
|
|
448
449
|
// Explicit caller-supplied userEffort wins over the prefix.
|
|
450
|
+
// task-327c nit: defensively normalize caller-supplied userEffort BEFORE
|
|
451
|
+
// the merge, so an invalid caller value (e.g. 'ULTRA') does not shadow a
|
|
452
|
+
// valid prompt prefix.
|
|
449
453
|
const parsed = parseEffortPrefix(prompt);
|
|
450
454
|
const effectivePrompt = parsed.cleanedPrompt;
|
|
451
|
-
const effectiveUserEffort = userEffort || parsed.effort || null;
|
|
455
|
+
const effectiveUserEffort = normalizeEffort(userEffort) || parsed.effort || null;
|
|
452
456
|
|
|
453
457
|
// ─── task-325a: engine-owned AbortController ─────────────
|
|
454
458
|
// We create our own controller for this query run so `engine.abort()`
|
package/unify/llm/anthropic.js
CHANGED
|
@@ -297,8 +297,13 @@ export class AnthropicAdapter extends LLMAdapter {
|
|
|
297
297
|
|
|
298
298
|
/**
|
|
299
299
|
* Non-streaming call for side queries.
|
|
300
|
+
*
|
|
301
|
+
* task-327c: accepts `effort` for internal scenario-tagged calls
|
|
302
|
+
* (consolidate/dream/recall/light). Guards mirror stream() — unsupported
|
|
303
|
+
* models silently drop the param. max_tokens auto-widens to budget+1024
|
|
304
|
+
* when needed.
|
|
300
305
|
*/
|
|
301
|
-
async call({ model, system, messages, maxTokens = 4096, signal }) {
|
|
306
|
+
async call({ model, system, messages, maxTokens = 4096, effort, signal }) {
|
|
302
307
|
if (signal?.aborted) throw new LLMAbortError();
|
|
303
308
|
|
|
304
309
|
const body = {
|
|
@@ -308,6 +313,20 @@ export class AnthropicAdapter extends LLMAdapter {
|
|
|
308
313
|
messages: this.#translateMessages(messages),
|
|
309
314
|
};
|
|
310
315
|
|
|
316
|
+
// task-327c: mirror stream()'s thinking injection for side queries.
|
|
317
|
+
const normEffort = normalizeEffort(effort);
|
|
318
|
+
if (thinkingV1Enabled() && normEffort) {
|
|
319
|
+
const cap = getThinkingCapability(model);
|
|
320
|
+
if (cap.supportsThinking && cap.thinkingProtocol === 'anthropic') {
|
|
321
|
+
const budget = thinkingBudgetForEffort(model, normEffort);
|
|
322
|
+
if (budget && budget > 0) {
|
|
323
|
+
const minMax = budget + 1024;
|
|
324
|
+
if (body.max_tokens < minMax) body.max_tokens = minMax;
|
|
325
|
+
body.thinking = { type: 'enabled', budget_tokens: budget };
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
311
330
|
const response = await fetch(`${this.#baseUrl}/v1/messages`, {
|
|
312
331
|
method: 'POST',
|
|
313
332
|
headers: {
|
|
@@ -350,8 +350,12 @@ export class ChatCompletionsAdapter extends LLMAdapter {
|
|
|
350
350
|
|
|
351
351
|
/**
|
|
352
352
|
* Non-streaming call for side queries.
|
|
353
|
+
*
|
|
354
|
+
* task-327c: accepts `effort` for internal scenario-tagged calls
|
|
355
|
+
* (consolidate/dream/recall/light). Feature-flag + capability guards
|
|
356
|
+
* mirror stream() exactly; unsupported models silently drop the param.
|
|
353
357
|
*/
|
|
354
|
-
async call({ model, system, messages, maxTokens = 4096, extraBody, signal }) {
|
|
358
|
+
async call({ model, system, messages, maxTokens = 4096, effort, extraBody, signal }) {
|
|
355
359
|
if (signal?.aborted) throw new LLMAbortError();
|
|
356
360
|
|
|
357
361
|
const body = {
|
|
@@ -360,6 +364,18 @@ export class ChatCompletionsAdapter extends LLMAdapter {
|
|
|
360
364
|
...this.#maxTokensBody(model, maxTokens),
|
|
361
365
|
};
|
|
362
366
|
|
|
367
|
+
// task-327c: mirror stream()'s reasoning.effort injection for side queries.
|
|
368
|
+
const normEffort = normalizeEffort(effort);
|
|
369
|
+
if (thinkingV1Enabled() && normEffort) {
|
|
370
|
+
const cap = getThinkingCapability(model);
|
|
371
|
+
if (cap.supportsThinking && cap.thinkingProtocol === 'openai-reasoning') {
|
|
372
|
+
const reasoningEffort = mapEffortToOpenAIReasoning(normEffort);
|
|
373
|
+
if (reasoningEffort) {
|
|
374
|
+
body.reasoning = { effort: reasoningEffort };
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
363
379
|
// extraBody allows callers to pass through any additional/override parameters
|
|
364
380
|
if (extraBody) Object.assign(body, extraBody);
|
|
365
381
|
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { extractMemories } from './extract.js';
|
|
18
|
+
import { pickEffort } from '../effort.js';
|
|
18
19
|
|
|
19
20
|
// ─── Constants ──────────────────────────────────────────────────
|
|
20
21
|
|
|
@@ -103,6 +104,11 @@ async function generateSummary(messages, adapter, config) {
|
|
|
103
104
|
system,
|
|
104
105
|
messages: [{ role: 'user', content: `Summarize this conversation:\n\n${conversation}` }],
|
|
105
106
|
maxTokens: 1024,
|
|
107
|
+
// task-327c: consolidate is a high-complexity side-query; flag as
|
|
108
|
+
// 'max' effort so supported models use extended thinking / reasoning.
|
|
109
|
+
// Router/adapter silently drops the param for models that don't
|
|
110
|
+
// support thinking, or when UNIFY_THINKING_V1 is off.
|
|
111
|
+
effort: pickEffort({ scenario: 'consolidate' }),
|
|
106
112
|
});
|
|
107
113
|
return result.text.trim();
|
|
108
114
|
} catch {
|
package/unify/memory/dream.js
CHANGED
|
@@ -16,6 +16,7 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, unlink
|
|
|
16
16
|
import { join } from 'path';
|
|
17
17
|
import { scanEntries, findStaleEntries, findDuplicateGroups, summarizeScan } from './scan.js';
|
|
18
18
|
import { MAX_ENTRIES } from './store.js';
|
|
19
|
+
import { pickEffort } from '../effort.js';
|
|
19
20
|
import {
|
|
20
21
|
ensureLayout,
|
|
21
22
|
renderIndex,
|
|
@@ -399,6 +400,9 @@ async function llmCall(adapter, config, system, prompt) {
|
|
|
399
400
|
system,
|
|
400
401
|
messages: [{ role: 'user', content: prompt }],
|
|
401
402
|
maxTokens: 4096,
|
|
403
|
+
// task-327c: dream is self-reflective memory maintenance — flag 'max'
|
|
404
|
+
// so supported models use the full thinking budget.
|
|
405
|
+
effort: pickEffort({ scenario: 'dream' }),
|
|
402
406
|
});
|
|
403
407
|
|
|
404
408
|
const text = result.text.trim();
|
|
@@ -761,6 +765,9 @@ Write the narrative as Markdown with:
|
|
|
761
765
|
system,
|
|
762
766
|
messages: [{ role: 'user', content: prompt }],
|
|
763
767
|
maxTokens: 2048,
|
|
768
|
+
// task-327c: dream narrative synthesis — same 'max' tier as the
|
|
769
|
+
// dream phase above; both pass through dream's self-reflection loop.
|
|
770
|
+
effort: pickEffort({ scenario: 'dream' }),
|
|
764
771
|
});
|
|
765
772
|
const text = (result?.text || '').trim();
|
|
766
773
|
if (!text) return null;
|
package/unify/memory/extract.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { MEMORY_KINDS } from './store.js';
|
|
12
|
+
import { pickEffort } from '../effort.js';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Build the extraction prompt.
|
|
@@ -69,6 +70,9 @@ export async function extractMemories({ messages, adapter, config }) {
|
|
|
69
70
|
system,
|
|
70
71
|
messages: [{ role: 'user', content: extractionPrompt }],
|
|
71
72
|
maxTokens: 2048,
|
|
73
|
+
// task-327c: extract runs inside the consolidate pipeline — the
|
|
74
|
+
// JSON-structured output benefits from the same 'max' thinking tier.
|
|
75
|
+
effort: pickEffort({ scenario: 'consolidate' }),
|
|
72
76
|
});
|
|
73
77
|
|
|
74
78
|
const text = result.text.trim();
|
package/unify/memory/recall.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { createHash } from 'crypto';
|
|
17
|
+
import { pickEffort } from '../effort.js';
|
|
17
18
|
|
|
18
19
|
// ─── Constants ──────────────────────────────────────────────────
|
|
19
20
|
|
|
@@ -148,6 +149,9 @@ Select the ${MAX_RECALL_RESULTS} most relevant entries. Return a JSON array of e
|
|
|
148
149
|
system,
|
|
149
150
|
messages,
|
|
150
151
|
maxTokens: 512,
|
|
152
|
+
// task-327c: recall step-3 is a cheap classifier pass (pick N out of
|
|
153
|
+
// 15 candidates). Flag 'low' so supported models skip deep reasoning.
|
|
154
|
+
effort: pickEffort({ scenario: 'recall' }),
|
|
151
155
|
});
|
|
152
156
|
|
|
153
157
|
// Parse the JSON array from the response
|