Merge pull request #157 from laurentenhoor/fix/156-remove-chained-dispatch

fix: remove chained dispatch from work_finish - heartbeat only pickup path (#156)
This commit is contained in:
Lauren ten Hoor
2026-02-13 17:51:32 +08:00
committed by GitHub
2 changed files with 2 additions and 42 deletions

View File

@@ -4,11 +4,10 @@
* Eliminates repeated boilerplate across tools: workspace validation,
* project resolution, provider creation.
*/
import type { OpenClawPluginApi, PluginRuntime } from "openclaw/plugin-sdk";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
import type { ToolContext } from "./types.js";
import { readProjects, getProject, type Project, type ProjectsData } from "./projects.js";
import { createProvider, type ProviderWithType } from "./providers/index.js";
import { projectTick, type TickAction } from "./services/tick.js";
/**
* Require workspaceDir from context or throw a clear error.
@@ -48,34 +47,3 @@ export async function resolveProvider(project: Project): Promise<ProviderWithTyp
export function getPluginConfig(api: OpenClawPluginApi): Record<string, unknown> | undefined {
return api.pluginConfig as Record<string, unknown> | undefined;
}
/**
* Run projectTick (non-fatal). Notifications are now handled by dispatchTask.
* Returns the pickups array (empty on failure).
*/
export async function tickAndNotify(opts: {
workspaceDir: string;
groupId: string;
agentId?: string;
pluginConfig?: Record<string, unknown>;
sessionKey?: string;
targetRole?: "dev" | "qa";
/** Plugin runtime for direct API access (avoids CLI subprocess timeouts) */
runtime?: PluginRuntime;
}): Promise<TickAction[]> {
try {
const result = await projectTick({
workspaceDir: opts.workspaceDir,
groupId: opts.groupId,
agentId: opts.agentId,
pluginConfig: opts.pluginConfig,
sessionKey: opts.sessionKey,
targetRole: opts.targetRole,
runtime: opts.runtime,
});
return result.pickups;
} catch {
/* non-fatal: tick failure shouldn't break the caller */
return [];
}
}

View File

@@ -10,7 +10,7 @@ import type { ToolContext } from "../types.js";
import { getWorker, resolveRepoPath } from "../projects.js";
import { executeCompletion, getRule, NEXT_STATE } from "../services/pipeline.js";
import { log as auditLog } from "../audit.js";
import { requireWorkspaceDir, resolveProject, resolveProvider, getPluginConfig, tickAndNotify } from "../tool-helpers.js";
import { requireWorkspaceDir, resolveProject, resolveProvider, getPluginConfig } from "../tool-helpers.js";
export function createWorkFinishTool(api: OpenClawPluginApi) {
return (ctx: ToolContext) => ({
@@ -73,18 +73,10 @@ export function createWorkFinishTool(api: OpenClawPluginApi) {
...completion,
};
// Tick: fill free slots (notifications handled by dispatchTask with runtime)
const tickPickups = await tickAndNotify({
workspaceDir, groupId, agentId: ctx.agentId, pluginConfig, sessionKey: ctx.sessionKey,
runtime: api.runtime,
});
if (tickPickups.length) output.tickPickups = tickPickups;
// Audit
await auditLog(workspaceDir, "work_finish", {
project: project.name, groupId, issue: issueId, role, result,
summary: summary ?? null, labelTransition: completion.labelTransition,
tickPickups: tickPickups.length,
});
return jsonResult(output);