@siftd/connect-agent 0.2.53 → 0.2.55
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/agent.js +9 -2
- package/dist/orchestrator.js +48 -8
- package/package.json +1 -1
package/dist/agent.js
CHANGED
|
@@ -415,8 +415,15 @@ export async function runAgent(pollInterval = 2000) {
|
|
|
415
415
|
});
|
|
416
416
|
// Worker results - send to user when workers complete
|
|
417
417
|
orchestrator.setWorkerResultCallback((workerId, result) => {
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
const trimmed = result.trim();
|
|
419
|
+
const lower = trimmed.toLowerCase();
|
|
420
|
+
const shouldSuppress = !trimmed ||
|
|
421
|
+
trimmed === '(No output)' ||
|
|
422
|
+
lower.startsWith('worker timed out') ||
|
|
423
|
+
lower.startsWith('worker error') ||
|
|
424
|
+
lower.includes('partial output: none');
|
|
425
|
+
console.log(`[WORKER DONE] ${workerId}: ${trimmed.slice(0, 100)}${shouldSuppress ? ' (suppressed)' : ''}`);
|
|
426
|
+
if (!shouldSuppress && wsClient?.connected()) {
|
|
420
427
|
// Send as response with worker ID as message ID
|
|
421
428
|
wsClient.sendResponse(workerId, `**Worker completed:**\n\n${result}`);
|
|
422
429
|
}
|
package/dist/orchestrator.js
CHANGED
|
@@ -734,15 +734,18 @@ export class MasterOrchestrator {
|
|
|
734
734
|
}
|
|
735
735
|
hasCalendarMutation(message) {
|
|
736
736
|
const lower = this.stripTodoSnapshot(message).toLowerCase();
|
|
737
|
-
const target = /(^|\s)\/cal\b|\/calendar\b|\bcalendar\b|\bcal\b/.test(lower);
|
|
738
|
-
const action = /\b(add|create|schedule|book|move|reschedule|update|change|cancel|delete|remove)\b/.test(lower);
|
|
737
|
+
const target = /(^|\s)\/cal\b|\/calendar\b|\bcalendar\b|\bcal\b|\bschedule\b|\bagenda\b/.test(lower);
|
|
738
|
+
const action = /\b(add|create|schedule|book|move|reschedule|update|change|cancel|delete|remove|set|put|place|remind)\b/.test(lower);
|
|
739
|
+
const dateCue = /\b(today|tomorrow|tonight|next|this\s+(week|month|year)|mon(day)?|tue(sday)?|wed(nesday)?|thu(rsday)?|fri(day)?|sat(urday)?|sun(day)?|\b\d{1,2}(:\d{2})?\s?(am|pm)\b|\b\d{1,2}\/\d{1,2}\b|\b\d{4}-\d{2}-\d{2}\b)\b/.test(lower);
|
|
740
|
+
const eventCue = /\b(meeting|call|appointment|event|reminder|session|class|lecture|review|deadline)\b/.test(lower);
|
|
741
|
+
const implicitTarget = eventCue && dateCue;
|
|
739
742
|
const query = /\b(what|show|list|open|view|see)\b/.test(lower);
|
|
740
|
-
return target && action && !query;
|
|
743
|
+
return (target || implicitTarget) && action && !query;
|
|
741
744
|
}
|
|
742
745
|
hasFileMutation(message) {
|
|
743
746
|
const lower = this.stripTodoSnapshot(message).toLowerCase();
|
|
744
747
|
const target = /(^|\s)\/files\b|\bfiles?\b/.test(lower);
|
|
745
|
-
const action = /\b(create|make|write|save|generate|export|upload|attach|produce|edit|update|modify|delete|remove)\b/.test(lower);
|
|
748
|
+
const action = /\b(create|make|write|save|generate|export|upload|attach|produce|edit|update|modify|delete|remove|add|append|insert|include)\b/.test(lower);
|
|
746
749
|
const query = /\b(what|show|list|open|view|see|browse|find)\b/.test(lower);
|
|
747
750
|
return target && action && !query;
|
|
748
751
|
}
|
|
@@ -1422,9 +1425,9 @@ ${hubContextStr}
|
|
|
1422
1425
|
const toolsBase = this.getToolDefinitions();
|
|
1423
1426
|
const last = messages[messages.length - 1];
|
|
1424
1427
|
const lastContent = last && last.role === 'user' && typeof last.content === 'string' ? last.content : '';
|
|
1425
|
-
const
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
+
const requiredTodo = lastContent ? this.hasTodoMutation(lastContent) : false;
|
|
1429
|
+
const requiredCal = lastContent ? this.hasCalendarMutation(lastContent) : false;
|
|
1430
|
+
const restrictWorkers = requiredTodo || requiredCal;
|
|
1428
1431
|
const wantsTodoOrCal = restrictWorkers;
|
|
1429
1432
|
const todoCalTools = new Set(['calendar_upsert_events', 'todo_upsert_items']);
|
|
1430
1433
|
const blockedTools = new Set([
|
|
@@ -1444,6 +1447,7 @@ ${hubContextStr}
|
|
|
1444
1447
|
const requestTimeoutMs = 60000;
|
|
1445
1448
|
const forcedToolChoice = this.getToolChoice(currentMessages);
|
|
1446
1449
|
let retriedForcedTool = false;
|
|
1450
|
+
let retriedTodoCal = false;
|
|
1447
1451
|
while (iterations < maxIterations) {
|
|
1448
1452
|
iterations++;
|
|
1449
1453
|
const toolChoice = forcedToolChoice ?? this.getToolChoice(currentMessages);
|
|
@@ -1492,13 +1496,44 @@ ${hubContextStr}
|
|
|
1492
1496
|
];
|
|
1493
1497
|
continue;
|
|
1494
1498
|
}
|
|
1499
|
+
if (wantsTodoOrCal && !retriedTodoCal && (requiredTodo || requiredCal)) {
|
|
1500
|
+
retriedTodoCal = true;
|
|
1501
|
+
const required = [
|
|
1502
|
+
requiredTodo ? 'todo_upsert_items' : null,
|
|
1503
|
+
requiredCal ? 'calendar_upsert_events' : null
|
|
1504
|
+
].filter(Boolean).join(' and ');
|
|
1505
|
+
const followup = `You must call ${required} now. Do not spawn workers or call any other tools.`;
|
|
1506
|
+
currentMessages = [
|
|
1507
|
+
...currentMessages,
|
|
1508
|
+
{ role: 'assistant', content: response.content },
|
|
1509
|
+
{ role: 'user', content: followup }
|
|
1510
|
+
];
|
|
1511
|
+
continue;
|
|
1512
|
+
}
|
|
1495
1513
|
return this.extractText(response.content);
|
|
1496
1514
|
}
|
|
1497
1515
|
const toolUseBlocks = response.content.filter((block) => block.type === 'tool_use');
|
|
1498
1516
|
const toolNames = toolUseBlocks.map((block) => block.name);
|
|
1499
1517
|
// Process tool calls
|
|
1500
1518
|
const toolResults = await this.processToolCalls(response.content, sendMessage);
|
|
1501
|
-
|
|
1519
|
+
const missingTodo = requiredTodo && !toolNames.includes('todo_upsert_items');
|
|
1520
|
+
const missingCal = requiredCal && !toolNames.includes('calendar_upsert_events');
|
|
1521
|
+
if (wantsTodoOrCal && (missingTodo || missingCal) && !retriedTodoCal) {
|
|
1522
|
+
retriedTodoCal = true;
|
|
1523
|
+
const required = [
|
|
1524
|
+
missingTodo ? 'todo_upsert_items' : null,
|
|
1525
|
+
missingCal ? 'calendar_upsert_events' : null
|
|
1526
|
+
].filter(Boolean).join(' and ');
|
|
1527
|
+
const followup = `You must call ${required} now. Do not repeat tools already called. Do not spawn workers.`;
|
|
1528
|
+
currentMessages = [
|
|
1529
|
+
...currentMessages,
|
|
1530
|
+
{ role: 'assistant', content: response.content },
|
|
1531
|
+
{ role: 'user', content: toolResults },
|
|
1532
|
+
{ role: 'user', content: followup }
|
|
1533
|
+
];
|
|
1534
|
+
continue;
|
|
1535
|
+
}
|
|
1536
|
+
if (wantsTodoOrCal && !missingTodo && !missingCal) {
|
|
1502
1537
|
const updates = [];
|
|
1503
1538
|
if (toolNames.includes('todo_upsert_items'))
|
|
1504
1539
|
updates.push('Updated /todo.');
|
|
@@ -2209,6 +2244,11 @@ Unlike lia_plan (internal only), this creates a VISIBLE todo list that appears i
|
|
|
2209
2244
|
try {
|
|
2210
2245
|
const pathValue = String(input.path || '').trim();
|
|
2211
2246
|
const content = String(input.content || '');
|
|
2247
|
+
const allowEmpty = /\b(empty|blank|placeholder)\b/i.test(this.lastUserMessage || '');
|
|
2248
|
+
if (!content.trim() && !allowEmpty) {
|
|
2249
|
+
result = { success: false, output: '', error: 'Refusing to write empty file content.' };
|
|
2250
|
+
break;
|
|
2251
|
+
}
|
|
2212
2252
|
const targetPath = this.resolveFilesWritePath(pathValue);
|
|
2213
2253
|
mkdirSync(dirname(targetPath), { recursive: true });
|
|
2214
2254
|
writeFileSync(targetPath, content, 'utf8');
|