UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

93 lines (92 loc) • 4.37 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. import { dispatchPreparedCommandInvocation } from "../../commands/command/command-execution.js"; import { finishAttempt } from "./attempt-lifecycle.js"; import { appendHistory } from "./task-history.js"; import { persistRunLog, scrubTaskOutput, streamLines } from "./task-log.js"; export async function runPreparedCommandTask(input) { const { task, logPath, startedAt, now, agentOptions, provenance } = input; const dispatchOptions = { ...(input.runAgentImpl ? { runAgent: input.runAgentImpl } : {}), ...(input.chatCompletionImpl ? { chat: input.chatCompletionImpl } : {}), ...(agentOptions ? { runOptions: agentOptions } : {}), // F-1 (R-07 fix, spec §5.2 point 3): threads the resolved event source // into the dispatched engine's child env and the recorded usage events. eventSource: provenance.eventSource, }; const result = await dispatchPreparedCommandInvocation(task.invocation, dispatchOptions); const engineName = result.engine; const finishedAt = finishAttempt(startedAt, now()); const log = renderPromptLog({ task, engineName, result, notices: result.notices, warnings: result.warnings }); persistRunLog({ taskId: task.taskId, startedAtIso: startedAt.toISOString(), finishedAtIso: finishedAt.toISOString(), logPath, fileText: log.fileText, dbLines: log.dbLines, redactNames: task.redact, environment: task.environment, }); const status = result.ok ? "completed" : "failed"; const out = { id: task.taskId, status, startedAt: startedAt.toISOString(), finishedAt: finishedAt.toISOString(), durationMs: finishedAt.getTime() - startedAt.getTime(), log: logPath, target: { kind: "command", engine: engineName }, detail: result.ok ? { exitCode: result.exitCode } : { reason: result.reason === undefined ? undefined : scrubTaskOutput(task, result.reason), error: result.error === undefined ? undefined : scrubTaskOutput(task, result.error), exitCode: result.exitCode, }, ...(result.notices && result.notices.length > 0 ? { notices: result.notices.map((notice) => ({ ...notice, message: scrubTaskOutput(task, notice.message), })), } : {}), }; appendHistory(out, input.historyReserved); return out; } function renderPromptLog(input) { const lines = []; const dbLines = []; const header = `[akm task] task=${input.task.taskId} kind=prompt engine=${input.engineName}`; const summary = `ok=${input.result.ok} exit_code=${input.result.exitCode ?? "null"} duration_ms=${input.result.durationMs}${input.result.sessionId ? ` session_id=${input.result.sessionId}` : ""}`; lines.push(header, summary); dbLines.push({ line: header }, { level: input.result.ok ? "info" : "error", line: summary }); for (const warning of input.warnings ?? []) { lines.push(warning); dbLines.push({ level: "warn", line: warning }); } for (const notice of input.notices ?? []) { const line = `lowering_notice=${notice.code} adapter=${notice.adapter} field=${notice.field ?? ""} message=${notice.message}`; lines.push(line); dbLines.push({ level: notice.severity === "warning" ? "warn" : "info", line }); } if (!input.result.ok) { const failure = `reason=${input.result.reason ?? ""} error=${input.result.error ?? ""}`; lines.push(failure); dbLines.push({ level: "error", line: failure }); } if (input.result.stdout) { lines.push("--- agent stdout ---"); lines.push(input.result.stdout); dbLines.push(...streamLines(input.result.stdout, "stdout", "info")); } if (input.result.stderr) { lines.push("--- agent stderr ---"); lines.push(input.result.stderr); dbLines.push(...streamLines(input.result.stderr, "stderr", "error")); } return { fileText: `${lines.join("\n")}\n`, dbLines }; }