morpheus-cli 0.6.1 → 0.6.2
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.
|
@@ -88,12 +88,11 @@ export class ChronosWorker {
|
|
|
88
88
|
session_id: activeSessionId,
|
|
89
89
|
});
|
|
90
90
|
try {
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
await this.oracle.injectAIMessage(contextMessage);
|
|
91
|
+
// Prefix the job prompt with the Chronos execution context marker so the
|
|
92
|
+
// Oracle system prompt can detect it in the current HumanMessage.
|
|
93
|
+
// This avoids persisting an AIMessage with the marker in conversation history,
|
|
94
|
+
// which would cause the LLM to reproduce the format in future scheduling responses.
|
|
95
|
+
const promptWithContext = `[CHRONOS EXECUTION — job_id: ${job.id}]\n${job.prompt}`;
|
|
97
96
|
// If a Telegram notify function is registered, tag delegated tasks with
|
|
98
97
|
// origin_channel: 'telegram' so the TaskDispatcher broadcasts their result.
|
|
99
98
|
const taskContext = ChronosWorker.notifyFn
|
|
@@ -101,7 +100,7 @@ export class ChronosWorker {
|
|
|
101
100
|
: undefined;
|
|
102
101
|
// Hard-block Chronos management tools during execution.
|
|
103
102
|
ChronosWorker.isExecuting = true;
|
|
104
|
-
const response = await this.oracle.chat(
|
|
103
|
+
const response = await this.oracle.chat(promptWithContext, undefined, false, taskContext);
|
|
105
104
|
this.repo.completeExecution(execId, 'success');
|
|
106
105
|
display.log(`Job ${job.id} completed — status: success`, { source: 'Chronos' });
|
|
107
106
|
// Deliver Oracle response to notification channels.
|
package/dist/runtime/oracle.js
CHANGED
|
@@ -114,6 +114,20 @@ export class Oracle {
|
|
|
114
114
|
}
|
|
115
115
|
return false;
|
|
116
116
|
}
|
|
117
|
+
hasChronosToolCall(messages) {
|
|
118
|
+
const chronosToolNames = new Set(["chronos_schedule", "chronos_list", "chronos_cancel", "chronos_preview"]);
|
|
119
|
+
for (const msg of messages) {
|
|
120
|
+
if (!(msg instanceof AIMessage))
|
|
121
|
+
continue;
|
|
122
|
+
const toolCalls = msg.tool_calls ?? [];
|
|
123
|
+
if (!Array.isArray(toolCalls))
|
|
124
|
+
continue;
|
|
125
|
+
if (toolCalls.some((tc) => chronosToolNames.has(tc?.name))) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
117
131
|
async initialize() {
|
|
118
132
|
if (!this.config.llm) {
|
|
119
133
|
throw new Error("LLM configuration missing in config object.");
|
|
@@ -198,6 +212,17 @@ Rules:
|
|
|
198
212
|
10. After enqueuing all required delegated tasks for the current message, stop calling tools and return a concise acknowledgement.
|
|
199
213
|
11. If a delegation is rejected as "not atomic", immediately split into smaller delegations and retry.
|
|
200
214
|
|
|
215
|
+
## Chronos Scheduled Execution
|
|
216
|
+
When the current user message starts with [CHRONOS EXECUTION], it means a Chronos scheduled job has just fired. The content after the prefix is the **job's saved prompt**, not a new live request from the user.
|
|
217
|
+
|
|
218
|
+
Behavior rules for Chronos execution context:
|
|
219
|
+
- **Reminder / notification prompts** (e.g., "me lembre de beber água", "lembre de tomar remédio", "avise que é hora de X", "lembrete: reunião às 15h"): respond with ONLY a short, direct notification message. Keep it to 1–2 sentences max. Do NOT use any tools. Do NOT delegate. Do NOT create tasks. Do NOT add motivational commentary or ask follow-up questions.
|
|
220
|
+
- Good: "Hora de beber água! 💧"
|
|
221
|
+
- Good: "Lembrete: reunião em 5 minutos."
|
|
222
|
+
- Bad: "Combinado! Vou beber agora. Você também deveria se hidratar!" (adds unnecessary commentary)
|
|
223
|
+
- **Action / task prompts** (e.g., "executar npm build", "verificar se o servidor está online", "enviar relatório"): execute normally using the appropriate tools.
|
|
224
|
+
- NEVER re-schedule or create new Chronos jobs from within a Chronos execution.
|
|
225
|
+
|
|
201
226
|
Delegation quality:
|
|
202
227
|
- Write delegation input in the same language requested by the user.
|
|
203
228
|
- Include clear objective and constraints.
|
|
@@ -294,6 +319,7 @@ Use it to inform your response and tool selection (if needed), but do not assume
|
|
|
294
319
|
let responseContent;
|
|
295
320
|
const toolDelegationAcks = this.extractDelegationAcksFromMessages(newGeneratedMessages);
|
|
296
321
|
const hadDelegationToolCall = this.hasDelegationToolCall(newGeneratedMessages);
|
|
322
|
+
const hadChronosToolCall = this.hasChronosToolCall(newGeneratedMessages);
|
|
297
323
|
const mergedDelegationAcks = [
|
|
298
324
|
...contextDelegationAcks.map((ack) => ({ task_id: ack.task_id, agent: ack.agent })),
|
|
299
325
|
...toolDelegationAcks,
|
|
@@ -336,7 +362,7 @@ Use it to inform your response and tool selection (if needed), but do not assume
|
|
|
336
362
|
else {
|
|
337
363
|
const lastMessage = response.messages[response.messages.length - 1];
|
|
338
364
|
responseContent = (typeof lastMessage.content === 'string') ? lastMessage.content : JSON.stringify(lastMessage.content);
|
|
339
|
-
if (this.looksLikeSyntheticDelegationAck(responseContent)) {
|
|
365
|
+
if (!hadChronosToolCall && this.looksLikeSyntheticDelegationAck(responseContent)) {
|
|
340
366
|
blockedSyntheticDelegationAck = true;
|
|
341
367
|
this.display.log("Blocked synthetic delegation acknowledgement without validated task creation.", { source: "Oracle", level: "error", meta: { preview: responseContent.slice(0, 200) } });
|
|
342
368
|
const usage = lastMessage.usage_metadata
|
|
@@ -11,8 +11,7 @@ Neo built-in capabilities (always available — no MCP required):
|
|
|
11
11
|
• Analytics: message_count, token_usage, provider_model_usage — message counts and token/cost usage stats
|
|
12
12
|
• Tasks: task_query — look up task status by id or session
|
|
13
13
|
• MCP Management: mcp_list, mcp_manage — list/add/update/delete/enable/disable MCP servers; use action "reload" to reload tools across all agents after config changes
|
|
14
|
-
• Webhooks: webhook_list, webhook_manage — create/update/delete webhooks; create returns api_key
|
|
15
|
-
• Trinity DB: trinity_db_list, trinity_db_manage — register/update/delete/test connection/refresh schema for databases`.trim();
|
|
14
|
+
• Webhooks: webhook_list, webhook_manage — create/update/delete webhooks; create returns api_key`.trim();
|
|
16
15
|
const NEO_BASE_DESCRIPTION = `Delegate execution to Neo asynchronously.
|
|
17
16
|
|
|
18
17
|
This tool creates a background task and returns an acknowledgement with task id.
|
|
@@ -29,7 +28,7 @@ function buildCatalogSection(mcpTools) {
|
|
|
29
28
|
if (mcpTools.length === 0) {
|
|
30
29
|
return "\n\nRuntime MCP tools: none currently loaded.";
|
|
31
30
|
}
|
|
32
|
-
const maxItems =
|
|
31
|
+
const maxItems = 500;
|
|
33
32
|
const lines = mcpTools.slice(0, maxItems).map((t) => {
|
|
34
33
|
const desc = normalizeDescription(t.description).slice(0, 120);
|
|
35
34
|
return `- ${t.name}: ${desc}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "morpheus-cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Morpheus is a local AI agent for developers, running as a CLI daemon that connects to LLMs, local tools, and MCPs, enabling interaction via Terminal, Telegram, and Discord. Inspired by the character Morpheus from *The Matrix*, the project acts as an intelligent orchestrator, bridging the gap between the developer and complex systems.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"morpheus": "./bin/morpheus.js"
|