tycono 0.3.28 → 0.3.30
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/package.json
CHANGED
|
@@ -425,14 +425,14 @@ Examples:
|
|
|
425
425
|
// New turn starts — flush accumulated text from previous turn
|
|
426
426
|
if (e.type === 'msg:start') {
|
|
427
427
|
if (currentText.trim()) {
|
|
428
|
-
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0,
|
|
428
|
+
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0, 500) });
|
|
429
429
|
currentText = '';
|
|
430
430
|
}
|
|
431
431
|
// Extract CEO directive
|
|
432
432
|
const task = String(e.data.task ?? '');
|
|
433
433
|
const match = task.match(/\[CEO (?:Supervisor|Question)\]\s*(.*?)(?:\n|$)/);
|
|
434
434
|
if (match) {
|
|
435
|
-
exchanges.push({ role: 'ceo', text: match[1].slice(0,
|
|
435
|
+
exchanges.push({ role: 'ceo', text: match[1].slice(0, 200) });
|
|
436
436
|
}
|
|
437
437
|
}
|
|
438
438
|
// Accumulate supervisor response text
|
|
@@ -445,27 +445,27 @@ Examples:
|
|
|
445
445
|
// Turn boundary — flush
|
|
446
446
|
if (e.type === 'msg:done' || e.type === 'msg:awaiting_input' || e.type === 'msg:error') {
|
|
447
447
|
if (currentText.trim()) {
|
|
448
|
-
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0,
|
|
448
|
+
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0, 500) });
|
|
449
449
|
currentText = '';
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
452
|
}
|
|
453
453
|
// Flush any remaining text
|
|
454
454
|
if (currentText.trim()) {
|
|
455
|
-
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0,
|
|
455
|
+
exchanges.push({ role: 'supervisor', text: currentText.trim().slice(0, 500) });
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
|
|
459
459
|
if (exchanges.length === 0) return '';
|
|
460
460
|
|
|
461
|
-
// Keep last
|
|
462
|
-
const recent = exchanges.slice(-
|
|
461
|
+
// Keep last 10 exchanges (5 Q&A pairs), cap total at 3000 chars
|
|
462
|
+
const recent = exchanges.slice(-10);
|
|
463
463
|
const formatted = recent.map(e =>
|
|
464
464
|
e.role === 'ceo' ? `CEO: "${e.text}"` : `→ ${e.text}`
|
|
465
465
|
).join('\n');
|
|
466
466
|
|
|
467
|
-
const result = formatted.length >
|
|
468
|
-
? `\n[Previous conversation]\n${formatted.slice(-
|
|
467
|
+
const result = formatted.length > 3000
|
|
468
|
+
? `\n[Previous conversation]\n${formatted.slice(-3000)}\n`
|
|
469
469
|
: `\n[Previous conversation]\n${formatted}\n`;
|
|
470
470
|
console.log(`[WaveHistory] Result (${result.length} chars): ${result.slice(0, 200)}`);
|
|
471
471
|
return result;
|
|
@@ -484,41 +484,53 @@ Examples:
|
|
|
484
484
|
// If no in-memory history, load from disk (restart case)
|
|
485
485
|
const diskHistory = !directiveHistory ? this.loadWaveHistory(state.waveId) : '';
|
|
486
486
|
|
|
487
|
-
//
|
|
488
|
-
|
|
489
|
-
|
|
487
|
+
// Save last execution's full output to a temp file so conversation CEO can read it.
|
|
488
|
+
// No truncation — CEO reads the file for full context instead of getting a sliced summary.
|
|
489
|
+
let contextFilePath = '';
|
|
490
490
|
const sessionIdToCheck = state.supervisorSessionId
|
|
491
491
|
|| listSessions().find(s => s.waveId === state.waveId && s.roleId === 'ceo')?.id;
|
|
492
492
|
if (sessionIdToCheck) {
|
|
493
493
|
try {
|
|
494
494
|
const events = ActivityStream.readAll(sessionIdToCheck);
|
|
495
|
-
// Get last text outputs (the supervisor's final response)
|
|
496
495
|
const textEvents = events.filter(e => e.type === 'text' && e.roleId === 'ceo');
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
const name = (e.data.name as string) ?? '';
|
|
502
|
-
const inp = e.data.input as Record<string, unknown> | undefined;
|
|
503
|
-
const detail = inp?.file_path ?? inp?.command ?? '';
|
|
504
|
-
return ` → ${name} ${String(detail).slice(0, 60)}`;
|
|
505
|
-
}).join('\n');
|
|
506
|
-
|
|
507
|
-
const lastText = textEvents.slice(-5).map(e => String(e.data.text ?? '')).join('').slice(-500);
|
|
508
|
-
|
|
509
|
-
if (toolSummary || lastText) {
|
|
510
|
-
lastExecutionSummary = `\n[Previous execution in this wave]\nTools used:\n${toolSummary}\n\nLast response:\n${lastText.slice(0, 500)}\n`;
|
|
496
|
+
const fullText = textEvents.map(e => String(e.data.text ?? '')).join('\n').trim();
|
|
497
|
+
if (fullText) {
|
|
498
|
+
contextFilePath = path.join(COMPANY_ROOT, '.tycono', `conversation-context-${state.waveId}.md`);
|
|
499
|
+
fs.writeFileSync(contextFilePath, `# Previous CEO Response (Wave ${state.waveId})\n\n${fullText}\n`);
|
|
511
500
|
}
|
|
512
501
|
} catch { /* ignore */ }
|
|
513
502
|
}
|
|
514
503
|
|
|
515
|
-
|
|
504
|
+
// Build a compact pointer — what was done, where to look
|
|
505
|
+
const contextPointer = contextFilePath
|
|
506
|
+
? `\n[Previous execution output saved to: ${contextFilePath}]\nRead this file for full context before answering.\n`
|
|
507
|
+
: '';
|
|
508
|
+
const context = [directiveHistory || diskHistory, contextPointer].filter(Boolean).join('\n');
|
|
509
|
+
|
|
510
|
+
// Also find files created/modified in this wave
|
|
511
|
+
let waveArtifacts = '';
|
|
512
|
+
try {
|
|
513
|
+
const waveFile = path.join(COMPANY_ROOT, 'operations', 'waves', `${state.waveId}.json`);
|
|
514
|
+
if (fs.existsSync(waveFile)) {
|
|
515
|
+
const waveData = JSON.parse(fs.readFileSync(waveFile, 'utf-8'));
|
|
516
|
+
const files = waveData.roles?.flatMap((r: { artifacts?: string[] }) => r.artifacts ?? []) ?? [];
|
|
517
|
+
if (files.length > 0) {
|
|
518
|
+
waveArtifacts = `\n[Files created/modified in this wave]:\n${files.slice(0, 20).map((f: string) => ` - ${f}`).join('\n')}\n`;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
} catch { /* ignore */ }
|
|
522
|
+
|
|
523
|
+
const task = `${context}${waveArtifacts}
|
|
524
|
+
[CEO Question] ${directive}
|
|
516
525
|
|
|
517
|
-
|
|
526
|
+
You are the CEO Supervisor responding to the CEO's follow-up question.
|
|
518
527
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
528
|
+
## Rules
|
|
529
|
+
1. **READ the context file above** before answering. It contains the full previous response — don't guess.
|
|
530
|
+
2. **READ wave artifact files** if they exist — they contain the team's deliverables (reports, analysis).
|
|
531
|
+
3. **Be concrete.** Use actual data, numbers, quotes from the documents. The CEO wants substance, not metadata.
|
|
532
|
+
4. Do NOT dispatch anyone. Do NOT create new files. This is a conversation.
|
|
533
|
+
5. Answer in the same language the CEO used.`;
|
|
522
534
|
|
|
523
535
|
// Reuse session
|
|
524
536
|
let sessionId = state.supervisorSessionId;
|