feat: enhance bootstrap hook with detailed logging and internal hook configuration
This commit is contained in:
@@ -106,10 +106,14 @@ export async function loadRoleInstructions(
|
|||||||
export function registerBootstrapHook(api: OpenClawPluginApi): void {
|
export function registerBootstrapHook(api: OpenClawPluginApi): void {
|
||||||
api.registerHook("agent:bootstrap", async (event) => {
|
api.registerHook("agent:bootstrap", async (event) => {
|
||||||
const sessionKey = event.sessionKey;
|
const sessionKey = event.sessionKey;
|
||||||
|
api.logger.debug(`Bootstrap hook fired: sessionKey=${sessionKey ?? "undefined"}, event keys=${Object.keys(event).join(",")}`);
|
||||||
if (!sessionKey) return;
|
if (!sessionKey) return;
|
||||||
|
|
||||||
const parsed = parseDevClawSessionKey(sessionKey);
|
const parsed = parseDevClawSessionKey(sessionKey);
|
||||||
if (!parsed) return;
|
if (!parsed) {
|
||||||
|
api.logger.debug(`Bootstrap hook: not a DevClaw session key: ${sessionKey}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const context = event.context as {
|
const context = event.context as {
|
||||||
workspaceDir?: string;
|
workspaceDir?: string;
|
||||||
@@ -122,10 +126,16 @@ export function registerBootstrapHook(api: OpenClawPluginApi): void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const workspaceDir = context.workspaceDir;
|
const workspaceDir = context.workspaceDir;
|
||||||
if (!workspaceDir || typeof workspaceDir !== "string") return;
|
if (!workspaceDir || typeof workspaceDir !== "string") {
|
||||||
|
api.logger.warn(`Bootstrap hook: no workspaceDir in context for ${sessionKey}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const bootstrapFiles = context.bootstrapFiles;
|
const bootstrapFiles = context.bootstrapFiles;
|
||||||
if (!Array.isArray(bootstrapFiles)) return;
|
if (!Array.isArray(bootstrapFiles)) {
|
||||||
|
api.logger.warn(`Bootstrap hook: no bootstrapFiles array in context for ${sessionKey}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const { content, source } = await loadRoleInstructions(
|
const { content, source } = await loadRoleInstructions(
|
||||||
workspaceDir,
|
workspaceDir,
|
||||||
@@ -134,7 +144,10 @@ export function registerBootstrapHook(api: OpenClawPluginApi): void {
|
|||||||
{ withSource: true },
|
{ withSource: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!content) return;
|
if (!content) {
|
||||||
|
api.logger.warn(`Bootstrap hook: no content found for ${parsed.role} in project "${parsed.projectName}" (workspace: ${workspaceDir})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Inject as a virtual bootstrap file. OpenClaw includes these in the
|
// Inject as a virtual bootstrap file. OpenClaw includes these in the
|
||||||
// agent's system prompt automatically (via buildBootstrapContextFiles).
|
// agent's system prompt automatically (via buildBootstrapContextFiles).
|
||||||
@@ -148,5 +161,5 @@ export function registerBootstrapHook(api: OpenClawPluginApi): void {
|
|||||||
api.logger.info(
|
api.logger.info(
|
||||||
`Bootstrap hook: injected ${parsed.role} instructions for project "${parsed.projectName}" from ${source}`,
|
`Bootstrap hook: injected ${parsed.role} instructions for project "${parsed.projectName}" from ${source}`,
|
||||||
);
|
);
|
||||||
});
|
}, { name: "devclaw-worker-instructions", description: "Injects role-specific instructions into DevClaw worker sessions" } as any);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export async function writePluginConfig(
|
|||||||
// Clean up legacy models from openclaw.json (moved to workflow.yaml)
|
// Clean up legacy models from openclaw.json (moved to workflow.yaml)
|
||||||
delete (config as any).plugins.entries.devclaw.config.models;
|
delete (config as any).plugins.entries.devclaw.config.models;
|
||||||
|
|
||||||
|
ensureInternalHooks(config);
|
||||||
ensureHeartbeatDefaults(config);
|
ensureHeartbeatDefaults(config);
|
||||||
configureSubagentCleanup(config);
|
configureSubagentCleanup(config);
|
||||||
|
|
||||||
@@ -77,6 +78,13 @@ function addToolRestrictions(config: Record<string, unknown>, agentId: string):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureInternalHooks(config: Record<string, unknown>): void {
|
||||||
|
if (!config.hooks) config.hooks = {};
|
||||||
|
const hooks = config.hooks as Record<string, unknown>;
|
||||||
|
if (!hooks.internal) hooks.internal = {};
|
||||||
|
(hooks.internal as Record<string, unknown>).enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
function ensureHeartbeatDefaults(config: Record<string, unknown>): void {
|
function ensureHeartbeatDefaults(config: Record<string, unknown>): void {
|
||||||
const devclaw = (config as any).plugins.entries.devclaw.config;
|
const devclaw = (config as any).plugins.entries.devclaw.config;
|
||||||
if (!devclaw.work_heartbeat) {
|
if (!devclaw.work_heartbeat) {
|
||||||
|
|||||||
Reference in New Issue
Block a user