@yeaft/webchat-agent 1.0.640 → 1.0.642
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 +4 -1
- package/index.js +1 -1
- package/local-runtime/server/handlers/agent-output.js +7 -5
- package/local-runtime/server/handlers/client-conversation.js +47 -0
- package/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +158 -119
- 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/conversation/persist.js +272 -24
- package/yeaft/conversation/session-history.js +336 -0
- package/yeaft/engine.js +88 -573
- package/yeaft/history-window.js +132 -5
- package/yeaft/routing/router.js +4 -0
- package/yeaft/sessions/index.js +1 -0
- package/yeaft/sessions/session-crud.js +68 -3
- package/yeaft/tools/agent.js +4 -1
- package/yeaft/web-bridge.js +255 -54
|
@@ -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, handleYeaftProjectContextSync, handleYeaftProjectMutation, handleYeaftCreateSession, handleYeaftCopySession, handleYeaftRenameSession, handleYeaftUpdateSession, handleYeaftUpdateSessionConfig, handleYeaftArchiveSession, handleYeaftDeleteSession, handleYeaftSessionAddMember, handleYeaftSessionRemoveMember, handleYeaftSessionSetDefaultVp, handleYeaftScanWorkdirSessions, handleYeaftRestoreSession, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, handleYeaftMcpList, handleYeaftMcpAdd, handleYeaftMcpRemove, handleYeaftMcpReload, handleYeaftPluginCatalog, handleYeaftManagedSkill, ensureSessionLoaded, 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, handleYeaftCopySession, handleYeaftMergeSessions, handleYeaftRenameSession, handleYeaftUpdateSession, handleYeaftUpdateSessionConfig, handleYeaftArchiveSession, handleYeaftDeleteSession, handleYeaftSessionAddMember, handleYeaftSessionRemoveMember, handleYeaftSessionSetDefaultVp, handleYeaftScanWorkdirSessions, handleYeaftRestoreSession, handleYeaftDreamTrigger, handleYeaftFetchToolStats, handleYeaftFetchDebugHistory, handleYeaftMcpList, handleYeaftMcpAdd, handleYeaftMcpRemove, handleYeaftMcpReload, handleYeaftPluginCatalog, handleYeaftManagedSkill, ensureSessionLoaded, 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
|
import { handlePersonRequest } from '../yeaft/person/bridge.js';
|
|
@@ -793,6 +793,9 @@ export async function handleMessage(msg) {
|
|
|
793
793
|
case 'yeaft_copy_session':
|
|
794
794
|
handleYeaftCopySession(msg);
|
|
795
795
|
break;
|
|
796
|
+
case 'yeaft_merge_sessions':
|
|
797
|
+
handleYeaftMergeSessions(msg);
|
|
798
|
+
break;
|
|
796
799
|
case 'yeaft_rename_group':
|
|
797
800
|
case 'unify_rename_group':
|
|
798
801
|
case 'yeaft_rename_session':
|
package/index.js
CHANGED
|
@@ -178,7 +178,7 @@ async function detectCapabilities() {
|
|
|
178
178
|
// agent build can speak plaintext WS frames. New servers see this and
|
|
179
179
|
// flip `agent.encryptOutbound = false`, stopping outbound encryption
|
|
180
180
|
// to this peer. Old servers ignore the unknown capability token.
|
|
181
|
-
const capabilities = ['background_tasks', 'file_editor', 'ping_session', 'plaintext-ok', 'workbench_session_routes', 'workbench_request_correlation', 'workbench_terminal_cleanup_fence', 'workbench_file_content_chunks', 'workbench_video_stream', 'session_history_search', 'session_history_outline', 'session_history_window_prefetch', 'session_fork_from_turn', 'file_reference_resolution', 'response_image_preview', 'yeaft_plugins', 'yeaft_managed_skills', 'settings_request_correlation', 'work_center_feature_settings'];
|
|
181
|
+
const capabilities = ['background_tasks', 'file_editor', 'ping_session', 'plaintext-ok', 'workbench_session_routes', 'workbench_request_correlation', 'workbench_terminal_cleanup_fence', 'workbench_file_content_chunks', 'workbench_video_stream', 'session_history_search', 'session_history_outline', 'session_history_window_prefetch', 'session_fork_from_turn', 'session_fork_while_running', 'session_merge', 'file_reference_resolution', 'response_image_preview', 'yeaft_plugins', 'yeaft_managed_skills', 'settings_request_correlation', 'work_center_feature_settings'];
|
|
182
182
|
capabilities.push('digital_person', getAgentUpgradeCapability());
|
|
183
183
|
if (ctx.CONFIG?.workCenterEnabled === true) {
|
|
184
184
|
capabilities.push('work_center', 'work_center_message_v2', 'work_center_workbench');
|
|
@@ -91,12 +91,14 @@ function syncYeaftSessionMetadata(agentId, agent, event) {
|
|
|
91
91
|
}
|
|
92
92
|
return { ...event, sessions: decorateYeaftSessionsWithPinned(agentId, event.sessions) };
|
|
93
93
|
}
|
|
94
|
-
// A fork is a new Session on the same Agent, not a new Project. Resolve
|
|
94
|
+
// A fork/merge is a new Session on the same Agent, not a new Project. Resolve
|
|
95
95
|
// membership here (never from browser/Agent project metadata) before the
|
|
96
96
|
// successful acknowledgement can focus the new Session in the browser.
|
|
97
|
-
if (event.ok && ownerId && op === 'copy' && event.sourceSessionId && event.session?.id) {
|
|
97
|
+
if (event.ok && ownerId && (op === 'copy' || op === 'merge') && event.sourceSessionId && event.session?.id) {
|
|
98
98
|
try {
|
|
99
|
-
if (event.sourceSessionId === event.session.id
|
|
99
|
+
if (event.sourceSessionId === event.session.id || event.otherSessionId === event.session.id) {
|
|
100
|
+
throw new Error('Fork/merge must have a new Session identity');
|
|
101
|
+
}
|
|
100
102
|
transaction(() => {
|
|
101
103
|
// Replayed acknowledgements must not undo a later user Project move.
|
|
102
104
|
if (yeaftSessionDb.getForAgent(ownerId, agentId, event.session.id)) return;
|
|
@@ -104,13 +106,13 @@ function syncYeaftSessionMetadata(agentId, agent, event) {
|
|
|
104
106
|
yeaftProjectDb.inheritSessionProject(ownerId, agentId, event.sourceSessionId, event.session.id);
|
|
105
107
|
})();
|
|
106
108
|
} catch (e) {
|
|
107
|
-
console.warn('[Server]
|
|
109
|
+
console.warn('[Server] Session Project inheritance failed:', e?.message || e);
|
|
108
110
|
return {
|
|
109
111
|
...event,
|
|
110
112
|
ok: false,
|
|
111
113
|
error: {
|
|
112
114
|
code: 'project_inheritance_failed',
|
|
113
|
-
message:
|
|
115
|
+
message: `${op === 'merge' ? 'Merged Session' : 'Fork'} ${event.session.id} was created, but its Project could not be saved.`,
|
|
114
116
|
},
|
|
115
117
|
};
|
|
116
118
|
}
|
|
@@ -1624,6 +1624,53 @@ export async function handleClientConversation(clientId, client, msg, checkAgent
|
|
|
1624
1624
|
break;
|
|
1625
1625
|
}
|
|
1626
1626
|
|
|
1627
|
+
case 'yeaft_merge_sessions':
|
|
1628
|
+
case 'unify_merge_sessions': {
|
|
1629
|
+
const mergeAgentId = msg.agentId || client.currentAgent || null;
|
|
1630
|
+
const reject = async (code, message) => sendToWebClient(client, {
|
|
1631
|
+
type: 'session_crud_result', op: 'merge', ok: false,
|
|
1632
|
+
requestId: msg.requestId ?? null,
|
|
1633
|
+
agentId: mergeAgentId,
|
|
1634
|
+
sourceSessionId: msg.sessionId ?? null,
|
|
1635
|
+
otherSessionId: msg.otherSessionId ?? null,
|
|
1636
|
+
error: { code, message },
|
|
1637
|
+
});
|
|
1638
|
+
// Use the shared ACL directly: checkAgentAccess emits an uncorrelated
|
|
1639
|
+
// error, which would leave the browser's pending merge waiting forever.
|
|
1640
|
+
const accessError = resolveAgentAccessError(mergeAgentId, client.userId, client.role);
|
|
1641
|
+
if (accessError) {
|
|
1642
|
+
await reject(accessError === 'Agent access denied' ? 'agent_access_denied' : 'agent_unavailable', accessError);
|
|
1643
|
+
break;
|
|
1644
|
+
}
|
|
1645
|
+
if (!agents.get(mergeAgentId)?.capabilities?.includes('session_merge')) {
|
|
1646
|
+
await reject('session_merge_unsupported', 'The selected Agent does not support merging Sessions.');
|
|
1647
|
+
break;
|
|
1648
|
+
}
|
|
1649
|
+
if (typeof msg.sessionId !== 'string' || !msg.sessionId.trim()
|
|
1650
|
+
|| typeof msg.otherSessionId !== 'string' || !msg.otherSessionId.trim()
|
|
1651
|
+
|| msg.sessionId === msg.otherSessionId) {
|
|
1652
|
+
await reject('invalid_merge_source', 'Select two different Sessions on the same Agent.');
|
|
1653
|
+
break;
|
|
1654
|
+
}
|
|
1655
|
+
if (!CONFIG.skipAuth && (!yeaftSessionDb.getForAgent(client.userId, mergeAgentId, msg.sessionId)
|
|
1656
|
+
|| !yeaftSessionDb.getForAgent(client.userId, mergeAgentId, msg.otherSessionId))) {
|
|
1657
|
+
await reject('agent_access_denied', 'Both Sessions must belong to the selected Agent and current user.');
|
|
1658
|
+
break;
|
|
1659
|
+
}
|
|
1660
|
+
// Session ids are scoped to this one Agent; no cross-Agent lookup or
|
|
1661
|
+
// fallback is allowed even if another Agent has an identically named id.
|
|
1662
|
+
let dispatched = false;
|
|
1663
|
+
try {
|
|
1664
|
+
dispatched = await forwardToAgent(mergeAgentId, {
|
|
1665
|
+
type: 'yeaft_merge_sessions', requestId: msg.requestId,
|
|
1666
|
+
sessionId: msg.sessionId, otherSessionId: msg.otherSessionId,
|
|
1667
|
+
...(msg.name !== undefined ? { name: msg.name } : {}),
|
|
1668
|
+
});
|
|
1669
|
+
} catch { /* Report a correlated dispatch failure below. */ }
|
|
1670
|
+
if (!dispatched) await reject('agent_unavailable', 'Agent is unavailable; Sessions were not merged.');
|
|
1671
|
+
break;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1627
1674
|
case 'yeaft_merge_thread':
|
|
1628
1675
|
case 'unify_merge_thread': {
|
|
1629
1676
|
const mergeAgentId = msg.agentId || client.currentAgent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.0.
|
|
1
|
+
{"version":"1.0.642"}
|