@siftd/connect-agent 0.2.55 → 0.2.57
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/orchestrator.d.ts +3 -0
- package/dist/orchestrator.js +71 -15
- package/package.json +1 -1
package/dist/orchestrator.d.ts
CHANGED
|
@@ -75,6 +75,7 @@ export declare class MasterOrchestrator {
|
|
|
75
75
|
private initialized;
|
|
76
76
|
private currentFileScope;
|
|
77
77
|
private forceTeamWorkingDir;
|
|
78
|
+
private recentFileWrites;
|
|
78
79
|
private bashTool;
|
|
79
80
|
private webTools;
|
|
80
81
|
private workerTools;
|
|
@@ -210,6 +211,8 @@ export declare class MasterOrchestrator {
|
|
|
210
211
|
private getFileScopeOverrides;
|
|
211
212
|
private rewriteFilesAlias;
|
|
212
213
|
private resolveFilesWritePath;
|
|
214
|
+
private toFilesVirtualPath;
|
|
215
|
+
private finalizeResponse;
|
|
213
216
|
private getFileScopeSystemNote;
|
|
214
217
|
/**
|
|
215
218
|
* Check if verbose mode is enabled
|
package/dist/orchestrator.js
CHANGED
|
@@ -258,6 +258,7 @@ export class MasterOrchestrator {
|
|
|
258
258
|
initialized = false;
|
|
259
259
|
currentFileScope = 'personal';
|
|
260
260
|
forceTeamWorkingDir = false;
|
|
261
|
+
recentFileWrites = [];
|
|
261
262
|
// New tools from whatsapp-claude
|
|
262
263
|
bashTool;
|
|
263
264
|
webTools;
|
|
@@ -721,9 +722,14 @@ export class MasterOrchestrator {
|
|
|
721
722
|
return lines.join('\n');
|
|
722
723
|
}
|
|
723
724
|
stripTodoSnapshot(message) {
|
|
724
|
-
const
|
|
725
|
-
const
|
|
726
|
-
|
|
725
|
+
const markers = ['\n\nTODO SNAPSHOT', '\n\nRECENT CONVERSATION'];
|
|
726
|
+
const indices = markers
|
|
727
|
+
.map((marker) => message.indexOf(marker))
|
|
728
|
+
.filter((index) => index !== -1);
|
|
729
|
+
if (indices.length === 0)
|
|
730
|
+
return message;
|
|
731
|
+
const earliest = Math.min(...indices);
|
|
732
|
+
return message.slice(0, earliest);
|
|
727
733
|
}
|
|
728
734
|
hasTodoMutation(message) {
|
|
729
735
|
const lower = this.stripTodoSnapshot(message).toLowerCase();
|
|
@@ -932,6 +938,52 @@ export class MasterOrchestrator {
|
|
|
932
938
|
}
|
|
933
939
|
return resolved;
|
|
934
940
|
}
|
|
941
|
+
toFilesVirtualPath(rawPath, resolvedPath) {
|
|
942
|
+
const trimmed = rawPath.trim();
|
|
943
|
+
if (!trimmed)
|
|
944
|
+
return '/files';
|
|
945
|
+
const lower = trimmed.toLowerCase();
|
|
946
|
+
if (lower.startsWith('/files')) {
|
|
947
|
+
const suffix = trimmed.slice('/files'.length).replace(/\\/g, '/');
|
|
948
|
+
return `/files${suffix}`;
|
|
949
|
+
}
|
|
950
|
+
if (lower.startsWith('files/')) {
|
|
951
|
+
const suffix = trimmed.slice('files'.length).replace(/\\/g, '/');
|
|
952
|
+
return `/files${suffix}`;
|
|
953
|
+
}
|
|
954
|
+
if (trimmed.startsWith('/')) {
|
|
955
|
+
const teamDir = this.currentFileScope === 'team' ? this.getTeamFilesDir() : null;
|
|
956
|
+
const baseDir = teamDir || getSharedOutputPath();
|
|
957
|
+
try {
|
|
958
|
+
const resolved = resolve(resolvedPath || trimmed);
|
|
959
|
+
const baseResolved = resolve(baseDir);
|
|
960
|
+
if (resolved === baseResolved)
|
|
961
|
+
return '/files';
|
|
962
|
+
if (resolved.startsWith(`${baseResolved}${sep}`)) {
|
|
963
|
+
const rel = resolved.slice(baseResolved.length + 1).replace(/\\/g, '/');
|
|
964
|
+
return `/files/${rel}`;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
catch {
|
|
968
|
+
return '/files';
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
const cleaned = trimmed.replace(/^\/+/, '').replace(/^files\/?/i, '');
|
|
972
|
+
return cleaned ? `/files/${cleaned}` : '/files';
|
|
973
|
+
}
|
|
974
|
+
finalizeResponse(text) {
|
|
975
|
+
const trimmed = text.trim();
|
|
976
|
+
if (this.recentFileWrites.length === 0)
|
|
977
|
+
return trimmed || text;
|
|
978
|
+
const uniquePaths = Array.from(new Set(this.recentFileWrites));
|
|
979
|
+
const confirmation = uniquePaths.length === 1
|
|
980
|
+
? `Saved ${uniquePaths[0]}.`
|
|
981
|
+
: `Saved files:\n${uniquePaths.map((path) => `- ${path}`).join('\n')}`;
|
|
982
|
+
if (!trimmed)
|
|
983
|
+
return confirmation;
|
|
984
|
+
const mentionsPath = uniquePaths.some((path) => trimmed.includes(path)) || /\/files\b/i.test(trimmed);
|
|
985
|
+
return mentionsPath ? trimmed : `${trimmed}\n\n${confirmation}`;
|
|
986
|
+
}
|
|
935
987
|
getFileScopeSystemNote() {
|
|
936
988
|
if (this.currentFileScope !== 'team')
|
|
937
989
|
return null;
|
|
@@ -950,14 +1002,15 @@ export class MasterOrchestrator {
|
|
|
950
1002
|
* Process a user message
|
|
951
1003
|
*/
|
|
952
1004
|
async processMessage(message, conversationHistory = [], sendMessage) {
|
|
953
|
-
|
|
1005
|
+
const cleanMessage = this.stripTodoSnapshot(message);
|
|
1006
|
+
this.lastUserMessage = cleanMessage;
|
|
954
1007
|
// Handle slash commands first
|
|
955
|
-
const slashResponse = this.handleSlashCommand(
|
|
1008
|
+
const slashResponse = this.handleSlashCommand(cleanMessage);
|
|
956
1009
|
if (slashResponse) {
|
|
957
1010
|
return slashResponse;
|
|
958
1011
|
}
|
|
959
|
-
this.updateFileScope(
|
|
960
|
-
const wantsTodoOrCal = this.hasTodoMutation(
|
|
1012
|
+
this.updateFileScope(cleanMessage);
|
|
1013
|
+
const wantsTodoOrCal = this.hasTodoMutation(cleanMessage) || this.hasCalendarMutation(cleanMessage);
|
|
961
1014
|
if (wantsTodoOrCal) {
|
|
962
1015
|
this.attachmentContext = this.extractAttachmentContext(message);
|
|
963
1016
|
const toolMessages = [{ role: 'user', content: message }];
|
|
@@ -979,11 +1032,11 @@ export class MasterOrchestrator {
|
|
|
979
1032
|
// return quickWrite;
|
|
980
1033
|
// }
|
|
981
1034
|
// Load hub context (AGENTS.md identity, LANDMARKS.md state, project bio if relevant)
|
|
982
|
-
const hubContext = loadHubContext(
|
|
1035
|
+
const hubContext = loadHubContext(cleanMessage);
|
|
983
1036
|
const hubContextStr = formatHubContext(hubContext);
|
|
984
1037
|
this.attachmentContext = this.extractAttachmentContext(message);
|
|
985
1038
|
// Build context from memory
|
|
986
|
-
const memoryContext = await this.getMemoryContext(
|
|
1039
|
+
const memoryContext = await this.getMemoryContext(cleanMessage);
|
|
987
1040
|
// Build system prompt with hub context, genesis knowledge, and memory context
|
|
988
1041
|
const genesisKnowledge = getKnowledgeForPrompt();
|
|
989
1042
|
let systemWithContext = SYSTEM_PROMPT;
|
|
@@ -1021,11 +1074,11 @@ ${hubContextStr}
|
|
|
1021
1074
|
try {
|
|
1022
1075
|
const response = await this.runAgentLoop(messages, systemWithContext, sendMessage);
|
|
1023
1076
|
// Auto-remember important things from the conversation
|
|
1024
|
-
await this.autoRemember(
|
|
1025
|
-
void this.autoCaptureContext(
|
|
1077
|
+
await this.autoRemember(cleanMessage, response);
|
|
1078
|
+
void this.autoCaptureContext(cleanMessage);
|
|
1026
1079
|
// Log significant actions to hub
|
|
1027
1080
|
if (response.length > 100) {
|
|
1028
|
-
const action =
|
|
1081
|
+
const action = cleanMessage.length > 50 ? cleanMessage.slice(0, 50) + '...' : cleanMessage;
|
|
1029
1082
|
logAction(action, hubContext.projectName || undefined, `Response: ${response.length} chars`);
|
|
1030
1083
|
}
|
|
1031
1084
|
return response;
|
|
@@ -1448,6 +1501,7 @@ ${hubContextStr}
|
|
|
1448
1501
|
const forcedToolChoice = this.getToolChoice(currentMessages);
|
|
1449
1502
|
let retriedForcedTool = false;
|
|
1450
1503
|
let retriedTodoCal = false;
|
|
1504
|
+
this.recentFileWrites = [];
|
|
1451
1505
|
while (iterations < maxIterations) {
|
|
1452
1506
|
iterations++;
|
|
1453
1507
|
const toolChoice = forcedToolChoice ?? this.getToolChoice(currentMessages);
|
|
@@ -1510,7 +1564,7 @@ ${hubContextStr}
|
|
|
1510
1564
|
];
|
|
1511
1565
|
continue;
|
|
1512
1566
|
}
|
|
1513
|
-
return this.extractText(response.content);
|
|
1567
|
+
return this.finalizeResponse(this.extractText(response.content));
|
|
1514
1568
|
}
|
|
1515
1569
|
const toolUseBlocks = response.content.filter((block) => block.type === 'tool_use');
|
|
1516
1570
|
const toolNames = toolUseBlocks.map((block) => block.name);
|
|
@@ -1548,7 +1602,7 @@ ${hubContextStr}
|
|
|
1548
1602
|
{ role: 'user', content: toolResults }
|
|
1549
1603
|
];
|
|
1550
1604
|
}
|
|
1551
|
-
return 'Maximum iterations reached.';
|
|
1605
|
+
return this.finalizeResponse('Maximum iterations reached.');
|
|
1552
1606
|
}
|
|
1553
1607
|
/**
|
|
1554
1608
|
* Get tool definitions for the orchestrator
|
|
@@ -2252,7 +2306,9 @@ Unlike lia_plan (internal only), this creates a VISIBLE todo list that appears i
|
|
|
2252
2306
|
const targetPath = this.resolveFilesWritePath(pathValue);
|
|
2253
2307
|
mkdirSync(dirname(targetPath), { recursive: true });
|
|
2254
2308
|
writeFileSync(targetPath, content, 'utf8');
|
|
2255
|
-
|
|
2309
|
+
const virtualPath = this.toFilesVirtualPath(pathValue, targetPath);
|
|
2310
|
+
this.recentFileWrites.push(virtualPath);
|
|
2311
|
+
result = { success: true, output: `Saved file to ${virtualPath}.` };
|
|
2256
2312
|
}
|
|
2257
2313
|
catch (error) {
|
|
2258
2314
|
const message = error instanceof Error ? error.message : String(error);
|