UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

82 lines (81 loc) • 4.2 kB
import { Type } from "typebox"; export const TASK_OUTPUT_TOOL_NAME = "TaskOutput"; export const TASK_STOP_TOOL_NAME = "TaskStop"; export const TASK_OUTPUT_CONTRACT = { contractId: "core.task_output@1", implementationRevision: "1" }; export const TASK_STOP_CONTRACT = { contractId: "core.task_stop@1", implementationRevision: "1" }; export const TASK_OUTPUT_MISSING_ID_MESSAGE = "Error (TaskOutput): Missing required parameter: task_id"; export const TASK_STOP_MISSING_ID_MESSAGE = "Missing required parameter: task_id"; export const TASK_STOP_PARAMS = Type.Object({ task_id: Type.Optional(Type.String({ description: "The ID of the background task to stop" })), shell_id: Type.Optional(Type.String({ description: "Deprecated: use task_id instead" })), }); export function resolveTaskIdArg(...values) { for (const value of values) { if (typeof value === "string" && value.trim() !== "") return value.trim(); } return undefined; } export const REGISTRY_TASK_TOOL_CAPS = { lanes: true, outputFile: true, notification: true, blockWait: true, nameAddressing: true, }; export const ENV_DIRECT_TASK_TOOL_CAPS = { lanes: false, outputFile: false, notification: false, blockWait: false, nameAddressing: false, }; export function composeTaskOutputDescription(caps) { const parts = []; if (caps.outputFile) { parts.push("[Deprecated] — for background Bash tasks, prefer Read on the output file path; for agent tasks, use the Agent tool result directly. " + "DEPRECATED: Background tasks return their output file path in the tool result" + (caps.notification ? ", and you receive a <task-notification> with the same path when the task completes. " : ". ")); } parts.push("Retrieve output or status for a background task by task_id. "); parts.push(caps.lanes ? "Supports background Bash tasks and workflow tasks returned by Workflow. Returns only the caller's own task scope; unknown and out-of-scope ids are " + "reported the same way. " : "Reads a background shell started with Bash(run_in_background): returns the run status (running / exited(code) / killed / failed) plus NEW stdout/stderr since your last call. "); if (!caps.notification) { parts.push('When using a background command as a wait condition, call this repeatedly until status is no longer "running" — completion ' + "is signalled by status/exitCode, not by any automatic notification; after you see a terminal status, one more " + "poll captures any final output. "); } if (!caps.lanes) parts.push("Optional `filter` is a regex keeping only matching lines."); return parts.join("").trimEnd(); } export function composeTaskStopDescription(caps) { return [ "- Stops a running background task by its ID", "- Takes a task_id parameter identifying the task to stop", ...(caps.nameAddressing ? ["- To stop a background agent spawned with a name, pass that name as task_id"] : []), "- Returns a success or failure status", "- Use this tool when you need to terminate a long-running task", ].join("\n"); } export function composeTaskOutputParams(caps) { return Type.Object({ task_id: Type.Optional(Type.String({ description: caps.lanes ? "The task_id returned by Bash(run_in_background) or Workflow." : "The task_id returned by Bash(run_in_background).", })), ...(caps.blockWait ? { block: Type.Optional(Type.Boolean({ description: "Whether to wait for completion (default true — the call waits until the task finishes or `timeout`, saving re-poll turns). Pass false for an instantaneous snapshot.", })), timeout: Type.Optional(Type.Number({ description: "Optional timeout in milliseconds when block is true (default 30000, max 600000)." })), } : {}), filter: Type.Optional(Type.String({ description: "Optional regex filter for background Bash output (sema extension)." })), }); }