wtt-connect 0.2.60 → 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 +66 -2
- 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);
|
|
@@ -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:',
|
|
@@ -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)}`,
|
|
@@ -1423,6 +1460,31 @@ function renderAgentSoulContext(metadata, profileRole = null) {
|
|
|
1423
1460
|
].join('\n');
|
|
1424
1461
|
}
|
|
1425
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
|
+
|
|
1426
1488
|
function stripHiddenContextLeak(text) {
|
|
1427
1489
|
return String(text || '')
|
|
1428
1490
|
.replace(/\[Agent Role Template\][\s\S]*?\[\/Agent Role Template\]\s*/gi, '')
|
|
@@ -1498,7 +1560,7 @@ function taskFromEvent(taskId, event) {
|
|
|
1498
1560
|
return { id: taskId, title: m.title || `WTT task ${taskId}`, description: m.content || '', topic_id: m.topic_id };
|
|
1499
1561
|
}
|
|
1500
1562
|
|
|
1501
|
-
function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts = [], agentProfile = null) {
|
|
1563
|
+
function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts = [], agentProfile = null, knowledgeContext = '') {
|
|
1502
1564
|
const title = task.title || task.name || `Task ${task.id}`;
|
|
1503
1565
|
const description = task.description || task.content || task.task_request || '';
|
|
1504
1566
|
const agentSoul = renderAgentSoulContext(task.metadata || task.msg_metadata, agentProfile?.role_template);
|
|
@@ -1509,6 +1571,8 @@ function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts
|
|
|
1509
1571
|
'',
|
|
1510
1572
|
agentSoul,
|
|
1511
1573
|
agentSoul ? '' : null,
|
|
1574
|
+
knowledgeContext,
|
|
1575
|
+
knowledgeContext ? '' : null,
|
|
1512
1576
|
'Description:',
|
|
1513
1577
|
description,
|
|
1514
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
|
}
|