wtt-connect 0.1.6 → 0.1.7
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 +29 -68
- package/src/wtt-api.js +10 -0
package/package.json
CHANGED
package/src/runner.js
CHANGED
|
@@ -35,6 +35,7 @@ export class Runner {
|
|
|
35
35
|
this.queuedTasks = new Set();
|
|
36
36
|
this.runningTasks = new Set();
|
|
37
37
|
this.doneTasks = new Map();
|
|
38
|
+
this.agentProfileCache = { value: null, expiresAt: 0 };
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
async start() {
|
|
@@ -156,9 +157,10 @@ export class Runner {
|
|
|
156
157
|
const transcripts = await this.transcribeAttachments(staged.files);
|
|
157
158
|
const adapter = this.registry.select({ ...m, content });
|
|
158
159
|
await this.wtt.typing(topicId, 'start', { statusText: `${adapterDisplayName(adapter.name)} 正在执行`, statusKind: 'running', adapter: adapter.name, ttlMs: 30000 });
|
|
159
|
-
const
|
|
160
|
+
const agentProfile = await this.getAgentProfile();
|
|
161
|
+
const agentSoul = renderAgentSoulContext(m.metadata, agentProfile?.role_template);
|
|
160
162
|
const discussionRouting = renderDiscussionRoutingInstruction(m, this.config);
|
|
161
|
-
const currentDisplayName = effectiveAgentDisplayName(this.config);
|
|
163
|
+
const currentDisplayName = effectiveAgentDisplayName(this.config, agentProfile);
|
|
162
164
|
const prompt = [
|
|
163
165
|
'You are replying to a WTT Web conversation. Do not mention implementation internals unless asked.',
|
|
164
166
|
`WTT topic_id: ${topicId}`,
|
|
@@ -189,7 +191,7 @@ export class Runner {
|
|
|
189
191
|
});
|
|
190
192
|
const reply = stripHiddenContextLeak(output || '(empty response)') || '(empty response)';
|
|
191
193
|
await this.maybeAttachSpeech(topicId, reply, `chat-${topicId}`);
|
|
192
|
-
await this.wtt.publish(topicId, reply, 'CHAT_REPLY'
|
|
194
|
+
await this.wtt.publish(topicId, reply, 'CHAT_REPLY');
|
|
193
195
|
log('info', 'chat replied', { topicId, chars: reply.length });
|
|
194
196
|
} catch (err) {
|
|
195
197
|
await this.wtt.publish(topicId, `执行失败:${err.message}`, 'CHAT_REPLY');
|
|
@@ -208,8 +210,9 @@ export class Runner {
|
|
|
208
210
|
const staged = await this.attachments.stageMessage(task);
|
|
209
211
|
const transcripts = await this.transcribeAttachments(staged.files);
|
|
210
212
|
const adapter = this.registry.select(task);
|
|
213
|
+
const agentProfile = await this.getAgentProfile();
|
|
211
214
|
if (topicId) await this.wtt.typing(topicId, 'start', { statusText: `${adapterDisplayName(adapter.name)} 正在执行任务`, statusKind: 'running', adapter: adapter.name, ttlMs: 30000 });
|
|
212
|
-
const prompt = buildTaskPrompt(task, this.config, staged, transcripts);
|
|
215
|
+
const prompt = buildTaskPrompt(task, this.config, staged, transcripts, agentProfile);
|
|
213
216
|
try {
|
|
214
217
|
const output = await adapter.run(prompt, {
|
|
215
218
|
sessionKey: `wtt:task:${taskId}`,
|
|
@@ -240,6 +243,14 @@ export class Runner {
|
|
|
240
243
|
}
|
|
241
244
|
}
|
|
242
245
|
|
|
246
|
+
async getAgentProfile() {
|
|
247
|
+
const now = Date.now();
|
|
248
|
+
if (this.agentProfileCache.value && now < this.agentProfileCache.expiresAt) return this.agentProfileCache.value;
|
|
249
|
+
const value = await this.api.getAgentProfile(this.config.agentId);
|
|
250
|
+
this.agentProfileCache = { value, expiresAt: now + 30_000 };
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
253
|
+
|
|
243
254
|
async transcribeAttachments(files) {
|
|
244
255
|
try {
|
|
245
256
|
return await this.stt.transcribeAll(files);
|
|
@@ -473,51 +484,26 @@ function parseMetadata(metadata) {
|
|
|
473
484
|
return obj && typeof obj === 'object' ? obj : null;
|
|
474
485
|
}
|
|
475
486
|
|
|
476
|
-
function effectiveAgentDisplayName(config) {
|
|
487
|
+
function effectiveAgentDisplayName(config, profile = null) {
|
|
488
|
+
const profileName = String(profile?.display_name || '').trim();
|
|
489
|
+
if (profileName && profileName.toLowerCase() !== 'wtt-connect') return profileName;
|
|
477
490
|
const name = String(config.setupDisplayName || '').trim();
|
|
478
491
|
if (!name || name.toLowerCase() === 'wtt-connect') return '';
|
|
479
492
|
return name;
|
|
480
493
|
}
|
|
481
494
|
|
|
482
|
-
function
|
|
483
|
-
const meta = parseMetadata(metadata);
|
|
484
|
-
if (!meta || typeof meta !== 'object') return null;
|
|
485
|
-
const out = {};
|
|
486
|
-
for (const key of [
|
|
487
|
-
'agent_role_templates_by_agent',
|
|
488
|
-
'agentRoleTemplatesByAgent',
|
|
489
|
-
]) {
|
|
490
|
-
const value = meta[key];
|
|
491
|
-
if (value && typeof value === 'object') out[key] = value;
|
|
492
|
-
}
|
|
493
|
-
return Object.keys(out).length ? out : null;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function renderAgentSoulContext(metadata, currentAgentId = '') {
|
|
495
|
+
function renderAgentSoulContext(metadata, profileRole = null) {
|
|
497
496
|
const meta = parseMetadata(metadata);
|
|
498
|
-
if (!meta) return '';
|
|
499
497
|
|
|
500
498
|
const lines = [];
|
|
501
|
-
const
|
|
502
|
-
const
|
|
503
|
-
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if (roleByAgent.label) lines.push(`Adopt this agent role silently: ${roleByAgent.label}.`);
|
|
510
|
-
if (Array.isArray(roleByAgent.skills) && roleByAgent.skills.length) lines.push(`Relevant capabilities: ${roleByAgent.skills.join(', ')}.`);
|
|
511
|
-
const systemPrompt = roleByAgent.system_prompt || roleByAgent.systemPrompt || roleByAgent.instructions;
|
|
512
|
-
if (systemPrompt) lines.push(String(systemPrompt));
|
|
513
|
-
} else if (!hasRoleMap && soul && typeof soul === 'object') {
|
|
514
|
-
if (soul.role) lines.push(`Adopt this agent role silently: ${soul.role}.`);
|
|
515
|
-
if (Array.isArray(soul.skills) && soul.skills.length) lines.push(`Relevant capabilities: ${soul.skills.join(', ')}.`);
|
|
516
|
-
if (soul.instructions) lines.push(String(soul.instructions));
|
|
517
|
-
} else if (!hasRoleMap && role && typeof role === 'object') {
|
|
518
|
-
if (role.label) lines.push(`Adopt this agent role silently: ${role.label}.`);
|
|
519
|
-
if (Array.isArray(role.skills) && role.skills.length) lines.push(`Relevant capabilities: ${role.skills.join(', ')}.`);
|
|
520
|
-
const systemPrompt = role.system_prompt || role.systemPrompt || role.instructions;
|
|
499
|
+
const persona = meta?.worker_persona;
|
|
500
|
+
const workerContext = meta?.worker_context;
|
|
501
|
+
|
|
502
|
+
const profileRoleObject = profileRole && typeof profileRole === 'object' ? profileRole : null;
|
|
503
|
+
if (profileRoleObject && (profileRoleObject.label || profileRoleObject.system_prompt || profileRoleObject.systemPrompt)) {
|
|
504
|
+
if (profileRoleObject.label) lines.push(`Adopt this agent role silently: ${profileRoleObject.label}.`);
|
|
505
|
+
if (Array.isArray(profileRoleObject.skills) && profileRoleObject.skills.length) lines.push(`Relevant capabilities: ${profileRoleObject.skills.join(', ')}.`);
|
|
506
|
+
const systemPrompt = profileRoleObject.system_prompt || profileRoleObject.systemPrompt || profileRoleObject.instructions;
|
|
521
507
|
if (systemPrompt) lines.push(String(systemPrompt));
|
|
522
508
|
}
|
|
523
509
|
|
|
@@ -539,31 +525,6 @@ function renderAgentSoulContext(metadata, currentAgentId = '') {
|
|
|
539
525
|
].join('\n');
|
|
540
526
|
}
|
|
541
527
|
|
|
542
|
-
function hasAgentRoleTemplateMap(meta) {
|
|
543
|
-
const byAgent = meta.agent_role_templates_by_agent || meta.agentRoleTemplatesByAgent;
|
|
544
|
-
return Boolean(byAgent && typeof byAgent === 'object');
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
function getRoleTemplateForAgent(meta, currentAgentId) {
|
|
548
|
-
const byAgent = meta.agent_role_templates_by_agent || meta.agentRoleTemplatesByAgent;
|
|
549
|
-
if (!byAgent || typeof byAgent !== 'object' || !currentAgentId) return null;
|
|
550
|
-
|
|
551
|
-
const exact = byAgent[currentAgentId];
|
|
552
|
-
if (exact && typeof exact === 'object') return exact;
|
|
553
|
-
|
|
554
|
-
const normalizedCurrent = normalizeAgentRoleMapKey(currentAgentId);
|
|
555
|
-
for (const [agentId, role] of Object.entries(byAgent)) {
|
|
556
|
-
if (normalizeAgentRoleMapKey(agentId) === normalizedCurrent && role && typeof role === 'object') {
|
|
557
|
-
return role;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
return null;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
function normalizeAgentRoleMapKey(value) {
|
|
564
|
-
return String(value || '').trim().toLowerCase();
|
|
565
|
-
}
|
|
566
|
-
|
|
567
528
|
function stripHiddenContextLeak(text) {
|
|
568
529
|
return String(text || '')
|
|
569
530
|
.replace(/\[Agent Role Template\][\s\S]*?\[\/Agent Role Template\]\s*/gi, '')
|
|
@@ -639,10 +600,10 @@ function taskFromEvent(taskId, event) {
|
|
|
639
600
|
return { id: taskId, title: m.title || `WTT task ${taskId}`, description: m.content || '', topic_id: m.topic_id };
|
|
640
601
|
}
|
|
641
602
|
|
|
642
|
-
function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts = []) {
|
|
603
|
+
function buildTaskPrompt(task, config, staged = { promptBlock: '' }, transcripts = [], agentProfile = null) {
|
|
643
604
|
const title = task.title || task.name || `Task ${task.id}`;
|
|
644
605
|
const description = task.description || task.content || task.task_request || '';
|
|
645
|
-
const agentSoul = renderAgentSoulContext(task.metadata || task.msg_metadata,
|
|
606
|
+
const agentSoul = renderAgentSoulContext(task.metadata || task.msg_metadata, agentProfile?.role_template);
|
|
646
607
|
return [
|
|
647
608
|
'You are executing a WTT task through wtt-connect.',
|
|
648
609
|
`Task ID: ${task.id}`,
|
package/src/wtt-api.js
CHANGED
|
@@ -49,6 +49,16 @@ export class WTTApi {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
async getAgentProfile(agentId = this.config.agentId) {
|
|
53
|
+
if (!agentId) return null;
|
|
54
|
+
try {
|
|
55
|
+
return await this.request('GET', `/agents/${encodeURIComponent(agentId)}/profile`);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
log('warn', 'get_agent_profile failed', { agentId, error: err.message });
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
52
62
|
async patchTask(taskId, payload) {
|
|
53
63
|
if (this.config.dryRun) {
|
|
54
64
|
log('info', 'dry-run patch task', { taskId, fields: Object.keys(payload).join(',') });
|