@yeaft/webchat-agent 1.0.308 → 1.0.310
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 +5 -1
- package/local-runtime/server/db/connection.js +13 -2
- package/local-runtime/server/db/yeaft-project-db.js +26 -1
- package/local-runtime/server/handlers/client-conversation.js +32 -1
- package/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +243 -177
- 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/engine.js +12 -4
- package/yeaft/projects/store.js +18 -0
- package/yeaft/prompts.js +13 -0
- package/yeaft/sub-agent/prompt-queue.js +22 -0
- package/yeaft/sub-agent/runner.js +32 -8
- package/yeaft/tools/send-message.js +5 -2
- package/yeaft/web-bridge.js +37 -3
|
@@ -30,7 +30,7 @@ import { getLlmConfig, updateLlmConfig, getYeaftSettings, updateYeaftSettings, g
|
|
|
30
30
|
import { loadConfig } from '../yeaft/config.js';
|
|
31
31
|
import { discoverLlmModels } from '../llm-model-discovery.js';
|
|
32
32
|
import { fetchModelsDev } from '../yeaft/llm/models-dev.js';
|
|
33
|
-
import { handleYeaftSessionSend, handleYeaftAskUserAnswer, handleYeaftSubAgentPrompt, handleYeaftTaskCancel, handleYeaftModeSwitch, handleYeaftModelSwitch, resetYeaftSession, refreshLiveSessionConfig, handleYeaftLoadHistory, handleYeaftLoadHistoryOutline, handleYeaftSearchHistory, handleYeaftLoadHistoryWindow, handleYeaftLoadMoreHistory, handleYeaftAbortThread, handleYeaftAbortAll, handleYeaftAbortTurn, handleYeaftVpSubscribe, handleYeaftVpCreate, handleYeaftVpUpdate, handleYeaftVpDelete, handleYeaftVpRead, handleYeaftListSessions, handleYeaftProjectMutation, handleYeaftCreateSession, handleYeaftRenameSession, handleYeaftUpdateSession, handleYeaftUpdateSessionConfig, handleYeaftArchiveSession, handleYeaftDeleteSession, handleYeaftSessionAddMember, handleYeaftSessionRemoveMember, handleYeaftSessionSetDefaultVp, handleYeaftScanWorkdirSessions, handleYeaftRestoreSession, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, handleYeaftMcpList, handleYeaftMcpAdd, handleYeaftMcpRemove, handleYeaftMcpReload, broadcastLanguageChange, broadcastYeaftSessionSnapshotEager, broadcastYeaftVpSnapshotEager, preloadYeaftSkillSlashCommands } from '../yeaft/web-bridge.js';
|
|
33
|
+
import { handleYeaftSessionSend, handleYeaftAskUserAnswer, handleYeaftSubAgentPrompt, handleYeaftTaskCancel, handleYeaftModeSwitch, handleYeaftModelSwitch, resetYeaftSession, refreshLiveSessionConfig, handleYeaftLoadHistory, handleYeaftLoadHistoryOutline, handleYeaftSearchHistory, handleYeaftLoadHistoryWindow, handleYeaftLoadMoreHistory, handleYeaftAbortThread, handleYeaftAbortAll, handleYeaftAbortTurn, handleYeaftVpSubscribe, handleYeaftVpCreate, handleYeaftVpUpdate, handleYeaftVpDelete, handleYeaftVpRead, handleYeaftListSessions, handleYeaftProjectContextSync, handleYeaftProjectMutation, handleYeaftCreateSession, handleYeaftRenameSession, handleYeaftUpdateSession, handleYeaftUpdateSessionConfig, handleYeaftArchiveSession, handleYeaftDeleteSession, handleYeaftSessionAddMember, handleYeaftSessionRemoveMember, handleYeaftSessionSetDefaultVp, handleYeaftScanWorkdirSessions, handleYeaftRestoreSession, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, handleYeaftMcpList, handleYeaftMcpAdd, handleYeaftMcpRemove, handleYeaftMcpReload, broadcastLanguageChange, broadcastYeaftSessionSnapshotEager, broadcastYeaftVpSnapshotEager, preloadYeaftSkillSlashCommands } from '../yeaft/web-bridge.js';
|
|
34
34
|
import { startYeaftStatusRefresh, forceRefreshYeaftStatus } from '../yeaft/status-cache.js';
|
|
35
35
|
import { handleWorkCenterRequest } from '../yeaft/work-center/bridge.js';
|
|
36
36
|
|
|
@@ -506,6 +506,10 @@ export async function handleMessage(msg) {
|
|
|
506
506
|
await handleYeaftSessionSend(msg);
|
|
507
507
|
break;
|
|
508
508
|
|
|
509
|
+
case 'yeaft_project_context_sync':
|
|
510
|
+
handleYeaftProjectContextSync(msg);
|
|
511
|
+
break;
|
|
512
|
+
|
|
509
513
|
case 'yeaft_project_mutation':
|
|
510
514
|
handleYeaftProjectMutation(msg);
|
|
511
515
|
break;
|
|
@@ -248,6 +248,7 @@ db.exec(`
|
|
|
248
248
|
id TEXT NOT NULL,
|
|
249
249
|
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
250
250
|
name TEXT NOT NULL,
|
|
251
|
+
instruction TEXT NOT NULL DEFAULT '',
|
|
251
252
|
sort_order INTEGER NOT NULL,
|
|
252
253
|
created_at INTEGER NOT NULL,
|
|
253
254
|
updated_at INTEGER NOT NULL,
|
|
@@ -331,6 +332,13 @@ for (const migration of yeaftMigrations) {
|
|
|
331
332
|
try { db.exec(migration); } catch (_) { /* column exists */ }
|
|
332
333
|
}
|
|
333
334
|
|
|
335
|
+
const yeaftProjectMigrations = [
|
|
336
|
+
`ALTER TABLE yeaft_projects ADD COLUMN instruction TEXT NOT NULL DEFAULT ''`,
|
|
337
|
+
];
|
|
338
|
+
for (const migration of yeaftProjectMigrations) {
|
|
339
|
+
try { db.exec(migration); } catch (_) { /* column exists */ }
|
|
340
|
+
}
|
|
341
|
+
|
|
334
342
|
for (const migration of migrations) {
|
|
335
343
|
try {
|
|
336
344
|
db.exec(migration);
|
|
@@ -679,8 +687,8 @@ export const stmts = {
|
|
|
679
687
|
// Project organization metadata. Projects are server-owned and may contain
|
|
680
688
|
// Sessions from multiple Agents; sharing still filters by agent_id.
|
|
681
689
|
insertYeaftProject: db.prepare(`
|
|
682
|
-
INSERT INTO yeaft_projects (id, user_id, name, sort_order, created_at, updated_at)
|
|
683
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
690
|
+
INSERT INTO yeaft_projects (id, user_id, name, instruction, sort_order, created_at, updated_at)
|
|
691
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
684
692
|
`),
|
|
685
693
|
getYeaftProjectsByUser: db.prepare(`
|
|
686
694
|
SELECT * FROM yeaft_projects WHERE user_id = ? ORDER BY sort_order ASC, created_at ASC
|
|
@@ -691,6 +699,9 @@ export const stmts = {
|
|
|
691
699
|
updateYeaftProjectName: db.prepare(`
|
|
692
700
|
UPDATE yeaft_projects SET name = ?, updated_at = ? WHERE user_id = ? AND id = ?
|
|
693
701
|
`),
|
|
702
|
+
updateYeaftProjectInstruction: db.prepare(`
|
|
703
|
+
UPDATE yeaft_projects SET instruction = ?, updated_at = ? WHERE user_id = ? AND id = ?
|
|
704
|
+
`),
|
|
694
705
|
deleteYeaftProject: db.prepare(`
|
|
695
706
|
DELETE FROM yeaft_projects WHERE user_id = ? AND id = ?
|
|
696
707
|
`),
|
|
@@ -21,6 +21,17 @@ function requireName(value) {
|
|
|
21
21
|
return name.slice(0, 120);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
function normalizeInstruction(value) {
|
|
25
|
+
if (typeof value !== 'string') {
|
|
26
|
+
throw new YeaftProjectDbError('invalid_instruction', 'Project instruction must be a string');
|
|
27
|
+
}
|
|
28
|
+
const instruction = value.trim();
|
|
29
|
+
if (instruction.length > 20_000) {
|
|
30
|
+
throw new YeaftProjectDbError('instruction_too_long', 'Project instruction must not exceed 20000 characters');
|
|
31
|
+
}
|
|
32
|
+
return instruction;
|
|
33
|
+
}
|
|
34
|
+
|
|
24
35
|
function requireId(value, code, label) {
|
|
25
36
|
const id = typeof value === 'string' ? value.trim() : '';
|
|
26
37
|
if (!id) throw new YeaftProjectDbError(code, `${label} is required`);
|
|
@@ -32,6 +43,7 @@ function mapProject(row, members = []) {
|
|
|
32
43
|
return {
|
|
33
44
|
id: row.id,
|
|
34
45
|
name: row.name,
|
|
46
|
+
instruction: typeof row.instruction === 'string' ? row.instruction : '',
|
|
35
47
|
sortOrder: row.sort_order,
|
|
36
48
|
createdAt: row.created_at,
|
|
37
49
|
updatedAt: row.updated_at,
|
|
@@ -79,6 +91,7 @@ export const yeaftProjectDb = {
|
|
|
79
91
|
const project = {
|
|
80
92
|
id: `project-${randomUUID().slice(0, 8)}`,
|
|
81
93
|
name: requireName(name),
|
|
94
|
+
instruction: '',
|
|
82
95
|
sortOrder: projects.reduce((max, row) => Math.max(max, Number(row.sortOrder) || 0), -1) + 1,
|
|
83
96
|
createdAt: now,
|
|
84
97
|
updatedAt: now,
|
|
@@ -88,6 +101,7 @@ export const yeaftProjectDb = {
|
|
|
88
101
|
project.id,
|
|
89
102
|
ownerId,
|
|
90
103
|
project.name,
|
|
104
|
+
project.instruction,
|
|
91
105
|
project.sortOrder,
|
|
92
106
|
now,
|
|
93
107
|
now,
|
|
@@ -105,6 +119,16 @@ export const yeaftProjectDb = {
|
|
|
105
119
|
stmts.getYeaftProjectMembersByUser.all(ownerId).filter(member => member.project_id === id));
|
|
106
120
|
},
|
|
107
121
|
|
|
122
|
+
updateInstruction(userId, projectId, instruction) {
|
|
123
|
+
const ownerId = requireUserId(userId);
|
|
124
|
+
const id = requireId(projectId, 'invalid_project_id', 'Project id');
|
|
125
|
+
requireProject(ownerId, id);
|
|
126
|
+
const nextInstruction = normalizeInstruction(instruction);
|
|
127
|
+
stmts.updateYeaftProjectInstruction.run(nextInstruction, Date.now(), ownerId, id);
|
|
128
|
+
return mapProject(stmts.getYeaftProjectForUser.get(ownerId, id),
|
|
129
|
+
stmts.getYeaftProjectMembersByUser.all(ownerId).filter(member => member.project_id === id));
|
|
130
|
+
},
|
|
131
|
+
|
|
108
132
|
delete(userId, projectId) {
|
|
109
133
|
const ownerId = requireUserId(userId);
|
|
110
134
|
const id = requireId(projectId, 'invalid_project_id', 'Project id');
|
|
@@ -185,7 +209,7 @@ export const yeaftProjectDb = {
|
|
|
185
209
|
for (let suffix = 2; usedNames.has(name); suffix += 1) name = `${baseName} ${suffix}`;
|
|
186
210
|
const projectId = `project-${randomUUID().slice(0, 8)}`;
|
|
187
211
|
const now = Date.now();
|
|
188
|
-
stmts.insertYeaftProject.run(projectId, ownerId, name.slice(0, 120), sortOrder, now, now);
|
|
212
|
+
stmts.insertYeaftProject.run(projectId, ownerId, name.slice(0, 120), '', sortOrder, now, now);
|
|
189
213
|
sortOrder += 1;
|
|
190
214
|
usedNames.add(name);
|
|
191
215
|
for (const rawSessionId of Array.isArray(row.sessionIds) ? row.sessionIds : []) {
|
|
@@ -219,6 +243,7 @@ export const yeaftProjectDb = {
|
|
|
219
243
|
return {
|
|
220
244
|
projectId: project.id,
|
|
221
245
|
projectName: project.name,
|
|
246
|
+
projectInstruction: typeof project.instruction === 'string' ? project.instruction : '',
|
|
222
247
|
sessionIds: sameAgentMembers,
|
|
223
248
|
};
|
|
224
249
|
},
|
|
@@ -49,6 +49,33 @@ async function sendVpSnapshotError(client, msg, error) {
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
export async function syncProjectContextsToAgents(userId) {
|
|
53
|
+
try {
|
|
54
|
+
const sessionsByAgent = groupOnlineYeaftSessions(yeaftSessionDb.getByUser(userId));
|
|
55
|
+
await Promise.all(Object.entries(sessionsByAgent).map(async ([agentId, sessions]) => {
|
|
56
|
+
try {
|
|
57
|
+
const contexts = sessions.map(session => ({
|
|
58
|
+
sessionId: session.id,
|
|
59
|
+
projectContext: yeaftProjectDb.contextForSession(userId, agentId, session.id) || {
|
|
60
|
+
projectId: null,
|
|
61
|
+
projectName: null,
|
|
62
|
+
projectInstruction: '',
|
|
63
|
+
sessionIds: [],
|
|
64
|
+
},
|
|
65
|
+
}));
|
|
66
|
+
await forwardToAgent(agentId, {
|
|
67
|
+
type: 'yeaft_project_context_sync',
|
|
68
|
+
contexts,
|
|
69
|
+
});
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.warn(`[Yeaft] Project context sync failed for Agent ${agentId}:`, err?.message || err);
|
|
72
|
+
}
|
|
73
|
+
}));
|
|
74
|
+
} catch (err) {
|
|
75
|
+
console.warn('[Yeaft] Project context sync failed:', err?.message || err);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
52
79
|
async function broadcastSessionPin(userId, payload) {
|
|
53
80
|
for (const [, target] of webClients) {
|
|
54
81
|
if (!target?.authenticated) continue;
|
|
@@ -1299,7 +1326,9 @@ export async function handleClientConversation(clientId, client, msg, checkAgent
|
|
|
1299
1326
|
let result = null;
|
|
1300
1327
|
if (op === 'create') result = yeaftProjectDb.create(client.userId, msg.name);
|
|
1301
1328
|
else if (op === 'rename') result = yeaftProjectDb.rename(client.userId, msg.projectId, msg.name);
|
|
1302
|
-
else if (op === '
|
|
1329
|
+
else if (op === 'update_instruction') {
|
|
1330
|
+
result = yeaftProjectDb.updateInstruction(client.userId, msg.projectId, msg.instruction);
|
|
1331
|
+
} else if (op === 'delete') result = yeaftProjectDb.delete(client.userId, msg.projectId);
|
|
1303
1332
|
else if (op === 'move_session') {
|
|
1304
1333
|
const agentId = msg.targetAgentId || msg.agentId;
|
|
1305
1334
|
const sessionId = typeof msg.sessionId === 'string' ? msg.sessionId.trim() : '';
|
|
@@ -1324,6 +1353,7 @@ export async function handleClientConversation(clientId, client, msg, checkAgent
|
|
|
1324
1353
|
? yeaftProjectDb.listForAgent(client.userId, responseAgentId)
|
|
1325
1354
|
: yeaftProjectDb.list(client.userId);
|
|
1326
1355
|
await respond({ ok: true, result, projects });
|
|
1356
|
+
await syncProjectContextsToAgents(client.userId);
|
|
1327
1357
|
await broadcastSessionCatalog(client.userId);
|
|
1328
1358
|
} catch (err) {
|
|
1329
1359
|
await respond({
|
|
@@ -1474,6 +1504,7 @@ export async function handleClientConversation(clientId, client, msg, checkAgent
|
|
|
1474
1504
|
rest.projectContext = projectContext || {
|
|
1475
1505
|
projectId: null,
|
|
1476
1506
|
projectName: null,
|
|
1507
|
+
projectInstruction: '',
|
|
1477
1508
|
sessionIds: [],
|
|
1478
1509
|
};
|
|
1479
1510
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.0.
|
|
1
|
+
{"version":"1.0.310"}
|