tycono 0.1.96-beta.32 → 0.1.96-beta.33
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
|
@@ -149,7 +149,15 @@ class SupervisorHeartbeat {
|
|
|
149
149
|
state.directive = text;
|
|
150
150
|
}
|
|
151
151
|
state.crashCount = 0;
|
|
152
|
-
|
|
152
|
+
|
|
153
|
+
// Dual Mode: Conversation vs Dispatch (code-level enforcement)
|
|
154
|
+
// If directive looks like a question/status check → spawn conversation mode
|
|
155
|
+
// If directive looks like a task → spawn full supervisor with dispatch tools
|
|
156
|
+
if (this.isConversationDirective(text)) {
|
|
157
|
+
this.spawnConversation(state, text);
|
|
158
|
+
} else {
|
|
159
|
+
this.scheduleRestart(state, 0);
|
|
160
|
+
}
|
|
153
161
|
}
|
|
154
162
|
|
|
155
163
|
return directive;
|
|
@@ -234,6 +242,93 @@ class SupervisorHeartbeat {
|
|
|
234
242
|
.filter(s => s.status === 'running' || s.status === 'starting' || s.status === 'restarting');
|
|
235
243
|
}
|
|
236
244
|
|
|
245
|
+
/* ─── Internal: Dual Mode ─────────────────── */
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Heuristic: is this directive a question/status check (conversation)
|
|
249
|
+
* or a work task (needs dispatch)?
|
|
250
|
+
*
|
|
251
|
+
* Conversation signals: question marks, status keywords, short length
|
|
252
|
+
* Dispatch signals: imperative verbs (만들어, 수정해, 구현해), long directives
|
|
253
|
+
*/
|
|
254
|
+
private isConversationDirective(text: string): boolean {
|
|
255
|
+
const t = text.trim();
|
|
256
|
+
|
|
257
|
+
// Short messages with question marks → conversation
|
|
258
|
+
if (t.includes('?') && t.length < 100) return true;
|
|
259
|
+
|
|
260
|
+
// Korean question patterns
|
|
261
|
+
const questionPatterns = [
|
|
262
|
+
/확인해/, /알려줘/, /보여줘/, /어때/, /뭐야/, /뭐지/, /뭘까/,
|
|
263
|
+
/상태/, /상황/, /진행/, /현재/, /어디/, /얼마/,
|
|
264
|
+
/what/i, /how.*going/i, /status/i, /check/i, /show/i, /tell/i,
|
|
265
|
+
];
|
|
266
|
+
if (questionPatterns.some(p => p.test(t))) return true;
|
|
267
|
+
|
|
268
|
+
// Long directives with action verbs → dispatch
|
|
269
|
+
const taskPatterns = [
|
|
270
|
+
/만들어/, /구현해/, /개발해/, /수정해/, /변경해/, /리팩토링/,
|
|
271
|
+
/설계해/, /작성해/, /배포해/, /테스트해/, /고쳐/,
|
|
272
|
+
/build/i, /create/i, /implement/i, /develop/i, /fix/i, /deploy/i, /refactor/i,
|
|
273
|
+
];
|
|
274
|
+
if (taskPatterns.some(p => p.test(t))) return false;
|
|
275
|
+
|
|
276
|
+
// Default: short → conversation, long → dispatch
|
|
277
|
+
return t.length < 60;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Spawn a lightweight conversation session (no dispatch tools).
|
|
282
|
+
* CEO reads files and answers directly.
|
|
283
|
+
*/
|
|
284
|
+
private spawnConversation(state: SupervisorState, directive: string): void {
|
|
285
|
+
// Build conversation context from previous directives
|
|
286
|
+
const deliveredDirectives = state.pendingDirectives.filter(d => d.delivered);
|
|
287
|
+
const history = deliveredDirectives.length > 0
|
|
288
|
+
? `\n[Previous conversation]\n${deliveredDirectives.map(d => `CEO: "${d.text}"`).join('\n')}\n`
|
|
289
|
+
: '';
|
|
290
|
+
|
|
291
|
+
const task = `${history}[CEO Question] ${directive}
|
|
292
|
+
|
|
293
|
+
You are the CEO's AI assistant. Answer this question directly by reading relevant files.
|
|
294
|
+
Do NOT dispatch anyone. Do NOT start any work. Just read, analyze, and answer.
|
|
295
|
+
Keep your response concise and informative.`;
|
|
296
|
+
|
|
297
|
+
// Reuse session
|
|
298
|
+
let sessionId = state.supervisorSessionId;
|
|
299
|
+
if (!sessionId || !getSession(sessionId)) {
|
|
300
|
+
const session = createSession('ceo', {
|
|
301
|
+
mode: 'do',
|
|
302
|
+
source: 'wave',
|
|
303
|
+
waveId: state.waveId,
|
|
304
|
+
});
|
|
305
|
+
sessionId = session.id;
|
|
306
|
+
state.supervisorSessionId = sessionId;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
state.status = 'running';
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
const exec = executionManager.startExecution({
|
|
313
|
+
type: 'assign', // assign = no supervisor tools (dispatch/watch/amend)
|
|
314
|
+
roleId: 'ceo',
|
|
315
|
+
task,
|
|
316
|
+
sourceRole: 'ceo',
|
|
317
|
+
readOnly: true, // readOnly = no code changes, conversation only
|
|
318
|
+
sessionId,
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
state.executionId = exec.id;
|
|
322
|
+
this.watchExecution(state, exec);
|
|
323
|
+
|
|
324
|
+
console.log(`[Supervisor] Conversation mode for wave ${state.waveId} | directive: ${directive.slice(0, 60)}`);
|
|
325
|
+
} catch (err) {
|
|
326
|
+
console.error(`[Supervisor] Conversation spawn failed:`, err);
|
|
327
|
+
// Fallback to full supervisor
|
|
328
|
+
this.scheduleRestart(state, 0);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
237
332
|
/* ─── Internal: Spawn / Restart ────────────── */
|
|
238
333
|
|
|
239
334
|
private spawnSupervisor(state: SupervisorState): void {
|