Download src/agents/subagents/spawn/subagent-spawn-plan.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 5.35 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/subagents/spawn/subagent-spawn-plan.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/agents/subagents/spawn/subagent-spawn-plan.ts
-
curl -L -o subagent-spawn-plan.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/agents/subagents/spawn/subagent-spawn-plan.ts
5.35 kB
| /** | |
| * Subagent spawn planning helpers. | |
| * | |
| * Resolves model, thinking, and timeout choices before the sessions_spawn executor launches work. | |
| */ | |
| import { formatThinkingLevels } from "../../../auto-reply/thinking.js"; | |
| import type { OpenClawConfig } from "../../../config/types.openclaw.js"; | |
| import type { FastMode } from "../../../shared/fast-mode.js"; | |
| import { splitTrailingAuthProfile } from "../../model-ref-profile.js"; | |
| import { | |
| type ModelRef, | |
| resolveDefaultModelForAgent, | |
| resolveSubagentConfiguredModelSelection, | |
| resolveSubagentSpawnModelSelection, | |
| } from "../../model-selection.js"; | |
| import { resolveSubagentThinkingOverride } from "./subagent-spawn-thinking.js"; | |
| /** Splits a provider/model ref while preserving model-only refs. */ | |
| export function splitModelRef(ref?: string) { | |
| if (!ref) { | |
| return { provider: undefined, model: undefined }; | |
| } | |
| const trimmed = ref.trim(); | |
| if (!trimmed) { | |
| return { provider: undefined, model: undefined }; | |
| } | |
| const slash = trimmed.indexOf("/"); | |
| if (slash > 0 && slash < trimmed.length - 1) { | |
| const provider = trimmed.slice(0, slash); | |
| const model = trimmed.slice(slash + 1); | |
| return { provider, model }; | |
| } | |
| const provider = undefined; | |
| const model = trimmed; | |
| if (model) { | |
| return { provider, model }; | |
| } | |
| return { provider: undefined, model: trimmed }; | |
| } | |
| /** Resolves the effective subagent run timeout from per-call override or config default. */ | |
| export function resolveConfiguredSubagentRunTimeoutSeconds(params: { | |
| cfg: OpenClawConfig; | |
| runTimeoutSeconds?: number; | |
| }) { | |
| const cfgSubagentTimeout = | |
| typeof params.cfg?.agents?.defaults?.subagents?.runTimeoutSeconds === "number" && | |
| Number.isFinite(params.cfg.agents.defaults.subagents.runTimeoutSeconds) | |
| ? Math.max(0, Math.floor(params.cfg.agents.defaults.subagents.runTimeoutSeconds)) | |
| : 0; | |
| return typeof params.runTimeoutSeconds === "number" && Number.isFinite(params.runTimeoutSeconds) | |
| ? Math.max(0, Math.floor(params.runTimeoutSeconds)) | |
| : cfgSubagentTimeout; | |
| } | |
| /** Resolves the subagent model plus thinking patch to apply to the spawned session. */ | |
| export function resolveSubagentModelAndThinkingPlan(params: { | |
| cfg: OpenClawConfig; | |
| targetAgentId: string; | |
| requesterAgentConfig?: unknown; | |
| targetAgentConfig?: unknown; | |
| modelOverride?: string; | |
| thinkingOverrideRaw?: string; | |
| callerThinkingRaw?: string; | |
| inheritedModel?: ModelRef; | |
| fastMode?: FastMode; | |
| }) { | |
| const { model: rawResolvedModel, resolvedModel: inheritedModel } = | |
| resolveSubagentSpawnModelSelection({ | |
| cfg: params.cfg, | |
| agentId: params.targetAgentId, | |
| modelOverride: params.modelOverride, | |
| inheritedModel: params.inheritedModel, | |
| }); | |
| const { model: resolvedModel, profile: authProfileId } = | |
| splitTrailingAuthProfile(rawResolvedModel); | |
| const thinkingPlan = resolveSubagentThinkingOverride({ | |
| cfg: params.cfg, | |
| requesterAgentConfig: params.requesterAgentConfig, | |
| targetAgentConfig: params.targetAgentConfig, | |
| thinkingOverrideRaw: params.thinkingOverrideRaw, | |
| callerThinkingRaw: params.callerThinkingRaw, | |
| }); | |
| if (thinkingPlan.status === "error") { | |
| const { provider, model } = splitModelRef(resolvedModel); | |
| // The hint is provider/model-specific because valid thinking levels vary by backend. | |
| const hint = formatThinkingLevels(provider, model); | |
| return { | |
| status: "error" as const, | |
| resolvedModel, | |
| error: `Invalid thinking level "${thinkingPlan.thinkingCandidateRaw}". Use one of: ${hint}.`, | |
| }; | |
| } | |
| const modelOverrideSource = params.modelOverride?.trim() ? "user" : "auto"; | |
| const hasSelectedAutoModel = | |
| modelOverrideSource === "auto" && | |
| Boolean( | |
| params.inheritedModel ?? | |
| resolveSubagentConfiguredModelSelection({ | |
| cfg: params.cfg, | |
| agentId: params.targetAgentId, | |
| }), | |
| ); | |
| const configuredModelRef = hasSelectedAutoModel ? splitModelRef(resolvedModel) : undefined; | |
| const modelOrigin = configuredModelRef?.model | |
| ? { | |
| provider: | |
| configuredModelRef.provider ?? | |
| resolveDefaultModelForAgent({ | |
| cfg: params.cfg, | |
| agentId: params.targetAgentId, | |
| }).provider, | |
| model: configuredModelRef.model, | |
| } | |
| : undefined; | |
| return { | |
| status: "ok" as const, | |
| resolvedModel, | |
| ...(inheritedModel ? { inheritedModel } : {}), | |
| modelApplied: Boolean(resolvedModel), | |
| thinkingOverride: thinkingPlan.thinkingOverride, | |
| initialSessionPatch: { | |
| ...(resolvedModel | |
| ? { | |
| model: resolvedModel, | |
| modelOverrideSource, | |
| ...(modelOrigin | |
| ? { | |
| // Selected child models are session overrides, not legacy fallback residue. | |
| // Self-origin metadata keeps cleanup from discarding them before first use. | |
| modelOverrideFallbackOriginProvider: modelOrigin.provider, | |
| modelOverrideFallbackOriginModel: modelOrigin.model, | |
| } | |
| : {}), | |
| } | |
| : {}), | |
| ...(authProfileId | |
| ? { | |
| authProfileOverride: authProfileId, | |
| authProfileOverrideSource: "user" as const, | |
| } | |
| : {}), | |
| ...thinkingPlan.initialSessionPatch, | |
| ...(params.fastMode !== undefined ? { fastMode: params.fastMode } : {}), | |
| }, | |
| }; | |
| } | |