UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

149 lines (148 loc) 6.89 kB
import { l as normalizeOptionalString } from "../string-coerce-CIXf7egm.js"; import { c as withPluginRuntimeGatewayContextResolver, r as getGatewayContextResolver } from "../gateway-request-scope-BCMYlsDI.js"; import { E as listTaskRecords } from "../task-registry-BP9SCk1B.js"; import "../runtime-internal-CdH7E8By.js"; import { a as finalizeTaskRunByRunId, c as recordTaskRunProgressByRunId, l as setDetachedTaskDeliveryStatusByRunId, r as createRunningTaskRun } from "../detached-task-runtime-ZA7N6H20.js"; import { n as AGENT_INTERNAL_EVENT_TYPE_TASK_COMPLETION } from "../subagent-requester-store-key-H6AgjPG7.js"; import { n as buildAnnounceIdempotencyKey } from "../announce-idempotency-D7LnUTJR.js"; import { a as loadRequesterSessionEntry, d as formatAgentInternalEventsForPrompt, i as resolveSubagentCompletionOrigin, n as isInternalAnnounceRequesterSession, r as resolveAnnounceOrigin, t as deliverSubagentAnnouncement } from "../subagent-announce-delivery-CB6b5kft.js"; import { t as assertAgentHarnessTaskRuntimeScope } from "../agent-harness-task-runtime-scope-CFHneTNI.js"; //#region src/plugin-sdk/agent-harness-task-runtime.ts /** * Runtime SDK helpers for agent harness task persistence and completion delivery. */ const AGENT_HARNESS_COMPLETION_SOURCE_TOOL = "agent_harness_task"; /** Creates a task runtime whose run ids and task records are constrained to one scope. */ function createAgentHarnessTaskRuntime(params) { const runtime = params.runtime; const requesterSessionKey = assertAgentHarnessTaskRuntimeScope(params.scope).requesterSessionKey; const taskKind = normalizeOptionalString(params.taskKind); const runIdPrefix = normalizeOptionalString(params.runIdPrefix); const assertRunId = (runId) => assertScopedRunId(runId, runIdPrefix); const tryCreateRunningTaskRun = (taskParams) => { assertRunId(taskParams.runId); return createRunningTaskRun({ ...taskParams, runtime, ...taskKind ? { taskKind } : {}, requesterSessionKey, ownerKey: requesterSessionKey, scopeKind: "session" }); }; return { createRunningTaskRun(taskParams) { const task = tryCreateRunningTaskRun(taskParams); if (!task) throw new Error("Task persistence failed."); return task; }, tryCreateRunningTaskRun, recordTaskRunProgressByRunId(taskParams) { assertRunId(taskParams.runId); return recordTaskRunProgressByRunId({ ...taskParams, runtime, sessionKey: requesterSessionKey }); }, finalizeTaskRunByRunId(taskParams) { assertRunId(taskParams.runId); return finalizeTaskRunByRunId({ ...taskParams, runtime, sessionKey: requesterSessionKey }); }, setDetachedTaskDeliveryStatusByRunId(taskParams) { assertRunId(taskParams.runId); return setDetachedTaskDeliveryStatusByRunId({ ...taskParams, runtime, sessionKey: requesterSessionKey }); }, listTaskRecords() { return listTaskRecords().filter((task) => task.runtime === runtime && (!taskKind || task.taskKind === taskKind) && task.scopeKind === "session" && task.ownerKey === requesterSessionKey && (!runIdPrefix || task.runId?.startsWith(runIdPrefix))); } }; } /** Delivers a completed harness task result back to the requester or parent session. */ async function deliverAgentHarnessTaskCompletion(params) { const scope = assertAgentHarnessTaskRuntimeScope(params.scope); const requesterSessionKey = scope.requesterSessionKey; const childSessionKey = params.childSessionKey.trim(); const childSessionId = params.childSessionId.trim(); const taskLabel = params.taskLabel?.trim() || "Agent harness task"; const announceType = params.announceType?.trim() || "Agent harness task"; const statusLabel = params.statusLabel?.trim() || params.status; const eventStatus = mapHarnessCompletionStatus(params.status); const requesterIsSubagent = isInternalAnnounceRequesterSession(requesterSessionKey); let directOrigin = scope.requesterOrigin; if (!requesterIsSubagent) { const { entry } = loadRequesterSessionEntry(requesterSessionKey); directOrigin = resolveAnnounceOrigin(entry, scope.requesterOrigin); } const completionDirectOrigin = requesterIsSubagent || !directOrigin ? directOrigin : await resolveSubagentCompletionOrigin({ childSessionKey, requesterSessionKey, requesterOrigin: directOrigin, childRunId: childSessionKey, spawnMode: "run", expectsCompletionMessage: true }); const internalEvents = [{ type: AGENT_INTERNAL_EVENT_TYPE_TASK_COMPLETION, source: "subagent", childSessionKey, childSessionId, announceType, taskLabel, status: eventStatus, statusLabel, result: params.result, replyInstruction: params.replyInstruction?.trim() || "Use the completed harness task result to continue or wrap up the parent task. If this is a channel session, send the visible response with the message tool instead of only writing a transcript final answer." }]; const prompt = formatAgentInternalEventsForPrompt(internalEvents); const deliver = () => deliverSubagentAnnouncement({ requesterSessionKey, announceId: params.announceId, triggerMessage: prompt, steerMessage: prompt, internalEvents, summaryLine: taskLabel, requesterSessionOrigin: scope.requesterOrigin, requesterOrigin: completionDirectOrigin ?? directOrigin, completionDirectOrigin: completionDirectOrigin ?? directOrigin, directOrigin, sourceSessionKey: childSessionKey, sourceTool: AGENT_HARNESS_COMPLETION_SOURCE_TOOL, targetRequesterSessionKey: requesterSessionKey, requesterIsSubagent, expectsCompletionMessage: true, bestEffortDeliver: true, directIdempotencyKey: buildAnnounceIdempotencyKey(params.announceId), signal: params.signal }); const resolveGatewayContext = getGatewayContextResolver(scope); return resolveGatewayContext ? await withPluginRuntimeGatewayContextResolver(resolveGatewayContext, deliver) : await deliver(); } function mapHarnessCompletionStatus(status) { if (status === "succeeded") return "ok"; return "error"; } /** Returns true when completion delivery reached a persistent direct or steered path. */ function isDurableAgentHarnessCompletionDelivery(delivery) { if (!delivery.delivered) return false; if (delivery.path === "steered") return true; if (delivery.path !== "direct") return false; const phases = Array.isArray(delivery.phases) ? delivery.phases : void 0; if (!phases) return true; return phases.some((phase) => phase.phase === "direct-primary" && phase.delivered && phase.path === "direct"); } function assertScopedRunId(runId, runIdPrefix) { const normalized = runId.trim(); if (!normalized) throw new Error("Agent harness task runtime requires runId"); if (runIdPrefix && !normalized.startsWith(runIdPrefix)) throw new Error("Agent harness task runId is outside the configured scope"); } //#endregion export { createAgentHarnessTaskRuntime, deliverAgentHarnessTaskCompletion, isDurableAgentHarnessCompletionDelivery };