UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

154 lines (153 loc) • 6.72 kB
import { n as AgentHarnessSessionSupersededError, t as AgentHarnessPreflightError } from "./errors-Bd6GQRkh.mjs"; import { t as abortAndDrainEmbeddedAgentRun } from "./runs-D3elciTh.mjs"; import { m as toolPolicy } from "./agent-harness-runtime-CfbNr0AL.mjs"; import { n as prepareNativeSessionGenerationAuthority } from "./agent-harness-session-runtime-DFZWNbRI.mjs"; import { t as requireAgentsApiSessionTarget } from "./agentsapi-target-ClP2ww2I.mjs"; import { t as runAgentsApiAttempt } from "./agentsapi-attempt-DsyfsjYz.mjs"; import { t as createAgentsApiBindings } from "./agentsapi-bindings-BvrW3YcT.mjs"; import { t as runAgentsApiIsolatedCompletion } from "./agentsapi-isolated-completion-BjNPeL8H.mjs"; //#region extensions/agentsapi/agentsapi-harness.ts const AGENTS_API_NATIVE_TOOL_REQUIREMENTS = [ "exec", "process", "read", "write", "edit", "apply_patch", "web_search" ]; /** Agents API owns native protocol; the host harness runtime owns coordination. */ function createAgentsApiHarness(runtime) { let disposed = false; let closing = false; const runningSessions = /* @__PURE__ */ new Map(); const isolatedRuns = /* @__PURE__ */ new Map(); const promptHistories = /* @__PURE__ */ new WeakMap(); let bindings; const getBindings = () => bindings ??= createAgentsApiBindings(runtime); const assertCurrent = () => { if (disposed) throw new Error("Agents API harness is disposed"); }; return { id: "agentsapi", label: "OpenAI Agents API (MVP)", autoSelection: { providerIds: [] }, deliveryDefaults: { visibleReplies: "automatic" }, conversationToolPolicySupport: "exact", conversationToolPolicyNativeTools: AGENTS_API_NATIVE_TOOL_REQUIREMENTS, conversationToolPolicySafeDenyTools: [ "gateway", "agents_list", "openclaw", "session_status", "progress_card", "automations", "message", "sessions_send", "conversations_list", "conversations_send", "conversations_turn", "subagents", "sessions_list", "sessions_history", "sessions_search", "sessions_spawn" ], supports: (ctx) => { if (ctx.provider !== "openai") return { supported: false, reason: "Agents API requires the OpenAI provider" }; if (ctx.modelProvider?.preparedAuth?.requirement === "subscription" || ctx.modelProvider?.api && ctx.modelProvider.api !== "openai-responses" || ctx.modelProvider?.requestTransportOverrides === "present" || ctx.modelProvider?.baseUrl && ctx.modelProvider.baseUrl !== "https://api.openai.com/v1") return { supported: false, reason: "Agents API MVP requires the official API-key route" }; return { supported: true }; }, runIsolatedCompletionV2: (params) => { assertCurrent(); if (closing) throw new Error("Agents API harness is closing"); const controller = new AbortController(); const pending = runAgentsApiIsolatedCompletion({ ...params, abortSignal: params.abortSignal ? AbortSignal.any([params.abortSignal, controller.signal]) : controller.signal }, assertCurrent); isolatedRuns.set(controller, pending); return pending.finally(() => isolatedRuns.delete(controller)); }, runAttempt: async (params) => { assertCurrent(); if (closing) throw new Error("Agents API harness is closing"); const target = validateAgentsApiInput(params); const authority = (await prepareNativeSessionGenerationAuthority({ target, config: params.config, storePath: target.storePath, assertCurrent: () => { assertCurrent(); params.hostCapabilities.assertActive(); }, createSupersededError: (sessionId) => new AgentHarnessSessionSupersededError(`Agents API session generation is no longer current: ${sessionId}`) })).authority; authority.assertLegacyCurrent(); runningSessions.set(params.sessionId, (runningSessions.get(params.sessionId) ?? 0) + 1); try { return await getBindings().withSession(params.sessionId, () => authority.assertLegacyCurrent(), (binding, bind, assertLeaseCurrent) => { if (closing) throw new Error("Agents API harness is closing"); return runAgentsApiAttempt(params, binding, bind, () => { authority.assertLegacyCurrent(); assertLeaseCurrent(); }, () => { assertCurrent(); assertLeaseCurrent(); }, target, () => runtime.config.current().plugins?.entries?.agentsapi?.config, promptHistories); }); } finally { const count = runningSessions.get(params.sessionId) - 1; if (count > 0) runningSessions.set(params.sessionId, count); else runningSessions.delete(params.sessionId); } }, reset: async (params) => { assertCurrent(); if (params.sessionId) await getBindings().reset(params.sessionId, assertCurrent); }, withSessionDeletion: (params, run) => getBindings().withSessionDeletion({ ...params, assertCurrent: () => { params.assertCurrent(); assertCurrent(); } }, run), dispose: async () => { closing = true; for (const controller of isolatedRuns.keys()) controller.abort(); await Promise.allSettled(isolatedRuns.values()); await Promise.all([...runningSessions.keys()].map((sessionId) => abortAndDrainEmbeddedAgentRun({ sessionId, settleMs: 95e3 }))); if (bindings) await bindings.withExclusiveMutationFence(async () => { disposed = true; }); else disposed = true; } }; } function validateAgentsApiInput(params) { const runtimeToolAllowed = toolPolicy.createToolPolicyMatcher({ allow: params.toolsAllow }); if (params.disableTools || params.pluginHarnessToolPolicyRestricted || params.toolExecutionAllow !== void 0 || params.toolsAllow?.length === 0 || AGENTS_API_NATIVE_TOOL_REQUIREMENTS.some((name) => !runtimeToolAllowed(name))) throw new AgentHarnessPreflightError("Agents API cannot enforce this run's restrictions on native shell, file, or web-search tools.", { scope: "harness", userMessage: "Agents API cannot run with this chat's tool restrictions because it cannot enforce them on native tools. Choose a harness that supports these restrictions or update the tool settings." }); const target = requireAgentsApiSessionTarget(params); if (!params.resolvedApiKey) throw new Error("Agents API MVP requires an OpenAI API key"); if (params.sandbox) throw new AgentHarnessPreflightError("Agents API does not support Gateway sandbox placement.", { scope: "harness", userMessage: "Agents API cannot run in the configured Gateway sandbox. Choose a harness that supports Gateway sandbox placement before retrying." }); if (params.contextEngine && params.contextEngine.info.id !== "legacy") throw new Error("Agents API MVP currently supports only the default legacy context engine"); return target; } //#endregion export { createAgentsApiHarness as t };