@ducci/jarvis 1.0.50 → 1.0.52
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/docs/system-prompt.md +12 -2
- package/package.json +1 -1
- package/src/server/crons.js +54 -1
package/docs/system-prompt.md
CHANGED
|
@@ -25,6 +25,16 @@ Only the most recent messages are included in your context (sliding window). Old
|
|
|
25
25
|
|
|
26
26
|
Use `create_cron` when the user wants something scheduled — even without the word "cron". Common triggers: "every night", "every 2 hours", "remind me at 3pm", "notify me in 2 hours", "check X every Monday". See the `create_cron` and `get_current_time` tool descriptions for how to construct the schedule and prompt correctly.
|
|
27
27
|
|
|
28
|
+
## Subagents
|
|
29
|
+
|
|
30
|
+
Use `spawn_subagent` when a task involves multiple independent items that can be processed in parallel. Common triggers: "check all emails", "process these files", "summarize each of these URLs", "do X for every Y".
|
|
31
|
+
|
|
32
|
+
Rules:
|
|
33
|
+
- Spawn **all subagents in a single response** — never one at a time. They run in parallel; waiting defeats the purpose.
|
|
34
|
+
- Each subagent must receive a **fully self-contained prompt** with all context it needs (item content, goal, expected output format).
|
|
35
|
+
- Use subagents to **avoid context overflow**: processing 10+ items serially in one session bloats the context and risks hitting limits. Offload to subagents instead.
|
|
36
|
+
- After all subagents return, **aggregate their results** yourself and decide on the next step — whether that means further tool calls, a follow-up action, or reporting back to the user.
|
|
37
|
+
|
|
28
38
|
## Skills
|
|
29
39
|
|
|
30
40
|
Skills are predefined workflows that guide how you approach specific tasks. When a task matches a skill, load its full instructions with the `read_skill` tool before proceeding — do not guess the workflow from the description alone.
|
|
@@ -54,8 +64,8 @@ Never include markdown code fences, preamble, or any text outside this JSON obje
|
|
|
54
64
|
You have access to a set of tools. Each tool has a name and description that tells you what it does and when to use it — read those descriptions carefully.
|
|
55
65
|
|
|
56
66
|
- Always use a tool to perform an action. Never claim to have done something without actually calling the relevant tool.
|
|
57
|
-
- Call tools one at a time. You will receive the result before deciding on the next step.
|
|
58
|
-
- After a tool call, verify the result before
|
|
67
|
+
- Call tools one at a time. You will receive the result before deciding on the next step. Exception: when using `spawn_subagent` for bulk tasks (e.g. N emails, files, or items), spawn all subagents in a single response so they run in parallel — do not wait for one to finish before spawning the next.
|
|
68
|
+
- After a tool call, verify the result before proceeding. In your final response, explain what was done and why — do not just report success without evidence.
|
|
59
69
|
- Stop as soon as the task is complete and verified. Do not do extra work that was not asked for.
|
|
60
70
|
- If a tool fails, record the error in `logSummary` and decide whether to retry with a corrected call or explain the failure to the user.
|
|
61
71
|
- Proactively save user facts with `save_user_info` when the user shares personal details (name, timezone, preferences) — even if not asked.
|
package/package.json
CHANGED
package/src/server/crons.js
CHANGED
|
@@ -60,8 +60,61 @@ export async function runCron(entry, config) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
let run;
|
|
63
|
+
let handoffCount = 0;
|
|
64
|
+
let previousRemaining = null;
|
|
65
|
+
const failedApproaches = [];
|
|
66
|
+
const checkpointState = {};
|
|
67
|
+
|
|
63
68
|
try {
|
|
64
|
-
|
|
69
|
+
while (true) {
|
|
70
|
+
const runStartIndex = session.messages.length;
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
run = await runAgentLoop(client, config, session, prepareMessages, usageAccum);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
run = { status: 'error', response: e.message, logSummary: e.message, runToolCalls: [] };
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (run.status !== 'checkpoint_reached') break;
|
|
80
|
+
|
|
81
|
+
if (run.checkpoint.failedApproaches?.length > 0) {
|
|
82
|
+
failedApproaches.push(...run.checkpoint.failedApproaches);
|
|
83
|
+
}
|
|
84
|
+
if (run.checkpoint.state && Object.keys(run.checkpoint.state).length > 0) {
|
|
85
|
+
Object.assign(checkpointState, run.checkpoint.state);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Zero-progress detection
|
|
89
|
+
const currentRemaining = (run.checkpoint.remaining || '').trim();
|
|
90
|
+
if (previousRemaining !== null && currentRemaining === previousRemaining) {
|
|
91
|
+
run = { ...run, status: 'intervention_required', logSummary: 'Zero progress detected in cron run.' };
|
|
92
|
+
session.messages.splice(runStartIndex, session.messages.length - runStartIndex - 1);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
previousRemaining = currentRemaining;
|
|
96
|
+
|
|
97
|
+
// Max handoffs
|
|
98
|
+
handoffCount++;
|
|
99
|
+
if (handoffCount > config.maxHandoffs) {
|
|
100
|
+
run = { ...run, status: 'intervention_required', logSummary: 'Max handoffs exceeded in cron run.' };
|
|
101
|
+
session.messages.splice(runStartIndex, session.messages.length - runStartIndex - 1);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Strip intermediate tool history, keep wrap-up assistant response
|
|
106
|
+
session.messages.splice(runStartIndex, session.messages.length - runStartIndex - 1);
|
|
107
|
+
|
|
108
|
+
// Resume with checkpoint.remaining + accumulated context
|
|
109
|
+
let resumeContent = run.checkpoint.remaining || 'Continue with the task.';
|
|
110
|
+
if (failedApproaches.length > 0) {
|
|
111
|
+
resumeContent += `\n\n[System: The following approaches were tried and failed in previous runs — do not repeat them:\n${failedApproaches.map((a, i) => `${i + 1}. ${a}`).join('\n')}]`;
|
|
112
|
+
}
|
|
113
|
+
if (Object.keys(checkpointState).length > 0) {
|
|
114
|
+
resumeContent += `\n\n[System: Known facts from previous runs:\n${Object.entries(checkpointState).map(([k, v]) => `- ${k}: ${v}`).join('\n')}]`;
|
|
115
|
+
}
|
|
116
|
+
session.messages.push({ role: 'user', content: resumeContent });
|
|
117
|
+
}
|
|
65
118
|
} catch (e) {
|
|
66
119
|
run = { status: 'error', response: e.message, logSummary: e.message, runToolCalls: [] };
|
|
67
120
|
}
|