@runfusion/fusion 0.0.5 → 0.0.6
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/bin.js +244 -98
- package/dist/client/assets/{index-9GdD09x7.css → index-CYkQfLYV.css} +1 -1
- package/dist/client/assets/index-zTogbMzz.js +1241 -0
- package/dist/client/index.html +2 -2
- package/dist/extension.js +145 -82
- package/package.json +1 -1
- package/dist/client/assets/index-wtVkS5Qz.js +0 -1241
package/dist/client/index.html
CHANGED
|
@@ -78,11 +78,11 @@
|
|
|
78
78
|
}
|
|
79
79
|
})();
|
|
80
80
|
</script>
|
|
81
|
-
<script type="module" crossorigin src="/assets/index-
|
|
81
|
+
<script type="module" crossorigin src="/assets/index-zTogbMzz.js"></script>
|
|
82
82
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-K0fH_qHe.js">
|
|
83
83
|
<link rel="modulepreload" crossorigin href="/assets/vendor-xterm-DzcZoU0P.js">
|
|
84
84
|
<link rel="stylesheet" crossorigin href="/assets/vendor-xterm-LZoznX6r.css">
|
|
85
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
85
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CYkQfLYV.css">
|
|
86
86
|
</head>
|
|
87
87
|
<body>
|
|
88
88
|
<div id="root"></div>
|
package/dist/extension.js
CHANGED
|
@@ -133,6 +133,8 @@ var init_settings_schema = __esm({
|
|
|
133
133
|
defaultPresetBySize: {},
|
|
134
134
|
autoResolveConflicts: true,
|
|
135
135
|
smartConflictResolution: true,
|
|
136
|
+
worktreeRebaseBeforeMerge: true,
|
|
137
|
+
worktreeRebaseRemote: "",
|
|
136
138
|
strictScopeEnforcement: false,
|
|
137
139
|
buildRetryCount: 0,
|
|
138
140
|
verificationFixRetries: 1,
|
|
@@ -30548,6 +30550,7 @@ ${newTask.description}
|
|
|
30548
30550
|
}
|
|
30549
30551
|
}
|
|
30550
30552
|
if (updates.steps !== void 0) task.steps = updates.steps;
|
|
30553
|
+
if (updates.currentStep !== void 0) task.currentStep = updates.currentStep;
|
|
30551
30554
|
if (updates.status === null) {
|
|
30552
30555
|
task.status = void 0;
|
|
30553
30556
|
} else if (updates.status !== void 0) {
|
|
@@ -53420,6 +53423,71 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
|
|
|
53420
53423
|
mergerLog.warn(`${taskId}: unable to verify/checkout main branch \u2014 proceeding on current HEAD`);
|
|
53421
53424
|
}
|
|
53422
53425
|
}
|
|
53426
|
+
if (settings.worktreeRebaseBeforeMerge !== false) {
|
|
53427
|
+
try {
|
|
53428
|
+
let remote = settings.worktreeRebaseRemote?.trim();
|
|
53429
|
+
if (!remote) {
|
|
53430
|
+
try {
|
|
53431
|
+
const { stdout: mainBranchOut } = await execAsync2(
|
|
53432
|
+
"git rev-parse --abbrev-ref HEAD",
|
|
53433
|
+
{ cwd: rootDir, encoding: "utf-8" }
|
|
53434
|
+
);
|
|
53435
|
+
const mainBranch = mainBranchOut.trim();
|
|
53436
|
+
const { stdout: configuredRemote } = await execAsync2(
|
|
53437
|
+
`git config --get branch.${mainBranch}.remote`,
|
|
53438
|
+
{ cwd: rootDir, encoding: "utf-8" }
|
|
53439
|
+
).catch(() => ({ stdout: "" }));
|
|
53440
|
+
remote = configuredRemote.trim();
|
|
53441
|
+
} catch {
|
|
53442
|
+
}
|
|
53443
|
+
}
|
|
53444
|
+
if (!remote) {
|
|
53445
|
+
try {
|
|
53446
|
+
const { stdout: remotesOut } = await execAsync2("git remote", {
|
|
53447
|
+
cwd: rootDir,
|
|
53448
|
+
encoding: "utf-8"
|
|
53449
|
+
});
|
|
53450
|
+
const remotes = remotesOut.trim().split(/\s+/).filter(Boolean);
|
|
53451
|
+
if (remotes.length === 1) {
|
|
53452
|
+
remote = remotes[0];
|
|
53453
|
+
} else if (remotes.includes("origin")) {
|
|
53454
|
+
remote = "origin";
|
|
53455
|
+
}
|
|
53456
|
+
} catch {
|
|
53457
|
+
}
|
|
53458
|
+
}
|
|
53459
|
+
if (!remote) {
|
|
53460
|
+
mergerLog.log(`${taskId}: no remote resolvable \u2014 skipping pre-merge rebase`);
|
|
53461
|
+
} else {
|
|
53462
|
+
mergerLog.log(`${taskId}: fetching ${remote} before merge`);
|
|
53463
|
+
await execAsync2(`git fetch "${remote}"`, { cwd: rootDir });
|
|
53464
|
+
try {
|
|
53465
|
+
const { stdout: mainBranchOut } = await execAsync2(
|
|
53466
|
+
"git rev-parse --abbrev-ref HEAD",
|
|
53467
|
+
{ cwd: rootDir, encoding: "utf-8" }
|
|
53468
|
+
);
|
|
53469
|
+
const mainBranch = mainBranchOut.trim();
|
|
53470
|
+
const remoteRef = `${remote}/${mainBranch}`;
|
|
53471
|
+
if (worktreePath) {
|
|
53472
|
+
await execAsync2(`git rebase "${remoteRef}"`, { cwd: worktreePath });
|
|
53473
|
+
mergerLog.log(`${taskId}: rebased ${branch} onto ${remoteRef}`);
|
|
53474
|
+
} else {
|
|
53475
|
+
mergerLog.warn(`${taskId}: no worktreePath \u2014 skipping task branch rebase`);
|
|
53476
|
+
}
|
|
53477
|
+
} catch (rebaseErr) {
|
|
53478
|
+
const msg = rebaseErr instanceof Error ? rebaseErr.message : String(rebaseErr);
|
|
53479
|
+
mergerLog.warn(`${taskId}: pre-merge rebase failed (${msg}) \u2014 aborting rebase and falling through to smart/AI merge`);
|
|
53480
|
+
if (worktreePath) {
|
|
53481
|
+
await execAsync2("git rebase --abort", { cwd: worktreePath }).catch(() => {
|
|
53482
|
+
});
|
|
53483
|
+
}
|
|
53484
|
+
}
|
|
53485
|
+
}
|
|
53486
|
+
} catch (err) {
|
|
53487
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
53488
|
+
mergerLog.warn(`${taskId}: pre-merge rebase pipeline failed (${msg}) \u2014 proceeding without rebase`);
|
|
53489
|
+
}
|
|
53490
|
+
}
|
|
53423
53491
|
let commitLog = "";
|
|
53424
53492
|
let diffStat = "";
|
|
53425
53493
|
try {
|
|
@@ -55936,19 +56004,6 @@ import { existsSync as existsSync25 } from "node:fs";
|
|
|
55936
56004
|
import { readFile as readFile14, writeFile as writeFile11 } from "node:fs/promises";
|
|
55937
56005
|
import { Type as Type4 } from "@mariozechner/pi-ai";
|
|
55938
56006
|
import { ModelRegistry as ModelRegistry2, SessionManager as SessionManager2 } from "@mariozechner/pi-coding-agent";
|
|
55939
|
-
function determineRevisionResetStart(steps, feedback) {
|
|
55940
|
-
const total = steps.length;
|
|
55941
|
-
if (total === 0) return 0;
|
|
55942
|
-
const skipPreflight = /preflight/i.test(steps[0].name);
|
|
55943
|
-
const firstCandidate = skipPreflight ? 1 : 0;
|
|
55944
|
-
if (firstCandidate >= total) return total;
|
|
55945
|
-
const fb = feedback.toLowerCase();
|
|
55946
|
-
for (let i = firstCandidate; i < total; i++) {
|
|
55947
|
-
const tokens = steps[i].name.toLowerCase().match(/[a-z][a-z]{4,}/g) ?? [];
|
|
55948
|
-
if (tokens.some((t) => fb.includes(t))) return i;
|
|
55949
|
-
}
|
|
55950
|
-
return firstCandidate;
|
|
55951
|
-
}
|
|
55952
56007
|
function truncateWorkflowScriptOutput2(output) {
|
|
55953
56008
|
if (output.length <= WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS2) return output;
|
|
55954
56009
|
return `... output truncated to last ${WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS2} characters ...
|
|
@@ -58265,35 +58320,23 @@ Take a different approach. Do NOT repeat the rejected strategy. Re-read the step
|
|
|
58265
58320
|
}
|
|
58266
58321
|
/**
|
|
58267
58322
|
* Handle a workflow step revision request.
|
|
58268
|
-
*
|
|
58269
|
-
*
|
|
58270
|
-
*
|
|
58271
|
-
*
|
|
58272
|
-
*
|
|
58273
|
-
*
|
|
58274
|
-
* The task stays in "in-progress" and is scheduled for a fresh executor pass.
|
|
58323
|
+
*
|
|
58324
|
+
* Re-opens ONLY the last step so the executor has exactly one pending slot
|
|
58325
|
+
* to re-enter through. All earlier done steps stay done — the agent reads
|
|
58326
|
+
* the injected feedback from PROMPT.md and applies an in-place fix rather
|
|
58327
|
+
* than redoing any completed step.
|
|
58275
58328
|
*/
|
|
58276
58329
|
async handleWorkflowRevisionRequest(task, worktreePath, feedback, stepName) {
|
|
58277
58330
|
executorLog.log(`${task.id}: workflow revision requested by step "${stepName}"`);
|
|
58278
58331
|
const updatedTask = await this.store.getTask(task.id);
|
|
58279
|
-
const
|
|
58280
|
-
const
|
|
58281
|
-
const resetSummary = resetStart >= updatedTask.steps.length ? "no steps to reset" : `resetting steps ${resetStart + 1}\u2013${updatedTask.steps.length} (starting at "${targetStepName}")`;
|
|
58332
|
+
const reopen = await this.reopenLastStepForRevision(task.id, updatedTask);
|
|
58333
|
+
const reopenSummary = reopen ? `re-opening Step ${reopen.index + 1} ("${reopen.name}") for in-place fix` : "no step to re-open (none were completed)";
|
|
58282
58334
|
await this.store.logEntry(
|
|
58283
58335
|
task.id,
|
|
58284
|
-
`Workflow step "${stepName}" requested revision \u2014 ${
|
|
58336
|
+
`Workflow step "${stepName}" requested revision \u2014 ${reopenSummary}`,
|
|
58285
58337
|
feedback
|
|
58286
58338
|
);
|
|
58287
|
-
await this.injectWorkflowRevisionInstructions(task, feedback
|
|
58288
|
-
resetStart,
|
|
58289
|
-
targetStepName,
|
|
58290
|
-
totalSteps: updatedTask.steps.length
|
|
58291
|
-
});
|
|
58292
|
-
for (let i = resetStart; i < updatedTask.steps.length; i++) {
|
|
58293
|
-
if (updatedTask.steps[i].status !== "pending") {
|
|
58294
|
-
await this.store.updateStep(task.id, i, "pending");
|
|
58295
|
-
}
|
|
58296
|
-
}
|
|
58339
|
+
await this.injectWorkflowRevisionInstructions(task, feedback);
|
|
58297
58340
|
await this.store.updateTask(task.id, {
|
|
58298
58341
|
status: null,
|
|
58299
58342
|
sessionFile: null
|
|
@@ -58315,12 +58358,36 @@ Take a different approach. Do NOT repeat the rejected strategy. Re-read the step
|
|
|
58315
58358
|
}
|
|
58316
58359
|
}, 0);
|
|
58317
58360
|
}
|
|
58361
|
+
/**
|
|
58362
|
+
* Re-open the last non-pending step so a revision/failure handler gives the
|
|
58363
|
+
* executor exactly one pending slot to re-enter through. Returns the index
|
|
58364
|
+
* and name of the step that was flipped to `pending`, or null when there
|
|
58365
|
+
* was nothing to re-open.
|
|
58366
|
+
*/
|
|
58367
|
+
async reopenLastStepForRevision(taskId, task) {
|
|
58368
|
+
const steps = task.steps;
|
|
58369
|
+
if (steps.length === 0) return null;
|
|
58370
|
+
let targetIndex = -1;
|
|
58371
|
+
for (let i = steps.length - 1; i >= 0; i--) {
|
|
58372
|
+
if (steps[i].status !== "pending") {
|
|
58373
|
+
targetIndex = i;
|
|
58374
|
+
break;
|
|
58375
|
+
}
|
|
58376
|
+
}
|
|
58377
|
+
if (targetIndex === -1) {
|
|
58378
|
+
await this.store.updateTask(taskId, { currentStep: 0 });
|
|
58379
|
+
return null;
|
|
58380
|
+
}
|
|
58381
|
+
await this.store.updateStep(taskId, targetIndex, "pending");
|
|
58382
|
+
await this.store.updateTask(taskId, { currentStep: targetIndex });
|
|
58383
|
+
return { index: targetIndex, name: steps[targetIndex].name };
|
|
58384
|
+
}
|
|
58318
58385
|
/**
|
|
58319
58386
|
* Inject or update the "Workflow Revision Instructions" section in PROMPT.md.
|
|
58320
58387
|
* This section contains feedback from workflow steps that requested revisions.
|
|
58321
58388
|
* The section is replaced entirely to avoid accumulation of old feedback.
|
|
58322
58389
|
*/
|
|
58323
|
-
async injectWorkflowRevisionInstructions(task, feedback
|
|
58390
|
+
async injectWorkflowRevisionInstructions(task, feedback) {
|
|
58324
58391
|
const promptPath = join32(this.store.getFusionDir(), "tasks", task.id, "PROMPT.md");
|
|
58325
58392
|
let content;
|
|
58326
58393
|
try {
|
|
@@ -58329,14 +58396,7 @@ Take a different approach. Do NOT repeat the rejected strategy. Re-read the step
|
|
|
58329
58396
|
executorLog.warn(`${task.id}: PROMPT.md not found at ${promptPath}, skipping revision injection`);
|
|
58330
58397
|
return;
|
|
58331
58398
|
}
|
|
58332
|
-
|
|
58333
|
-
if (scope && scope.targetStepName && scope.resetStart < scope.totalSteps) {
|
|
58334
|
-
scopeLine = `Re-execution starts at **Step ${scope.resetStart + 1} ("${scope.targetStepName}")**. Earlier steps remain done \u2014 do not re-run them unless the feedback explicitly calls them out.`;
|
|
58335
|
-
} else if (scope && scope.resetStart >= scope.totalSteps) {
|
|
58336
|
-
scopeLine = "No steps were reset; apply the feedback as an in-place fix and call task_done() when complete.";
|
|
58337
|
-
} else {
|
|
58338
|
-
scopeLine = "Address the feedback above by making the necessary code changes, then mark all affected steps as done and call task_done() when complete.";
|
|
58339
|
-
}
|
|
58399
|
+
const scopeLine = "All prior steps remain **done**. Apply the feedback above as an in-place fix (make the necessary code changes, commit, and call `task_done()` when complete). Do **not** re-run or re-plan any earlier step unless the feedback explicitly calls it out.";
|
|
58340
58400
|
const revisionSectionHeader = "## Workflow Revision Instructions";
|
|
58341
58401
|
const revisionSectionContent = `${revisionSectionHeader}
|
|
58342
58402
|
|
|
@@ -58395,11 +58455,7 @@ ${feedback}
|
|
|
58395
58455
|
});
|
|
58396
58456
|
await this.injectWorkflowStepFailureInstructions(task, failureFeedback, stepName, retryCount);
|
|
58397
58457
|
const updatedTask = await this.store.getTask(task.id);
|
|
58398
|
-
|
|
58399
|
-
if (updatedTask.steps[i].status !== "pending") {
|
|
58400
|
-
await this.store.updateStep(task.id, i, "pending");
|
|
58401
|
-
}
|
|
58402
|
-
}
|
|
58458
|
+
await this.reopenLastStepForRevision(task.id, updatedTask);
|
|
58403
58459
|
await this.store.updateTask(task.id, {
|
|
58404
58460
|
status: null,
|
|
58405
58461
|
sessionFile: null
|
|
@@ -58443,11 +58499,7 @@ Please fix the issues so the verification can pass on the next attempt.`,
|
|
|
58443
58499
|
);
|
|
58444
58500
|
await this.injectWorkflowStepFailureInstructions(task, failureFeedback, stepName, MAX_WORKFLOW_STEP_RETRIES);
|
|
58445
58501
|
const updatedTask = await this.store.getTask(taskId);
|
|
58446
|
-
|
|
58447
|
-
if (updatedTask.steps[i].status !== "pending") {
|
|
58448
|
-
await this.store.updateStep(taskId, i, "pending");
|
|
58449
|
-
}
|
|
58450
|
-
}
|
|
58502
|
+
await this.reopenLastStepForRevision(taskId, updatedTask);
|
|
58451
58503
|
await this.store.updateTask(taskId, {
|
|
58452
58504
|
status: null,
|
|
58453
58505
|
error: null,
|
|
@@ -64246,6 +64298,12 @@ async function getHeartbeatMemorySettings(taskStore) {
|
|
|
64246
64298
|
}
|
|
64247
64299
|
return maybeGetSettings.call(taskStore);
|
|
64248
64300
|
}
|
|
64301
|
+
function isTickableState(state) {
|
|
64302
|
+
return state === "active" || state === "running";
|
|
64303
|
+
}
|
|
64304
|
+
function isHeartbeatManaged(agent) {
|
|
64305
|
+
return !isEphemeralAgent(agent);
|
|
64306
|
+
}
|
|
64249
64307
|
var HEARTBEAT_SYSTEM_PROMPT, HEARTBEAT_NO_TASK_SYSTEM_PROMPT, heartbeatDoneParams, HeartbeatMonitor, HeartbeatTriggerScheduler;
|
|
64250
64308
|
var init_agent_heartbeat = __esm({
|
|
64251
64309
|
"../engine/src/agent-heartbeat.ts"() {
|
|
@@ -65482,10 +65540,6 @@ ${taskDetail.prompt}` : "No PROMPT.md available.",
|
|
|
65482
65540
|
* @param config - Per-agent heartbeat config
|
|
65483
65541
|
*/
|
|
65484
65542
|
registerAgent(agentId, config) {
|
|
65485
|
-
if (config.enabled === false) {
|
|
65486
|
-
heartbeatLog.log(`Skipping timer registration for ${agentId} (disabled)`);
|
|
65487
|
-
return;
|
|
65488
|
-
}
|
|
65489
65543
|
let rawIntervalMs = config.heartbeatIntervalMs;
|
|
65490
65544
|
let usingDefaultInterval = false;
|
|
65491
65545
|
if (!rawIntervalMs || typeof rawIntervalMs !== "number" || !Number.isFinite(rawIntervalMs) || rawIntervalMs <= 0) {
|
|
@@ -65575,8 +65629,8 @@ ${taskDetail.prompt}` : "No PROMPT.md available.",
|
|
|
65575
65629
|
this.assignedListener = async (agent, taskId) => {
|
|
65576
65630
|
if (!this.running) return;
|
|
65577
65631
|
try {
|
|
65578
|
-
if (agent
|
|
65579
|
-
heartbeatLog.log(`Assignment trigger skipped for ${agent.id} (
|
|
65632
|
+
if (!isHeartbeatManaged(agent) || !isTickableState(agent.state)) {
|
|
65633
|
+
heartbeatLog.log(`Assignment trigger skipped for ${agent.id} (state=${agent.state})`);
|
|
65580
65634
|
return;
|
|
65581
65635
|
}
|
|
65582
65636
|
const activeRun = await this.store.getActiveHeartbeatRun(agent.id);
|
|
@@ -65645,9 +65699,21 @@ ${taskDetail.prompt}` : "No PROMPT.md available.",
|
|
|
65645
65699
|
watchAgentLifecycle() {
|
|
65646
65700
|
if (this.updatedListener || this.deletedListener) return;
|
|
65647
65701
|
this.updatedListener = (agent) => {
|
|
65648
|
-
if (agent
|
|
65702
|
+
if (!isHeartbeatManaged(agent) || !isTickableState(agent.state)) {
|
|
65649
65703
|
this.unregisterAgent(agent.id);
|
|
65704
|
+
return;
|
|
65650
65705
|
}
|
|
65706
|
+
if (this.timers.has(agent.id)) {
|
|
65707
|
+
return;
|
|
65708
|
+
}
|
|
65709
|
+
const rc = agent.runtimeConfig ?? {};
|
|
65710
|
+
this.registerAgent(agent.id, {
|
|
65711
|
+
heartbeatIntervalMs: rc.heartbeatIntervalMs,
|
|
65712
|
+
maxConcurrentRuns: rc.maxConcurrentRuns
|
|
65713
|
+
});
|
|
65714
|
+
heartbeatLog.log(
|
|
65715
|
+
`State-driven registration: ${agent.id} is ${agent.state} \u2014 timer armed`
|
|
65716
|
+
);
|
|
65651
65717
|
};
|
|
65652
65718
|
this.deletedListener = (agentId) => {
|
|
65653
65719
|
this.unregisterAgent(agentId);
|
|
@@ -65678,8 +65744,8 @@ ${taskDetail.prompt}` : "No PROMPT.md available.",
|
|
|
65678
65744
|
this.unregisterAgent(agentId);
|
|
65679
65745
|
return;
|
|
65680
65746
|
}
|
|
65681
|
-
if (agent
|
|
65682
|
-
heartbeatLog.log(`Timer tick skipped for ${agentId} (
|
|
65747
|
+
if (!isHeartbeatManaged(agent) || !isTickableState(agent.state)) {
|
|
65748
|
+
heartbeatLog.log(`Timer tick skipped for ${agentId} (state=${agent.state})`);
|
|
65683
65749
|
this.unregisterAgent(agentId);
|
|
65684
65750
|
return;
|
|
65685
65751
|
}
|
|
@@ -67884,13 +67950,13 @@ var init_in_process_runtime = __esm({
|
|
|
67884
67950
|
this.taskStore
|
|
67885
67951
|
);
|
|
67886
67952
|
this.triggerScheduler.start();
|
|
67953
|
+
const isTickable = (agent) => !isEphemeralAgent(agent) && (agent.state === "active" || agent.state === "running");
|
|
67887
67954
|
this.agentCreatedListener = (agent) => {
|
|
67888
67955
|
if (!this.triggerScheduler) return;
|
|
67956
|
+
if (!isTickable(agent)) return;
|
|
67889
67957
|
const rc = agent.runtimeConfig;
|
|
67890
|
-
if (rc?.enabled === false) return;
|
|
67891
67958
|
this.triggerScheduler.registerAgent(agent.id, {
|
|
67892
67959
|
heartbeatIntervalMs: rc?.heartbeatIntervalMs,
|
|
67893
|
-
enabled: rc?.enabled,
|
|
67894
67960
|
maxConcurrentRuns: rc?.maxConcurrentRuns
|
|
67895
67961
|
});
|
|
67896
67962
|
runtimeLog.log(`Registered new agent ${agent.id} for heartbeat triggers`);
|
|
@@ -67898,18 +67964,17 @@ var init_in_process_runtime = __esm({
|
|
|
67898
67964
|
this.agentStore.on("agent:created", this.agentCreatedListener);
|
|
67899
67965
|
this.agentUpdatedListener = (agent) => {
|
|
67900
67966
|
if (!this.triggerScheduler) return;
|
|
67901
|
-
|
|
67902
|
-
if (rc?.enabled === false) {
|
|
67967
|
+
if (!isTickable(agent)) {
|
|
67903
67968
|
this.triggerScheduler.unregisterAgent(agent.id);
|
|
67904
|
-
runtimeLog.log(`Unregistered agent ${agent.id} from heartbeat triggers (
|
|
67905
|
-
|
|
67906
|
-
this.triggerScheduler.registerAgent(agent.id, {
|
|
67907
|
-
heartbeatIntervalMs: rc?.heartbeatIntervalMs,
|
|
67908
|
-
enabled: rc?.enabled,
|
|
67909
|
-
maxConcurrentRuns: rc?.maxConcurrentRuns
|
|
67910
|
-
});
|
|
67911
|
-
runtimeLog.log(`Re-registered agent ${agent.id} for heartbeat triggers`);
|
|
67969
|
+
runtimeLog.log(`Unregistered agent ${agent.id} from heartbeat triggers (state=${agent.state})`);
|
|
67970
|
+
return;
|
|
67912
67971
|
}
|
|
67972
|
+
const rc = agent.runtimeConfig;
|
|
67973
|
+
this.triggerScheduler.registerAgent(agent.id, {
|
|
67974
|
+
heartbeatIntervalMs: rc?.heartbeatIntervalMs,
|
|
67975
|
+
maxConcurrentRuns: rc?.maxConcurrentRuns
|
|
67976
|
+
});
|
|
67977
|
+
runtimeLog.log(`Re-registered agent ${agent.id} for heartbeat triggers (state=${agent.state})`);
|
|
67913
67978
|
};
|
|
67914
67979
|
this.agentStore.on("agent:updated", this.agentUpdatedListener);
|
|
67915
67980
|
this.ephemeralTerminationListener = (agentId, from, to) => {
|
|
@@ -67944,15 +68009,13 @@ var init_in_process_runtime = __esm({
|
|
|
67944
68009
|
const agents = await this.agentStore.listAgents();
|
|
67945
68010
|
let registeredCount = 0;
|
|
67946
68011
|
for (const agent of agents) {
|
|
68012
|
+
if (!isTickable(agent)) continue;
|
|
67947
68013
|
const rc = agent.runtimeConfig;
|
|
67948
|
-
|
|
67949
|
-
|
|
67950
|
-
|
|
67951
|
-
|
|
67952
|
-
|
|
67953
|
-
});
|
|
67954
|
-
registeredCount++;
|
|
67955
|
-
}
|
|
68014
|
+
this.triggerScheduler.registerAgent(agent.id, {
|
|
68015
|
+
heartbeatIntervalMs: rc?.heartbeatIntervalMs,
|
|
68016
|
+
maxConcurrentRuns: rc?.maxConcurrentRuns
|
|
68017
|
+
});
|
|
68018
|
+
registeredCount++;
|
|
67956
68019
|
}
|
|
67957
68020
|
if (agents.length > 0) {
|
|
67958
68021
|
runtimeLog.log(`Registered ${registeredCount} of ${agents.length} agents for heartbeat triggers`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|