wtt-connect 0.2.59 → 0.2.61
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/src/runner.js +77 -5
- package/src/wtt-api.js +14 -0
package/package.json
CHANGED
package/src/runner.js
CHANGED
|
@@ -77,6 +77,18 @@ export class Runner {
|
|
|
77
77
|
return buildRuntimeInfo(this.config, this.store.getRuntime());
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
async buildKnowledgeContext(metadata, query) {
|
|
81
|
+
const meta = parseMetadata(metadata);
|
|
82
|
+
if (!meta || meta.kb_mode !== true) return '';
|
|
83
|
+
const kbTaskId = String(meta.kb_task_id || meta.kbTaskId || '').trim();
|
|
84
|
+
if (!kbTaskId) return '';
|
|
85
|
+
const result = await this.api.searchKnowledgeContext(kbTaskId, query, { limit: 8 });
|
|
86
|
+
return renderKnowledgeContextBlock(result?.results || [], {
|
|
87
|
+
taskId: kbTaskId,
|
|
88
|
+
scope: meta.kb_scope || meta.kbScope || 'personal',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
80
92
|
async onEvent(msg) {
|
|
81
93
|
if (msg.type === 'shell_run') {
|
|
82
94
|
await this.handleShellRun(msg);
|
|
@@ -182,6 +194,11 @@ export class Runner {
|
|
|
182
194
|
await this.wtt.typing(topicId, 'start', { statusText: `${adapterDisplayName(adapter.name)} 正在执行${modelConfig.model ? ` · ${modelConfig.model}` : ''}`, statusKind: 'running', adapter: adapter.name, model: modelConfig.model || undefined, ttlMs: 30000 });
|
|
183
195
|
const agentProfile = await this.getAgentProfile();
|
|
184
196
|
const agentSoul = renderAgentSoulContext(m.metadata, agentProfile?.role_template);
|
|
197
|
+
const knowledgeContext = await this.buildKnowledgeContext(m.metadata, [
|
|
198
|
+
content,
|
|
199
|
+
staged.promptBlock,
|
|
200
|
+
transcripts.map((item) => item.text).join('\n'),
|
|
201
|
+
].filter(Boolean).join('\n\n'));
|
|
185
202
|
const discussionRouting = renderDiscussionRoutingInstruction(m, this.config);
|
|
186
203
|
const currentDisplayName = effectiveAgentDisplayName(this.config, agentProfile);
|
|
187
204
|
const isSlashPassthrough = isAgentSlashCommand(m, content);
|
|
@@ -198,7 +215,7 @@ export class Runner {
|
|
|
198
215
|
if (localSlash !== null) {
|
|
199
216
|
const reply = stripHiddenContextLeak(localSlash || '(empty response)') || '(empty response)';
|
|
200
217
|
await chatStream.finish(reply);
|
|
201
|
-
await this.wtt.publish(topicId, reply, 'CHAT_REPLY',
|
|
218
|
+
await this.wtt.publish(topicId, reply, 'CHAT_REPLY', chatStream.finalMetadata());
|
|
202
219
|
log('info', 'slash command replied', { topicId, adapter: adapter.name, chars: reply.length });
|
|
203
220
|
return;
|
|
204
221
|
}
|
|
@@ -218,6 +235,8 @@ export class Runner {
|
|
|
218
235
|
discussionRouting ? '' : null,
|
|
219
236
|
agentSoul,
|
|
220
237
|
agentSoul ? '' : null,
|
|
238
|
+
knowledgeContext,
|
|
239
|
+
knowledgeContext ? '' : null,
|
|
221
240
|
renderCompactSummaryBlock(compactSummary),
|
|
222
241
|
compactSummary ? '' : null,
|
|
223
242
|
'User message:',
|
|
@@ -241,12 +260,12 @@ export class Runner {
|
|
|
241
260
|
const reply = prepared.text || '(empty response)';
|
|
242
261
|
await chatStream.finish(reply);
|
|
243
262
|
await this.maybeAttachSpeech(topicId, reply, `chat-${topicId}`);
|
|
244
|
-
await this.wtt.publish(topicId, reply, 'CHAT_REPLY',
|
|
263
|
+
await this.wtt.publish(topicId, reply, 'CHAT_REPLY', chatStream.finalMetadata());
|
|
245
264
|
await this.publishGeneratedFileArtifacts(topicId, prepared.refs, { source: 'chat', sourceId: topicId, adapter: adapter.name });
|
|
246
265
|
log('info', 'chat replied', { topicId, chars: reply.length });
|
|
247
266
|
} catch (err) {
|
|
248
267
|
await chatStream?.fail(err?.message || String(err));
|
|
249
|
-
await this.wtt.publish(topicId, `执行失败:${err.message}`, 'CHAT_REPLY', chatStream?.
|
|
268
|
+
await this.wtt.publish(topicId, `执行失败:${err.message}`, 'CHAT_REPLY', chatStream?.finalMetadata?.() || null);
|
|
250
269
|
log('error', 'chat failed', { topicId, error: err.message });
|
|
251
270
|
} finally {
|
|
252
271
|
if (runtimeSelection) this.recordRuntimeSelection(runtimeSelection.adapter, runtimeSelection.modelConfig, 'idle');
|
|
@@ -267,7 +286,25 @@ export class Runner {
|
|
|
267
286
|
this.recordRuntimeSelection(adapter.name, modelConfig, 'running');
|
|
268
287
|
const agentProfile = await this.getAgentProfile();
|
|
269
288
|
if (topicId) await this.wtt.typing(topicId, 'start', { statusText: `${adapterDisplayName(adapter.name)} 正在执行任务${modelConfig.model ? ` · ${modelConfig.model}` : ''}`, statusKind: 'running', adapter: adapter.name, model: modelConfig.model || undefined, ttlMs: 30000 });
|
|
270
|
-
const
|
|
289
|
+
const taskMetadata = task.metadata || task.msg_metadata || event?.message?.metadata || event?.metadata;
|
|
290
|
+
const taskQuery = [
|
|
291
|
+
task.title,
|
|
292
|
+
task.description,
|
|
293
|
+
task.content,
|
|
294
|
+
task.task_request,
|
|
295
|
+
event?.message?.content,
|
|
296
|
+
staged.promptBlock,
|
|
297
|
+
transcripts.map((item) => item.text).join('\n'),
|
|
298
|
+
].filter(Boolean).join('\n\n');
|
|
299
|
+
const knowledgeContext = await this.buildKnowledgeContext(taskMetadata, taskQuery);
|
|
300
|
+
const prompt = buildTaskPrompt(
|
|
301
|
+
{ ...task, metadata: taskMetadata || task.metadata },
|
|
302
|
+
this.config,
|
|
303
|
+
staged,
|
|
304
|
+
transcripts,
|
|
305
|
+
agentProfile,
|
|
306
|
+
knowledgeContext,
|
|
307
|
+
);
|
|
271
308
|
try {
|
|
272
309
|
const output = await this.runAdapter(adapter, prompt, {
|
|
273
310
|
sessionKey: `wtt:task:${taskId}:${adapter.name}:${sessionModelKey(modelConfig)}`,
|
|
@@ -610,6 +647,14 @@ export class Runner {
|
|
|
610
647
|
|
|
611
648
|
return {
|
|
612
649
|
id: streamId,
|
|
650
|
+
finalMetadata() {
|
|
651
|
+
return {
|
|
652
|
+
stream_id: streamId,
|
|
653
|
+
streamId,
|
|
654
|
+
adapter: adapterName,
|
|
655
|
+
model: modelConfig.model || modelConfig.model_id || modelConfig.modelId || '',
|
|
656
|
+
};
|
|
657
|
+
},
|
|
613
658
|
async start() {
|
|
614
659
|
await send('start');
|
|
615
660
|
},
|
|
@@ -1415,6 +1460,31 @@ function renderAgentSoulContext(metadata, profileRole = null) {
|
|
|
1415
1460
|
].join('\n');
|
|
1416
1461
|
}
|
|
1417
1462
|
|
|
1463
|
+
function renderKnowledgeContextBlock(results = [], options = {}) {
|
|
1464
|
+
const rows = Array.isArray(results) ? results : [];
|
|
1465
|
+
if (!rows.length) {
|
|
1466
|
+
return [
|
|
1467
|
+
'WTT personal knowledge base mode is enabled, but no indexed chunk matched this request.',
|
|
1468
|
+
'If the user expects a recently uploaded file to be used, say the knowledge base may still be indexing and ask for the specific file or detail needed.',
|
|
1469
|
+
].join('\n');
|
|
1470
|
+
}
|
|
1471
|
+
const lines = [
|
|
1472
|
+
'WTT personal knowledge base context. Use these user-provided references when relevant, cite filenames naturally, and do not claim you read files that are not represented here.',
|
|
1473
|
+
`knowledge_scope: ${options.scope || 'personal'}`,
|
|
1474
|
+
`knowledge_task_id: ${options.taskId || 'unknown'}`,
|
|
1475
|
+
];
|
|
1476
|
+
rows.slice(0, 8).forEach((row, index) => {
|
|
1477
|
+
const filename = String(row.filename || row.title || row.source_id || `source-${index + 1}`).slice(0, 180);
|
|
1478
|
+
const chunk = row.chunk_index !== undefined ? `#${row.chunk_index}` : `#${index + 1}`;
|
|
1479
|
+
const content = truncateForTranscript(String(row.content || row.snippet || ''), 2400);
|
|
1480
|
+
if (!content.trim()) return;
|
|
1481
|
+
lines.push('');
|
|
1482
|
+
lines.push(`[KB ${index + 1}] ${filename} ${chunk}`);
|
|
1483
|
+
lines.push(content);
|
|
1484
|
+
});
|
|
1485
|
+
return truncateForTranscript(lines.join('\n'), 18000);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1418
1488
|
function stripHiddenContextLeak(text) {
|
|
1419
1489
|
return String(text || '')
|
|
1420
1490
|
.replace(/\[Agent Role Template\][\s\S]*?\[\/Agent Role Template\]\s*/gi, '')
|
|
@@ -1490,7 +1560,7 @@ function taskFromEvent(taskId, event) {
|
|
|
1490
1560
|
return { id: taskId, title: m.title || `WTT task ${taskId}`, description: m.content || '', topic_id: m.topic_id };
|
|
1491
1561
|
}
|
|
1492
1562
|
|
|
1493
|
-
function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts = [], agentProfile = null) {
|
|
1563
|
+
function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts = [], agentProfile = null, knowledgeContext = '') {
|
|
1494
1564
|
const title = task.title || task.name || `Task ${task.id}`;
|
|
1495
1565
|
const description = task.description || task.content || task.task_request || '';
|
|
1496
1566
|
const agentSoul = renderAgentSoulContext(task.metadata || task.msg_metadata, agentProfile?.role_template);
|
|
@@ -1501,6 +1571,8 @@ function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts
|
|
|
1501
1571
|
'',
|
|
1502
1572
|
agentSoul,
|
|
1503
1573
|
agentSoul ? '' : null,
|
|
1574
|
+
knowledgeContext,
|
|
1575
|
+
knowledgeContext ? '' : null,
|
|
1504
1576
|
'Description:',
|
|
1505
1577
|
description,
|
|
1506
1578
|
staged.promptBlock,
|
package/src/wtt-api.js
CHANGED
|
@@ -92,6 +92,20 @@ export class WTTApi {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
async searchKnowledgeContext(kbTaskId, query, { limit = 8 } = {}) {
|
|
96
|
+
if (!kbTaskId || !String(query || '').trim()) return { results: [] };
|
|
97
|
+
const params = new URLSearchParams({ kb_task_id: String(kbTaskId) });
|
|
98
|
+
try {
|
|
99
|
+
return await this.request('POST', `/kb/context/search?${params.toString()}`, {
|
|
100
|
+
headers: this.agentHeaders(),
|
|
101
|
+
json: { query: String(query || '').slice(0, 4000), limit },
|
|
102
|
+
});
|
|
103
|
+
} catch (err) {
|
|
104
|
+
log('warn', 'kb_context_search failed', { kbTaskId, error: err.message });
|
|
105
|
+
return { results: [] };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
95
109
|
async runTask(taskId, payload = {}) {
|
|
96
110
|
return this.request('POST', `/tasks/${taskId}/run`, { json: payload });
|
|
97
111
|
}
|