@agent-link/agent 0.1.326 → 0.1.329
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/dist/backends/index.js +2 -0
- package/dist/backends/index.js.map +1 -1
- package/dist/backends/types.d.ts +71 -21
- package/dist/backends/types.js +93 -1
- package/dist/backends/types.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/connection.js +324 -43
- package/dist/connection.js.map +1 -1
- package/dist/history-message-transform.d.ts +3 -0
- package/dist/history-message-transform.js.map +1 -1
- package/dist/pi.d.ts +4 -0
- package/dist/pi.js +234 -4
- package/dist/pi.js.map +1 -1
- package/dist/provider-command-discovery.d.ts +25 -0
- package/dist/provider-command-discovery.js +42 -0
- package/dist/provider-command-discovery.js.map +1 -0
- package/dist/provider-command-types.d.ts +23 -0
- package/dist/provider-command-types.js +13 -0
- package/dist/provider-command-types.js.map +1 -0
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +17 -1
- package/dist/providers.js.map +1 -1
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.js +5 -0
- package/dist/runtime.js.map +1 -1
- package/dist/sdk.d.ts +2 -1
- package/dist/sdk.js +8 -1
- package/dist/sdk.js.map +1 -1
- package/dist/yeaft.d.ts +105 -0
- package/dist/yeaft.js +1334 -0
- package/dist/yeaft.js.map +1 -0
- package/package.json +1 -1
package/dist/connection.js
CHANGED
|
@@ -29,10 +29,13 @@ const require = createRequire(import.meta.url);
|
|
|
29
29
|
const pkg = require('../package.json');
|
|
30
30
|
const TEAM_SESSIONS_DIR = path.join(CONFIG_DIR, 'team-sessions');
|
|
31
31
|
const LOOP_SESSIONS_DIR = path.join(CONFIG_DIR, 'loop-sessions');
|
|
32
|
-
import { handleChat as claudeHandleChat, addSendFn, abort as abortClaude, abortAll as abortAllClaude, cancelExecution as claudeCancelExecution, handleUserAnswer, handleToolPermissionResponse, handleBtwQuestion, getConversation, getConversations, getIsCompacting, clearSessionId, evictByClaudeSessionId, rebindConversation, addOutputObserver, removeOutputObserver, addCloseObserver, removeCloseObserver, setOutputObserver, clearOutputObserver, setCloseObserver, clearCloseObserver, restartConversation, createPlaceholderConversation, getPendingQuestions, getPendingToolPermissions, setModel, addOnSessionStarted, getBackendType, setBackendType, isCopilotBackend, isCodexBackend, isPiBackend, addCopilotSendFn, handleCopilotChat, cancelCopilotExecution, listCopilotSessionsPage, listAllCopilotSessionsPage, readCopilotSessionMessages, getCopilotSessionWorkDir, deleteCopilotSession, renameCopilotSession, moveCopilotSession, getCopilotConversation, getCopilotConversations, createCopilotPlaceholder, restartCopilotConversation, rebindCopilotConversation, cleanupAllCopilotConversations, copilotCapabilities, addCodexSendFn, handleCodexChat, cancelCodexExecution, listCodexSessionsPage, listAllCodexSessionsPage, readCodexSessionMessages, deleteCodexSession, renameCodexSession, moveCodexSession, getCodexConversation, getCodexConversations, createCodexPlaceholder, restartCodexConversation, rebindCodexConversation, cleanupAllCodexConversations, evictByCodexSessionId, codexCapabilities } from './runtime.js';
|
|
32
|
+
import { handleChat as claudeHandleChat, addSendFn, abort as abortClaude, abortAll as abortAllClaude, cancelExecution as claudeCancelExecution, handleUserAnswer, handleToolPermissionResponse, handleBtwQuestion, getConversation, getConversations, getIsCompacting, clearSessionId, evictByClaudeSessionId, rebindConversation, addOutputObserver, removeOutputObserver, addCloseObserver, removeCloseObserver, setOutputObserver, clearOutputObserver, setCloseObserver, clearCloseObserver, restartConversation, createPlaceholderConversation, getPendingQuestions, getPendingToolPermissions, setModel, addOnSessionStarted, getBackendType, setBackendType, isCopilotBackend, isCodexBackend, isPiBackend, isYeaftBackend, addCopilotSendFn, handleCopilotChat, cancelCopilotExecution, listCopilotSessionsPage, listAllCopilotSessionsPage, readCopilotSessionMessages, getCopilotSessionWorkDir, deleteCopilotSession, renameCopilotSession, moveCopilotSession, getCopilotConversation, getCopilotConversations, createCopilotPlaceholder, restartCopilotConversation, rebindCopilotConversation, cleanupAllCopilotConversations, copilotCapabilities, addCodexSendFn, handleCodexChat, cancelCodexExecution, listCodexSessionsPage, listAllCodexSessionsPage, readCodexSessionMessages, deleteCodexSession, renameCodexSession, moveCodexSession, getCodexConversation, getCodexConversations, createCodexPlaceholder, restartCodexConversation, rebindCodexConversation, cleanupAllCodexConversations, evictByCodexSessionId, codexCapabilities } from './runtime.js';
|
|
33
33
|
import { addPiSendFn, cancelPiExecution, cleanupAllPiConversations, createPiPlaceholder, deletePiSession, evictByPiSessionId, getPiConversation, getPiConversations, getPiSessionWorkDir, handlePiChat, listAllPiSessionsPage, listPiSessionsPage, movePiSession, piCapabilities, readPiSessionMessages, rebindPiConversation, renamePiSession, restartPiConversation, } from './pi.js';
|
|
34
|
+
import { addYeaftSendFn, cancelYeaftExecution, cleanupAllYeaftConversations, createYeaftPlaceholder, deleteYeaftSession, evictByYeaftSessionId, getYeaftConversation, getYeaftConversations, handleYeaftChat, handleYeaftUserAnswer, listAllYeaftSessionsPage, listYeaftSessionsPage, moveYeaftSession, readYeaftSessionMessages, rebindYeaftConversation, renameYeaftSession, restartYeaftConversation, } from './yeaft.js';
|
|
34
35
|
import { DEFAULT_SESSION_LIST_LIMIT, LEGACY_SESSION_LIST_CAP, listSessions, listSessionsPageAsync, readSessionMessages, deleteSession, renameSession, moveSession, listAllRecentSessionsPage, getSessionCacheStats } from './history.js';
|
|
35
|
-
import {
|
|
36
|
+
import { discoverProviderCommands, providerCommandDiscoverers, } from './provider-command-discovery.js';
|
|
37
|
+
import { providerCommandsMessage } from './provider-command-types.js';
|
|
38
|
+
import { claudeCapabilities, yeaftCapabilities } from './backends/types.js';
|
|
36
39
|
import { searchSessions } from './search-sessions.js';
|
|
37
40
|
import { formatSessionExport, isSessionExportFormat } from './session-export.js';
|
|
38
41
|
import { listMemoryFiles, updateMemoryFile, deleteMemoryFile } from './memory.js';
|
|
@@ -71,6 +74,7 @@ let unsubscribeSend = null;
|
|
|
71
74
|
let unsubscribeCopilotSend = null;
|
|
72
75
|
let unsubscribeCodexSend = null;
|
|
73
76
|
let unsubscribePiSend = null;
|
|
77
|
+
let unsubscribeYeaftSend = null;
|
|
74
78
|
let unsubscribeSessionStarted = null;
|
|
75
79
|
let heartbeatInterval = null;
|
|
76
80
|
let heartbeatTimeout = null;
|
|
@@ -80,18 +84,30 @@ initEntraTimers({
|
|
|
80
84
|
setToken: (token) => { state.entraToken = token; },
|
|
81
85
|
send: (msg) => send(msg),
|
|
82
86
|
});
|
|
83
|
-
function capabilitiesForBackend(backend) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
function capabilitiesForBackend(backend, providerId) {
|
|
88
|
+
const capabilities = (() => {
|
|
89
|
+
switch (backend) {
|
|
90
|
+
case 'copilot':
|
|
91
|
+
return copilotCapabilities();
|
|
92
|
+
case 'codex':
|
|
93
|
+
return codexCapabilities();
|
|
94
|
+
case 'pi':
|
|
95
|
+
return piCapabilities();
|
|
96
|
+
case 'yeaft':
|
|
97
|
+
return yeaftCapabilities();
|
|
98
|
+
case 'claude':
|
|
99
|
+
default:
|
|
100
|
+
return claudeCapabilities();
|
|
101
|
+
}
|
|
102
|
+
})();
|
|
103
|
+
if (!providerId)
|
|
104
|
+
return capabilities;
|
|
105
|
+
return {
|
|
106
|
+
...capabilities,
|
|
107
|
+
commands: {
|
|
108
|
+
discovery: providerCommandDiscoverers.capability(providerId, backend),
|
|
109
|
+
},
|
|
110
|
+
};
|
|
95
111
|
}
|
|
96
112
|
function normalizeDirForCompare(value) {
|
|
97
113
|
const normalized = value.replace(/[\\/]+$/, '');
|
|
@@ -124,6 +140,16 @@ function hasActiveSessionConversation(backend, sessionId, providerId, workDir) {
|
|
|
124
140
|
}
|
|
125
141
|
}
|
|
126
142
|
}
|
|
143
|
+
else if (backend === 'yeaft') {
|
|
144
|
+
for (const conv of getYeaftConversations().values()) {
|
|
145
|
+
if ((conv.yeaftSessionId === sessionId || conv.lastYeaftSessionId === sessionId)
|
|
146
|
+
&& (!providerId || conv.providerId === providerId)
|
|
147
|
+
&& (!workDir || normalizeDirForCompare(conv.workDir) === normalizeDirForCompare(workDir))
|
|
148
|
+
&& conv.turnActive) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
127
153
|
else {
|
|
128
154
|
for (const conv of getConversations().values()) {
|
|
129
155
|
if (conv.claudeSessionId === sessionId || conv.lastClaudeSessionId === sessionId) {
|
|
@@ -155,6 +181,14 @@ function syncMovedConversationWorkDir(backend, sessionId, toWorkDir, providerId,
|
|
|
155
181
|
conv.workDir = toWorkDir;
|
|
156
182
|
}
|
|
157
183
|
}
|
|
184
|
+
else if (backend === 'yeaft') {
|
|
185
|
+
for (const conv of getYeaftConversations().values()) {
|
|
186
|
+
if ((conv.yeaftSessionId === sessionId || conv.lastYeaftSessionId === sessionId)
|
|
187
|
+
&& (!providerId || conv.providerId === providerId)
|
|
188
|
+
&& (!fromWorkDir || normalizeDirForCompare(conv.workDir) === normalizeDirForCompare(fromWorkDir)))
|
|
189
|
+
conv.workDir = toWorkDir;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
158
192
|
else {
|
|
159
193
|
for (const conv of getConversations().values()) {
|
|
160
194
|
if (conv.claudeSessionId === sessionId || conv.lastClaudeSessionId === sessionId)
|
|
@@ -224,6 +258,13 @@ export function initializeLocalConnection(config) {
|
|
|
224
258
|
catch { /* ignore */ }
|
|
225
259
|
}
|
|
226
260
|
unsubscribePiSend = addPiSendFn(send);
|
|
261
|
+
if (unsubscribeYeaftSend) {
|
|
262
|
+
try {
|
|
263
|
+
unsubscribeYeaftSend();
|
|
264
|
+
}
|
|
265
|
+
catch { /* ignore */ }
|
|
266
|
+
}
|
|
267
|
+
unsubscribeYeaftSend = addYeaftSendFn(send);
|
|
227
268
|
// Wire up action item session linkage
|
|
228
269
|
if (unsubscribeSessionStarted) {
|
|
229
270
|
try {
|
|
@@ -522,6 +563,7 @@ export function disconnect() {
|
|
|
522
563
|
cleanupAllCopilotConversations();
|
|
523
564
|
cleanupAllCodexConversations();
|
|
524
565
|
cleanupAllPiConversations();
|
|
566
|
+
cleanupAllYeaftConversations();
|
|
525
567
|
if (unsubscribeSend) {
|
|
526
568
|
try {
|
|
527
569
|
unsubscribeSend();
|
|
@@ -550,6 +592,13 @@ export function disconnect() {
|
|
|
550
592
|
catch { /* ignore */ }
|
|
551
593
|
unsubscribePiSend = null;
|
|
552
594
|
}
|
|
595
|
+
if (unsubscribeYeaftSend) {
|
|
596
|
+
try {
|
|
597
|
+
unsubscribeYeaftSend();
|
|
598
|
+
}
|
|
599
|
+
catch { /* ignore */ }
|
|
600
|
+
unsubscribeYeaftSend = null;
|
|
601
|
+
}
|
|
553
602
|
if (unsubscribeSessionStarted) {
|
|
554
603
|
try {
|
|
555
604
|
unsubscribeSessionStarted();
|
|
@@ -663,6 +712,7 @@ export function getConnectionStatus() {
|
|
|
663
712
|
conversations: getConversations().size
|
|
664
713
|
+ getCopilotConversations().size
|
|
665
714
|
+ getCodexConversations().size
|
|
715
|
+
+ getYeaftConversations().size
|
|
666
716
|
+ getPiConversations().size,
|
|
667
717
|
};
|
|
668
718
|
}
|
|
@@ -883,7 +933,7 @@ function handleServerMessage(msg) {
|
|
|
883
933
|
if (requiredBt !== getBackendType()) {
|
|
884
934
|
setBackendType(requiredBt);
|
|
885
935
|
console.log(`[AgentLink] Backend auto-switched to ${requiredBt} (chat providerId=${effectiveProviderId})`);
|
|
886
|
-
const caps = capabilitiesForBackend(requiredBt);
|
|
936
|
+
const caps = capabilitiesForBackend(requiredBt, effectiveProviderId);
|
|
887
937
|
send({
|
|
888
938
|
type: 'backend_info',
|
|
889
939
|
backend: requiredBt,
|
|
@@ -892,7 +942,15 @@ function handleServerMessage(msg) {
|
|
|
892
942
|
}
|
|
893
943
|
}
|
|
894
944
|
// Route to the selected backend.
|
|
895
|
-
if (
|
|
945
|
+
if (isYeaftBackend()) {
|
|
946
|
+
const yeaftMsg = msg;
|
|
947
|
+
handleYeaftChat(chatConvId || '', yeaftMsg.prompt, chatDir, {
|
|
948
|
+
resumeSessionId: chatOptions.resumeSessionId,
|
|
949
|
+
providerId: effectiveProviderId,
|
|
950
|
+
yeaftOptions: yeaftMsg.yeaftOptions || yeaftMsg.copilotOptions,
|
|
951
|
+
}, yeaftMsg.files);
|
|
952
|
+
}
|
|
953
|
+
else if (isPiBackend()) {
|
|
896
954
|
const piMsg = msg;
|
|
897
955
|
const piState = chatConvId ? getPiConversation(chatConvId) : undefined;
|
|
898
956
|
const piResumeDir = chatOptions.resumeSessionId
|
|
@@ -926,12 +984,46 @@ function handleServerMessage(msg) {
|
|
|
926
984
|
}
|
|
927
985
|
break;
|
|
928
986
|
}
|
|
987
|
+
case 'get_provider_commands': {
|
|
988
|
+
const m = msg;
|
|
989
|
+
if (typeof m.requestId !== 'string' || !m.requestId.trim()
|
|
990
|
+
|| typeof m.providerId !== 'string' || !m.providerId.trim()
|
|
991
|
+
|| typeof m.conversationId !== 'string' || !m.conversationId.trim()
|
|
992
|
+
|| typeof m.workDir !== 'string' || !m.workDir.trim()) {
|
|
993
|
+
send({
|
|
994
|
+
type: 'provider_commands_list',
|
|
995
|
+
requestId: m.requestId,
|
|
996
|
+
providerId: m.providerId,
|
|
997
|
+
conversationId: m.conversationId,
|
|
998
|
+
workDir: m.workDir,
|
|
999
|
+
commands: [],
|
|
1000
|
+
error: 'Invalid provider command discovery scope',
|
|
1001
|
+
});
|
|
1002
|
+
break;
|
|
1003
|
+
}
|
|
1004
|
+
const scope = {
|
|
1005
|
+
requestId: m.requestId,
|
|
1006
|
+
providerId: m.providerId,
|
|
1007
|
+
conversationId: m.conversationId,
|
|
1008
|
+
workDir: path.resolve(m.workDir),
|
|
1009
|
+
};
|
|
1010
|
+
void discoverProviderCommands(scope)
|
|
1011
|
+
.then(result => send(providerCommandsMessage(scope, result)))
|
|
1012
|
+
.catch(error => send(providerCommandsMessage(scope, {
|
|
1013
|
+
commands: [],
|
|
1014
|
+
error: error.message,
|
|
1015
|
+
})));
|
|
1016
|
+
break;
|
|
1017
|
+
}
|
|
929
1018
|
case 'cancel_execution':
|
|
930
1019
|
{
|
|
931
1020
|
const conversationId = msg.conversationId || '';
|
|
932
1021
|
// Cancellation follows conversation ownership, not the currently selected
|
|
933
1022
|
// provider. This keeps background turns cancellable after a tab switches.
|
|
934
|
-
if (
|
|
1023
|
+
if (getYeaftConversation(conversationId)) {
|
|
1024
|
+
cancelYeaftExecution(conversationId);
|
|
1025
|
+
}
|
|
1026
|
+
else if (getPiConversation(conversationId)) {
|
|
935
1027
|
cancelPiExecution(conversationId);
|
|
936
1028
|
}
|
|
937
1029
|
else if (getCodexConversation(conversationId)) {
|
|
@@ -943,6 +1035,9 @@ function handleServerMessage(msg) {
|
|
|
943
1035
|
else if (getConversation(conversationId)) {
|
|
944
1036
|
claudeCancelExecution(conversationId);
|
|
945
1037
|
}
|
|
1038
|
+
else if (isYeaftBackend()) {
|
|
1039
|
+
cancelYeaftExecution(conversationId);
|
|
1040
|
+
}
|
|
946
1041
|
else if (isPiBackend()) {
|
|
947
1042
|
cancelPiExecution(conversationId);
|
|
948
1043
|
}
|
|
@@ -964,7 +1059,17 @@ function handleServerMessage(msg) {
|
|
|
964
1059
|
const sessionBackend = m.providerId
|
|
965
1060
|
? getBackendTypeForProvider(m.providerId)
|
|
966
1061
|
: getBackendType();
|
|
967
|
-
if (sessionBackend === '
|
|
1062
|
+
if (sessionBackend === 'yeaft') {
|
|
1063
|
+
handleListYeaftSessionsFn(dir, {
|
|
1064
|
+
limit: m.limit,
|
|
1065
|
+
cursor: m.cursor,
|
|
1066
|
+
mode: m.mode,
|
|
1067
|
+
requestId: m.requestId,
|
|
1068
|
+
providerId: m.providerId,
|
|
1069
|
+
legacy: m.limit == null && !m.cursor && !m.mode && !m.requestId,
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
else if (sessionBackend === 'pi') {
|
|
968
1073
|
handleListPiSessionsFn(dir, {
|
|
969
1074
|
limit: m.limit,
|
|
970
1075
|
cursor: m.cursor,
|
|
@@ -1014,7 +1119,21 @@ function handleServerMessage(msg) {
|
|
|
1014
1119
|
const recentBackend = m.providerId
|
|
1015
1120
|
? getBackendTypeForProvider(m.providerId)
|
|
1016
1121
|
: getBackendType();
|
|
1017
|
-
if (recentBackend === '
|
|
1122
|
+
if (recentBackend === 'yeaft') {
|
|
1123
|
+
const page = listAllYeaftSessionsPage({ limit: m.limit, cursor: m.cursor });
|
|
1124
|
+
console.log(`[AgentLink] → recent_sessions_list (${page.sessions.length} Yeaft sessions) hasMore=${page.hasMore}`);
|
|
1125
|
+
send({
|
|
1126
|
+
type: 'recent_sessions_list',
|
|
1127
|
+
sessions: page.sessions,
|
|
1128
|
+
hasMore: page.hasMore,
|
|
1129
|
+
nextCursor: page.nextCursor,
|
|
1130
|
+
indexState: page.indexState,
|
|
1131
|
+
...(m.mode ? { mode: m.mode } : {}),
|
|
1132
|
+
...(m.requestId ? { requestId: m.requestId } : {}),
|
|
1133
|
+
providerId: m.providerId || 'yeaft',
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
else if (recentBackend === 'pi') {
|
|
1018
1137
|
const page = listAllPiSessionsPage({
|
|
1019
1138
|
limit: m.limit,
|
|
1020
1139
|
cursor: m.cursor,
|
|
@@ -1179,6 +1298,39 @@ function handleServerMessage(msg) {
|
|
|
1179
1298
|
const resumeBackend = m.providerId
|
|
1180
1299
|
? getBackendTypeForProvider(m.providerId)
|
|
1181
1300
|
: getBackendType();
|
|
1301
|
+
if (resumeBackend === 'yeaft') {
|
|
1302
|
+
if (convId) {
|
|
1303
|
+
rebindYeaftConversation(m.claudeSessionId, convId);
|
|
1304
|
+
if (!getYeaftConversation(convId)) {
|
|
1305
|
+
createYeaftPlaceholder(convId, { providerId: m.providerId || 'yeaft' });
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
const yeaftState = getYeaftConversation(convId || '');
|
|
1309
|
+
const resolvedWorkDir = explicitWorkDir || yeaftState?.workDir || state.workDir;
|
|
1310
|
+
if (yeaftState) {
|
|
1311
|
+
yeaftState.yeaftSessionId = m.claudeSessionId;
|
|
1312
|
+
yeaftState.lastYeaftSessionId = m.claudeSessionId;
|
|
1313
|
+
yeaftState.workDir = resolvedWorkDir;
|
|
1314
|
+
}
|
|
1315
|
+
const history = readYeaftSessionMessages(resolvedWorkDir, m.claudeSessionId);
|
|
1316
|
+
const isYeaftProcessing = !!(yeaftState?.turnActive && yeaftState.child);
|
|
1317
|
+
console.log(`[AgentLink] → conversation_resumed (${history.length} Yeaft messages, session ${m.claudeSessionId.slice(0, 8)})`);
|
|
1318
|
+
send({
|
|
1319
|
+
type: 'conversation_resumed',
|
|
1320
|
+
conversationId: convId,
|
|
1321
|
+
claudeSessionId: m.claudeSessionId,
|
|
1322
|
+
history,
|
|
1323
|
+
isCompacting: false,
|
|
1324
|
+
isProcessing: isYeaftProcessing,
|
|
1325
|
+
planMode: false,
|
|
1326
|
+
permissionMode: 'normal',
|
|
1327
|
+
workDir: resolvedWorkDir,
|
|
1328
|
+
providerId: m.providerId || 'yeaft',
|
|
1329
|
+
...(typeof m.scrollToMessageIdx === 'number' ? { scrollToMessageIdx: m.scrollToMessageIdx } : {}),
|
|
1330
|
+
...(m.searchQuery ? { searchQuery: m.searchQuery } : {}),
|
|
1331
|
+
});
|
|
1332
|
+
break;
|
|
1333
|
+
}
|
|
1182
1334
|
if (resumeBackend === 'pi') {
|
|
1183
1335
|
const persistedWorkDir = getPiSessionWorkDir(m.claudeSessionId, m.providerId || 'pi', explicitWorkDir);
|
|
1184
1336
|
if (convId) {
|
|
@@ -1392,7 +1544,10 @@ function handleServerMessage(msg) {
|
|
|
1392
1544
|
}
|
|
1393
1545
|
case 'ask_user_answer': {
|
|
1394
1546
|
const m = msg;
|
|
1395
|
-
|
|
1547
|
+
if (isYeaftBackend())
|
|
1548
|
+
handleYeaftUserAnswer(m.requestId, m.answers, { conversationId: m.conversationId });
|
|
1549
|
+
else
|
|
1550
|
+
handleUserAnswer(m.requestId, m.answers);
|
|
1396
1551
|
break;
|
|
1397
1552
|
}
|
|
1398
1553
|
case 'delete_session': {
|
|
@@ -1403,7 +1558,27 @@ function handleServerMessage(msg) {
|
|
|
1403
1558
|
const dir = m.workDir?.trim()
|
|
1404
1559
|
? path.resolve(m.workDir)
|
|
1405
1560
|
: (m.providerId === 'brain' ? BRAIN_DATA_DIR : state.workDir);
|
|
1406
|
-
if (sessionBackend === '
|
|
1561
|
+
if (sessionBackend === 'yeaft') {
|
|
1562
|
+
if (evictByYeaftSessionId(m.sessionId)) {
|
|
1563
|
+
send({ type: 'error', message: 'Cannot delete a session while it is processing.' });
|
|
1564
|
+
break;
|
|
1565
|
+
}
|
|
1566
|
+
const ok = deleteYeaftSession(dir, m.sessionId);
|
|
1567
|
+
console.log(`[AgentLink] delete Yeaft session ${m.sessionId}: ${ok}`);
|
|
1568
|
+
if (ok) {
|
|
1569
|
+
send({
|
|
1570
|
+
type: 'session_deleted',
|
|
1571
|
+
sessionId: m.sessionId,
|
|
1572
|
+
providerId: m.providerId || 'yeaft',
|
|
1573
|
+
workDir: dir,
|
|
1574
|
+
});
|
|
1575
|
+
}
|
|
1576
|
+
else {
|
|
1577
|
+
send({ type: 'error', message: 'Session not found or could not be deleted.' });
|
|
1578
|
+
}
|
|
1579
|
+
handleListYeaftSessionsFn(dir, { providerId: m.providerId || 'yeaft' });
|
|
1580
|
+
}
|
|
1581
|
+
else if (sessionBackend === 'pi') {
|
|
1407
1582
|
if (evictByPiSessionId(m.sessionId, m.providerId || 'pi', dir)) {
|
|
1408
1583
|
send({ type: 'error', message: 'Cannot delete a session while it is processing.' });
|
|
1409
1584
|
break;
|
|
@@ -1454,7 +1629,28 @@ function handleServerMessage(msg) {
|
|
|
1454
1629
|
const dir = m.workDir?.trim()
|
|
1455
1630
|
? path.resolve(m.workDir)
|
|
1456
1631
|
: (m.providerId === 'brain' ? BRAIN_DATA_DIR : state.workDir);
|
|
1457
|
-
if (sessionBackend === '
|
|
1632
|
+
if (sessionBackend === 'yeaft') {
|
|
1633
|
+
if (hasActiveSessionConversation('yeaft', m.sessionId, m.providerId || 'yeaft', dir)) {
|
|
1634
|
+
send({ type: 'error', message: 'Cannot rename a session while it is processing.' });
|
|
1635
|
+
break;
|
|
1636
|
+
}
|
|
1637
|
+
const ok = renameYeaftSession(dir, m.sessionId, m.newTitle);
|
|
1638
|
+
console.log(`[AgentLink] rename Yeaft session ${m.sessionId}: ${ok}`);
|
|
1639
|
+
if (ok) {
|
|
1640
|
+
send({
|
|
1641
|
+
type: 'session_renamed',
|
|
1642
|
+
sessionId: m.sessionId,
|
|
1643
|
+
newTitle: m.newTitle,
|
|
1644
|
+
providerId: m.providerId || 'yeaft',
|
|
1645
|
+
workDir: dir,
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
else {
|
|
1649
|
+
send({ type: 'error', message: 'Session not found or could not be renamed.' });
|
|
1650
|
+
}
|
|
1651
|
+
handleListYeaftSessionsFn(dir, { providerId: m.providerId || 'yeaft' });
|
|
1652
|
+
}
|
|
1653
|
+
else if (sessionBackend === 'pi') {
|
|
1458
1654
|
if (hasActiveSessionConversation('pi', m.sessionId, m.providerId || 'pi', dir)) {
|
|
1459
1655
|
send({ type: 'error', message: 'Cannot rename a session while it is processing.' });
|
|
1460
1656
|
break;
|
|
@@ -1518,7 +1714,10 @@ function handleServerMessage(msg) {
|
|
|
1518
1714
|
break;
|
|
1519
1715
|
}
|
|
1520
1716
|
let ok = false;
|
|
1521
|
-
if (sessionBackend === '
|
|
1717
|
+
if (sessionBackend === 'yeaft') {
|
|
1718
|
+
ok = moveYeaftSession(fromDir, toDir, m.sessionId);
|
|
1719
|
+
}
|
|
1720
|
+
else if (sessionBackend === 'pi') {
|
|
1522
1721
|
ok = movePiSession(fromDir, toDir, m.sessionId, m.providerId || 'pi');
|
|
1523
1722
|
}
|
|
1524
1723
|
else if (sessionBackend === 'codex') {
|
|
@@ -1541,11 +1740,15 @@ function handleServerMessage(msg) {
|
|
|
1541
1740
|
sessionId: m.sessionId,
|
|
1542
1741
|
fromWorkDir: fromDir,
|
|
1543
1742
|
toWorkDir: toDir,
|
|
1544
|
-
...(sessionBackend === 'pi'
|
|
1545
|
-
? { providerId: m.providerId ||
|
|
1743
|
+
...(sessionBackend === 'pi' || sessionBackend === 'yeaft'
|
|
1744
|
+
? { providerId: m.providerId || sessionBackend, workDir: toDir }
|
|
1546
1745
|
: (m.providerId ? { providerId: m.providerId } : {})),
|
|
1547
1746
|
});
|
|
1548
|
-
if (sessionBackend === '
|
|
1747
|
+
if (sessionBackend === 'yeaft') {
|
|
1748
|
+
handleListYeaftSessionsFn(fromDir, { providerId: m.providerId || 'yeaft' });
|
|
1749
|
+
handleListYeaftSessionsFn(toDir, { providerId: m.providerId || 'yeaft' });
|
|
1750
|
+
}
|
|
1751
|
+
else if (sessionBackend === 'pi') {
|
|
1549
1752
|
handleListPiSessionsFn(fromDir, { providerId: m.providerId || 'pi' });
|
|
1550
1753
|
handleListPiSessionsFn(toDir, { providerId: m.providerId || 'pi' });
|
|
1551
1754
|
}
|
|
@@ -1579,7 +1782,13 @@ function handleServerMessage(msg) {
|
|
|
1579
1782
|
break;
|
|
1580
1783
|
}
|
|
1581
1784
|
let readResult;
|
|
1582
|
-
if (exportBackend === '
|
|
1785
|
+
if (exportBackend === 'yeaft') {
|
|
1786
|
+
readResult = {
|
|
1787
|
+
history: readYeaftSessionMessages(dir, m.sessionId),
|
|
1788
|
+
workDir: dir,
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
else if (exportBackend === 'pi') {
|
|
1583
1792
|
readResult = {
|
|
1584
1793
|
history: readPiSessionMessages(dir, m.sessionId, m.providerId || 'pi'),
|
|
1585
1794
|
workDir: dir,
|
|
@@ -1626,7 +1835,7 @@ function handleServerMessage(msg) {
|
|
|
1626
1835
|
break;
|
|
1627
1836
|
}
|
|
1628
1837
|
sendSessionExportResult(requestId, m.sessionId, result, {
|
|
1629
|
-
providerId: m.providerId || (exportBackend === 'pi'
|
|
1838
|
+
providerId: m.providerId || ((exportBackend === 'pi' || exportBackend === 'yeaft') ? exportBackend : undefined),
|
|
1630
1839
|
workDir: readResult.workDir,
|
|
1631
1840
|
});
|
|
1632
1841
|
break;
|
|
@@ -1635,7 +1844,7 @@ function handleServerMessage(msg) {
|
|
|
1635
1844
|
const request = msg;
|
|
1636
1845
|
const active = [];
|
|
1637
1846
|
const pushActive = (convId, conv) => {
|
|
1638
|
-
const sessionId = conv.claudeSessionId ?? conv.copilotSessionId ?? conv.codexSessionId ?? conv.piSessionId ?? null;
|
|
1847
|
+
const sessionId = conv.claudeSessionId ?? conv.copilotSessionId ?? conv.codexSessionId ?? conv.yeaftSessionId ?? conv.piSessionId ?? null;
|
|
1639
1848
|
if (conv.turnActive) {
|
|
1640
1849
|
active.push({
|
|
1641
1850
|
conversationId: convId,
|
|
@@ -1668,6 +1877,9 @@ function handleServerMessage(msg) {
|
|
|
1668
1877
|
for (const [convId, conv] of getCodexConversations()) {
|
|
1669
1878
|
pushActive(convId, conv);
|
|
1670
1879
|
}
|
|
1880
|
+
for (const [convId, conv] of getYeaftConversations()) {
|
|
1881
|
+
pushActive(convId, conv);
|
|
1882
|
+
}
|
|
1671
1883
|
for (const [convId, conv] of getPiConversations()) {
|
|
1672
1884
|
pushActive(convId, conv);
|
|
1673
1885
|
}
|
|
@@ -1697,7 +1909,7 @@ function handleServerMessage(msg) {
|
|
|
1697
1909
|
return {
|
|
1698
1910
|
type: 'turn_status',
|
|
1699
1911
|
conversationId: convId,
|
|
1700
|
-
claudeSessionId: conv.claudeSessionId ?? conv.copilotSessionId ?? conv.codexSessionId ?? conv.piSessionId ?? null,
|
|
1912
|
+
claudeSessionId: conv.claudeSessionId ?? conv.copilotSessionId ?? conv.codexSessionId ?? conv.yeaftSessionId ?? conv.piSessionId ?? null,
|
|
1701
1913
|
turnId: conv.turnId,
|
|
1702
1914
|
status,
|
|
1703
1915
|
isProcessing: isProc,
|
|
@@ -1732,6 +1944,15 @@ function handleServerMessage(msg) {
|
|
|
1732
1944
|
}
|
|
1733
1945
|
}
|
|
1734
1946
|
}
|
|
1947
|
+
if (!found) {
|
|
1948
|
+
for (const [convId, conv] of getYeaftConversations()) {
|
|
1949
|
+
if (conv.turnId === m.turnId) {
|
|
1950
|
+
send(buildTurnStatus(convId, conv));
|
|
1951
|
+
found = true;
|
|
1952
|
+
break;
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1735
1956
|
if (!found) {
|
|
1736
1957
|
for (const [convId, conv] of getPiConversations()) {
|
|
1737
1958
|
if (conv.turnId === m.turnId) {
|
|
@@ -1761,12 +1982,18 @@ function handleServerMessage(msg) {
|
|
|
1761
1982
|
send(buildTurnStatus(m.conversationId, codexConv));
|
|
1762
1983
|
}
|
|
1763
1984
|
else {
|
|
1764
|
-
const
|
|
1765
|
-
if (
|
|
1766
|
-
send(buildTurnStatus(m.conversationId,
|
|
1985
|
+
const yeaftConv = getYeaftConversation(m.conversationId);
|
|
1986
|
+
if (yeaftConv) {
|
|
1987
|
+
send(buildTurnStatus(m.conversationId, yeaftConv));
|
|
1767
1988
|
}
|
|
1768
1989
|
else {
|
|
1769
|
-
|
|
1990
|
+
const piConv = getPiConversation(m.conversationId);
|
|
1991
|
+
if (piConv) {
|
|
1992
|
+
send(buildTurnStatus(m.conversationId, piConv));
|
|
1993
|
+
}
|
|
1994
|
+
else {
|
|
1995
|
+
send({ type: 'turn_status', conversationId: m.conversationId, status: 'unknown', isProcessing: false, isCompacting: false, stateVersion: 0 });
|
|
1996
|
+
}
|
|
1770
1997
|
}
|
|
1771
1998
|
}
|
|
1772
1999
|
}
|
|
@@ -1967,6 +2194,20 @@ function handleServerMessage(msg) {
|
|
|
1967
2194
|
setBackendType(newBackendType);
|
|
1968
2195
|
console.log(`[AgentLink] Backend switched: ${oldBackendType} → ${newBackendType}`);
|
|
1969
2196
|
}
|
|
2197
|
+
else if (oldBackendType === 'yeaft') {
|
|
2198
|
+
const existingYeaftConv = conversationId ? getYeaftConversation(conversationId) : undefined;
|
|
2199
|
+
if (existingYeaftConv?.turnActive) {
|
|
2200
|
+
existingYeaftConv.providerId = providerId;
|
|
2201
|
+
}
|
|
2202
|
+
else if (conversationId && existingYeaftConv) {
|
|
2203
|
+
const result = restartYeaftConversation(conversationId, { providerId });
|
|
2204
|
+
if (result.wasTurnActive)
|
|
2205
|
+
send({ type: 'execution_cancelled', conversationId });
|
|
2206
|
+
}
|
|
2207
|
+
else if (conversationId) {
|
|
2208
|
+
createYeaftPlaceholder(conversationId, { providerId });
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
1970
2211
|
else if (oldBackendType === 'pi') {
|
|
1971
2212
|
const existingPiConversation = conversationId ? getPiConversation(conversationId) : undefined;
|
|
1972
2213
|
if (existingPiConversation?.turnActive) {
|
|
@@ -2032,14 +2273,14 @@ function handleServerMessage(msg) {
|
|
|
2032
2273
|
}
|
|
2033
2274
|
}
|
|
2034
2275
|
send({ type: 'provider_changed', providerId, conversationId });
|
|
2035
|
-
//
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
}
|
|
2276
|
+
// Capabilities are provider-scoped: wrappers and custom providers can
|
|
2277
|
+
// share a backend while exposing different command discovery behavior.
|
|
2278
|
+
send({
|
|
2279
|
+
type: 'backend_info',
|
|
2280
|
+
backend: newBackendType,
|
|
2281
|
+
providerId,
|
|
2282
|
+
capabilities: capabilitiesForBackend(newBackendType, providerId),
|
|
2283
|
+
});
|
|
2043
2284
|
break;
|
|
2044
2285
|
}
|
|
2045
2286
|
case 'list_providers': {
|
|
@@ -2050,7 +2291,8 @@ function handleServerMessage(msg) {
|
|
|
2050
2291
|
send({
|
|
2051
2292
|
type: 'backend_info',
|
|
2052
2293
|
backend: getBackendType(),
|
|
2053
|
-
|
|
2294
|
+
providerId: defaultId,
|
|
2295
|
+
capabilities: capabilitiesForBackend(getBackendType(), defaultId),
|
|
2054
2296
|
});
|
|
2055
2297
|
break;
|
|
2056
2298
|
}
|
|
@@ -2673,6 +2915,45 @@ function handleListCodexSessionsFn(dir, options = {}) {
|
|
|
2673
2915
|
});
|
|
2674
2916
|
}
|
|
2675
2917
|
}
|
|
2918
|
+
function handleListYeaftSessionsFn(dir, options = {}) {
|
|
2919
|
+
try {
|
|
2920
|
+
const page = options.legacy
|
|
2921
|
+
? { ...listYeaftSessionsPage(dir, { limit: Number.POSITIVE_INFINITY }), hasMore: false }
|
|
2922
|
+
: listYeaftSessionsPage(dir, {
|
|
2923
|
+
limit: options.limit ?? DEFAULT_SESSION_LIST_LIMIT,
|
|
2924
|
+
cursor: options.cursor,
|
|
2925
|
+
});
|
|
2926
|
+
if (options.legacy && page.sessions.length > LEGACY_SESSION_LIST_CAP) {
|
|
2927
|
+
page.sessions = page.sessions.slice(0, LEGACY_SESSION_LIST_CAP);
|
|
2928
|
+
}
|
|
2929
|
+
console.log(`[AgentLink] → sessions_list (${page.sessions.length} Yeaft sessions for ${dir}) hasMore=${page.hasMore}`);
|
|
2930
|
+
send({
|
|
2931
|
+
type: 'sessions_list',
|
|
2932
|
+
sessions: page.sessions,
|
|
2933
|
+
workDir: dir,
|
|
2934
|
+
hasMore: page.hasMore,
|
|
2935
|
+
nextCursor: page.nextCursor,
|
|
2936
|
+
indexState: 'ready',
|
|
2937
|
+
...(options.mode ? { mode: options.mode } : {}),
|
|
2938
|
+
...(options.requestId ? { requestId: options.requestId } : {}),
|
|
2939
|
+
providerId: options.providerId || 'yeaft',
|
|
2940
|
+
});
|
|
2941
|
+
}
|
|
2942
|
+
catch (err) {
|
|
2943
|
+
console.error('[AgentLink] listYeaftSessions failed:', err);
|
|
2944
|
+
send({
|
|
2945
|
+
type: 'sessions_list',
|
|
2946
|
+
sessions: [],
|
|
2947
|
+
workDir: dir,
|
|
2948
|
+
hasMore: false,
|
|
2949
|
+
indexState: 'ready',
|
|
2950
|
+
error: err.message,
|
|
2951
|
+
...(options.mode ? { mode: options.mode } : {}),
|
|
2952
|
+
...(options.requestId ? { requestId: options.requestId } : {}),
|
|
2953
|
+
providerId: options.providerId || 'yeaft',
|
|
2954
|
+
});
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2676
2957
|
function handleListPiSessionsFn(dir, options = {}) {
|
|
2677
2958
|
try {
|
|
2678
2959
|
const page = options.legacy
|