@yeaft/webchat-agent 1.0.351 → 1.0.352
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/connection/message-router.js +29 -1
- package/index.js +2 -0
- package/local-runtime/server/handlers/agent-sync.js +14 -0
- package/local-runtime/server/handlers/client-misc.js +21 -0
- package/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +52 -33
- package/local-runtime/web/app.bundle.js.gz +0 -0
- package/local-runtime/web/index.html +2 -2
- package/local-runtime/web/style.bundle.css +1 -1
- package/local-runtime/web/style.bundle.css.gz +0 -0
- package/package.json +1 -1
- package/yeaft/config-api.js +53 -1
- package/yeaft/config.js +54 -0
- package/yeaft/conversation/history-index-worker.js +13 -10
- package/yeaft/conversation/internal-control.js +1 -0
- package/yeaft/debug-trace.js +164 -47
- package/yeaft/engine.js +318 -28
- package/yeaft/llm/adapter.js +38 -0
- package/yeaft/llm/anthropic.js +11 -8
- package/yeaft/llm/openai-responses.js +11 -8
- package/yeaft/llm/router.js +1 -1
- package/yeaft/perf-trace.js +156 -24
- package/yeaft/session.js +7 -0
- package/yeaft/sessions/session-crud.js +19 -4
- package/yeaft/sub-agent/runner.js +4 -0
- package/yeaft/tools/agent.js +4 -0
- package/yeaft/tools/ask-user.js +1 -0
- package/yeaft/tools/bash.js +4 -0
- package/yeaft/tools/create-work-item.js +3 -0
- package/yeaft/tools/file-read.js +1 -0
- package/yeaft/tools/glob.js +1 -0
- package/yeaft/tools/grep.js +1 -0
- package/yeaft/tools/history-search.js +74 -20
- package/yeaft/tools/js-repl.js +1 -0
- package/yeaft/tools/list-agents.js +1 -0
- package/yeaft/tools/list-dir.js +1 -0
- package/yeaft/tools/list-tasks.js +1 -0
- package/yeaft/tools/read-task-log.js +1 -0
- package/yeaft/tools/route-forward.js +4 -0
- package/yeaft/tools/send-message.js +3 -0
- package/yeaft/tools/types.js +8 -0
- package/yeaft/tools/wait-agent.js +1 -0
- package/yeaft/utf8.js +44 -0
- package/yeaft/web-bridge.js +6 -0
- package/yeaft/work-center/runner.js +1 -0
|
@@ -21,6 +21,7 @@ export default defineTool({
|
|
|
21
21
|
},
|
|
22
22
|
isConcurrencySafe: () => true,
|
|
23
23
|
isReadOnly: () => true,
|
|
24
|
+
cacheWithinQuery: false,
|
|
24
25
|
async execute(input = {}, ctx = {}) {
|
|
25
26
|
if (!ctx.taskManager) return JSON.stringify({ error: 'task manager unavailable' });
|
|
26
27
|
const sessionId = input.sessionId || ctx.sessionId || null;
|
|
@@ -23,6 +23,7 @@ export default defineTool({
|
|
|
23
23
|
},
|
|
24
24
|
isConcurrencySafe: () => true,
|
|
25
25
|
isReadOnly: () => true,
|
|
26
|
+
cacheWithinQuery: false,
|
|
26
27
|
async execute(input = {}, ctx = {}) {
|
|
27
28
|
if (!ctx.taskManager) return JSON.stringify({ error: 'task manager unavailable' });
|
|
28
29
|
const taskId = input.taskId;
|
|
@@ -104,6 +104,10 @@ Returns JSON: { ok, dispatched?, error?, detail? }.`,
|
|
|
104
104
|
},
|
|
105
105
|
isConcurrencySafe: () => false,
|
|
106
106
|
isReadOnly: () => false,
|
|
107
|
+
// A handoff can start another VP on the shared workDir while this query
|
|
108
|
+
// still has queued tool calls. Conservatively disable reuse even when the
|
|
109
|
+
// dispatch is rejected; the cost is one fresh read, not stale workspace data.
|
|
110
|
+
mayMutateWorkspaceAfterReturn: () => true,
|
|
107
111
|
async execute(input, ctx = {}) {
|
|
108
112
|
const { to, text, reason } = input || {};
|
|
109
113
|
if (!to || typeof to !== 'string') {
|
|
@@ -62,6 +62,9 @@ SpawnAgent -> (PromptAgent <-> WaitAgent)+ -> CloseAgent -> 最终回复给用
|
|
|
62
62
|
},
|
|
63
63
|
isConcurrencySafe: () => false,
|
|
64
64
|
isReadOnly: () => false,
|
|
65
|
+
// Queueing a prompt can resume an existing writable child after this
|
|
66
|
+
// orchestration call returns, so parent filesystem snapshots are stale-risk.
|
|
67
|
+
mayMutateWorkspaceAfterReturn: () => true,
|
|
65
68
|
async execute(input, ctx) {
|
|
66
69
|
// NB: next_steps is the FIRST envelope field — the registry's
|
|
67
70
|
// model-context tail truncation would eat it if it lived at the end.
|
package/yeaft/tools/types.js
CHANGED
|
@@ -68,6 +68,8 @@
|
|
|
68
68
|
* @property {(input: object, ctx?: ToolContext) => Promise<string>} execute — execution function
|
|
69
69
|
* @property {(input?: object) => boolean} [isConcurrencySafe] — can run in parallel?
|
|
70
70
|
* @property {(input?: object) => boolean} [isReadOnly] — read-only operation?
|
|
71
|
+
* @property {boolean | ((input?: object) => boolean)} [cacheWithinQuery] — explicitly safe to reuse for identical calls in one query
|
|
72
|
+
* @property {boolean | ((input?: object) => boolean)} [mayMutateWorkspaceAfterReturn] — may keep changing the workspace after execute() resolves; disables same-query read reuse
|
|
71
73
|
* @property {(input?: object) => boolean} [isDestructive] — destructive operation?
|
|
72
74
|
* @property {'json-error-envelope' | null} [errorOutput] — explicit returned-output error contract; null means only thrown errors fail
|
|
73
75
|
* @property {'external' | 'run'} [sideEffectScope] — whether mutations escape the current Run collector
|
|
@@ -83,6 +85,8 @@
|
|
|
83
85
|
* execute: (input: object, ctx?: ToolContext) => Promise<string>,
|
|
84
86
|
* isConcurrencySafe?: (input?: object) => boolean,
|
|
85
87
|
* isReadOnly?: (input?: object) => boolean,
|
|
88
|
+
* cacheWithinQuery?: boolean | ((input?: object) => boolean),
|
|
89
|
+
* mayMutateWorkspaceAfterReturn?: boolean | ((input?: object) => boolean),
|
|
86
90
|
* isDestructive?: (input?: object) => boolean,
|
|
87
91
|
* errorOutput?: 'json-error-envelope' | null,
|
|
88
92
|
* sideEffectScope?: 'external' | 'run',
|
|
@@ -98,6 +102,8 @@ export function defineTool({
|
|
|
98
102
|
execute,
|
|
99
103
|
isConcurrencySafe = () => false,
|
|
100
104
|
isReadOnly = () => false,
|
|
105
|
+
cacheWithinQuery = false,
|
|
106
|
+
mayMutateWorkspaceAfterReturn = false,
|
|
101
107
|
isDestructive = () => false,
|
|
102
108
|
errorOutput = 'json-error-envelope',
|
|
103
109
|
sideEffectScope = 'external',
|
|
@@ -113,6 +119,8 @@ export function defineTool({
|
|
|
113
119
|
execute,
|
|
114
120
|
isConcurrencySafe,
|
|
115
121
|
isReadOnly,
|
|
122
|
+
cacheWithinQuery,
|
|
123
|
+
mayMutateWorkspaceAfterReturn,
|
|
116
124
|
isDestructive,
|
|
117
125
|
errorOutput,
|
|
118
126
|
sideEffectScope,
|
package/yeaft/utf8.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* utf8.js — Small UTF-8 byte-budget helpers shared by Agent internals.
|
|
3
|
+
*
|
|
4
|
+
* JavaScript strings are UTF-16. Convert malformed lone surrogates before
|
|
5
|
+
* walking code points so a byte-limited preview is always well-formed Unicode.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export function normalizeUtf8ByteBudget(value, fallback = 0) {
|
|
9
|
+
const parsed = Number(value);
|
|
10
|
+
return Number.isFinite(parsed)
|
|
11
|
+
? Math.max(0, Math.floor(parsed))
|
|
12
|
+
: Math.max(0, Math.floor(Number(fallback) || 0));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function toWellFormedText(value) {
|
|
16
|
+
return String(value ?? '').toWellFormed();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Return the longest well-formed UTF-8 prefix within maxBytes.
|
|
21
|
+
*
|
|
22
|
+
* This makes one code-point pass and one final slice. It deliberately does
|
|
23
|
+
* not repeatedly rescan successively shorter UTF-16 slices with
|
|
24
|
+
* Buffer.byteLength(), which becomes quadratic for oversized payloads.
|
|
25
|
+
*/
|
|
26
|
+
export function utf8PrefixWithinBytes(value, maxBytes) {
|
|
27
|
+
const text = toWellFormedText(value);
|
|
28
|
+
const limit = normalizeUtf8ByteBudget(maxBytes);
|
|
29
|
+
let end = 0;
|
|
30
|
+
let bytes = 0;
|
|
31
|
+
|
|
32
|
+
while (end < text.length) {
|
|
33
|
+
const codePoint = text.codePointAt(end);
|
|
34
|
+
const width = codePoint > 0xFFFF ? 2 : 1;
|
|
35
|
+
const byteLength = codePoint <= 0x7F
|
|
36
|
+
? 1
|
|
37
|
+
: (codePoint <= 0x7FF ? 2 : (codePoint <= 0xFFFF ? 3 : 4));
|
|
38
|
+
if (bytes + byteLength > limit) break;
|
|
39
|
+
bytes += byteLength;
|
|
40
|
+
end += width;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { text: text.slice(0, end), bytes };
|
|
44
|
+
}
|
package/yeaft/web-bridge.js
CHANGED
|
@@ -192,6 +192,11 @@ export async function refreshLiveSessionConfig(options = {}) {
|
|
|
192
192
|
|
|
193
193
|
const configRoot = liveConfigRoot();
|
|
194
194
|
const freshConfig = loadConfig({ dir: configRoot });
|
|
195
|
+
// All bridge producers reference ctx.CONFIG. Keep it synchronized even
|
|
196
|
+
// when no live Session is loaded and refresh returns early below.
|
|
197
|
+
if (ctx.CONFIG && typeof ctx.CONFIG === 'object') {
|
|
198
|
+
ctx.CONFIG.telemetry = freshConfig.telemetry;
|
|
199
|
+
}
|
|
195
200
|
const previousDefaultModel = options.previousDefaultModel
|
|
196
201
|
|| session?.config?.primaryModel
|
|
197
202
|
|| session?.config?.model
|
|
@@ -234,6 +239,7 @@ export async function refreshLiveSessionConfig(options = {}) {
|
|
|
234
239
|
for (const key of Object.keys(currentConfig)) delete currentConfig[key];
|
|
235
240
|
Object.assign(currentConfig, nextConfig);
|
|
236
241
|
liveSession.engine?.refreshConfig?.(currentConfig);
|
|
242
|
+
liveSession.trace?.refreshConfig?.(currentConfig.telemetry || {});
|
|
237
243
|
for (const { key, engine, config } of vpConfigSnapshots) {
|
|
238
244
|
engine.refreshConfig?.(config);
|
|
239
245
|
vpEngineConfigKeys.set(key, engineConfigKey(config));
|
|
@@ -823,6 +823,7 @@ export class WorkItemRunner {
|
|
|
823
823
|
this.trace = options.trace || createTrace({
|
|
824
824
|
enabled: options.debug === true && Boolean(options.yeaftDir),
|
|
825
825
|
dirPath: options.yeaftDir || null,
|
|
826
|
+
textMaxBytes: options.config?.telemetry?.traceTextMaxBytes,
|
|
826
827
|
});
|
|
827
828
|
this.actionWorktreeRoot = options.actionWorktreeRoot || null;
|
|
828
829
|
this.store = options.store;
|